Android開發之ButterKnife,GreenDao簡單運用,以及推薦並使用一個好用的開源庫BaseRecyclerViewAdapterHelper。
在實習的這段時間裏,完成了幾個app的快速開發,最近閒下來,無聊寫了一個NoteDemo,主要使用了一些三方框架,並使用了MVP模式,經驗不足,寫下第一篇博客和大家交流學習。
- 一個好用的依賴注入框架ButterKnife
- 一個ORM框架GreenDao
- 一個快速強大的recycler幫助框架BaseRecyclerViewAdapterHelper
ButterKnife
在之前的項目中,findviewbyid什麼的,寫到手斷,一個界面有十幾二十個控件綁定。在這次的demo中也是第一次使用,發現實在是太簡潔了不少。
在gradle中添加
apply plugin: 'com.jakewharton.butterknife' dependencies { compile 'com.jakewharton:butterknife:8.4.0' annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0' }
在root中添加
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0' } }
本來綁定是:
private EditText username;
username = findViewById(R.id.user);
使用了ButterKnife:
@BindView(R.id.user) EditText username;
還可以綁定onClick監聽:
@OnClick(R.id.home_add)
void add() {
Intent intent = new Intent(this,EditNoteActivity.class);
startActivityForResult(intent,REQUEST_EDIT);
}
GreenDao
greenDAO is a light & fast ORM for Android that maps objects to SQLite databases. Being highly optimized for Android, greenDAO offers great performance and consumes minimal memory.
greenDAO是一個將對象映射到SQLite數據庫的輕量、快速的ORM框架。對Android高度優化,greenDAO擁有高性能低內存消耗。
在gradle添加
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1'
}
}
apply plugin: 'org.greenrobot.greendao'
dependencies {
compile 'org.greenrobot:greendao:3.2.0'
}
創建一個Note的實體類
@Entity
public class Note {
@Id
private Long id;
private Long addTime;
private String title;
private String content;
}
build一下,自動編譯生成一些get、set方法和NoteDao類。
@Entity
public class Note {
@Id
private Long id;
private Long addTime;
private String title;
private String content;
@Generated(hash = 128193520)
public Note(Long id, Long addTime, String title, String content) {
this.id = id;
this.addTime = addTime;
this.title = title;
this.content = content;
}
@Generated(hash = 1272611929)
public Note() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Long getAddTime() {
return this.addTime;
}
public void setAddTime(Long addTime) {
this.addTime = addTime;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return this.content;
}
public void setContent(String content) {
this.content = content;
}
}
於是可以開始做簡單的查詢操作
//獲取一個Session對象,即和數據庫的連接。
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(context, "note.db", null);
DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb());
daoSession = daoMaster.newSession();
//獲取NoteDao,就可以直接對NoteDao進行增刪改查操作了。
NoteDao mNoteDao = daoSession.getNoteDao();
//查詢Note,按addtime降序查詢。
List<Note> list = mNoteDao.queryBuilder().offset(index*size).limit(size).orderDesc(NoteDao.Properties.AddTime).list();
其他相關操作可以查看 greenDao的文檔
BaseRecyclerViewAdapterHelper
主要特性
- 優化Adapter代碼
- 添加Item事件
- 添加列表加載動畫
- 添加頭部、尾部
- 上拉加載
- 添加分組
- 自定義不同的item類型
- 設置空佈局
- 添加拖拽、滑動刪除
- 分組的伸縮欄
- 自定義ViewHolder
使用
在gradle添加
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
dependencies { compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:VERSION_CODE' }
把VERSION_CODE替換成版本號,我這裏用的是2.6.7
使用方法可以查看代碼,或者查看他們的 文檔
具體代碼
我這裏主要採用了MVP模式,類比較多,直放上個別代碼,具體看這裏。
HomeContract類,包含View和Presenter
public interface HomeContract {
interface View {
/**
* 設置SwipeRefreshLayout的刷新動畫顯示
* @param isShow 是否顯示
*/
void showSwipe(boolean isShow);
/**
* 獲取Note成功
* @param notes note列表
*/
void getNoteSuccess(List<Note> notes);
/**
* 加載更多note成功
* @param notes note列表
*/
void loadMoreNoteSuccess(List<Note> notes);
/**
* 列表到底
* @param canLoad 能否加載更多
*/
void loadEnd(boolean canLoad);
}
interface Presenter {
/**
* 刷新note列表
*/
void refreshNote();
/**
* 初始化方法
*/
void start();
/**
* 加載更多note
*/
void loadMoreNote();
/**
* 刪除note
* @param id note id
*/
void removeNote(Long id);
}
}
HomePresenter類,實現HomeContract.Presenter接口
public class HomePresenter implements HomeContract.Presenter {
private Context context;
/**
* view 控制視圖
*/
private HomeContract.View mView;
/**
* 分頁的當前頁
*/
private int index = 0;
/**
* 每頁的數量
*/
private int size = 8;
/**
* 是否到底
*/
private boolean isEnd = false;
/**
* 加載線程
*/
private static Handler handler = new Handler();
/**
* 用來操作數據庫的對象
*/
private NoteDao mNoteDao;
public HomePresenter(Context context, HomeContract.View mView) {
this.context = context;
this.mView = mView;
//初始化NoteDao
mNoteDao = DAO.getInstance(context).getSession().getNoteDao();
}
@Override
public void refreshNote() {
//刷新重置頁面
index = 0;
isEnd = false;
//開啓刷新動畫
mView.showSwipe(true);
//延時1秒執行查詢並傳送數據到view中
handler.postDelayed(new Runnable() {
@Override
public void run() {
List<Note> list = mNoteDao.queryBuilder().offset(index*size).limit(size).orderDesc(NoteDao.Properties.AddTime).list();
mView.getNoteSuccess(list);
//關閉刷新動畫
mView.showSwipe(false);
}
},1000);
}
@Override
public void start() {
refreshNote();
}
@Override
public void loadMoreNote() {
//如果到底則不加載
if(isEnd) return;
//延時1秒執行查詢並傳送數據到view中
handler.postDelayed(new Runnable() {
@Override
public void run() {
//查詢
List<Note> list = mNoteDao.queryBuilder().offset((++index)*size).limit(size).orderDesc(NoteDao.Properties.AddTime).list();
//傳送數據到view中
mView.loadMoreNoteSuccess(list);
//如果查詢結果小於每頁數量,則到底,告訴view不能加載了。
if(list.size()<size) {
isEnd = true;
mView.loadEnd(!isEnd);
}
}
},1000);
}
@Override
public void removeNote(Long id) {
//根據id刪除note
mNoteDao.deleteByKey(id);
}
}
MainActivity類
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener,
HomeContract.View{
/**
* 編輯或添加的activity的請求flag
*/
public final static int REQUEST_EDIT = 1000;
/**
* 綁定recyclerview
*/
@BindView(R.id.home_recycler)
RecyclerView recyclerView;
/**
* 綁定添加按鈕
*/
@BindView(R.id.home_add)
Button addButton;
/**
* 綁定SwipeRefreshLayout,下拉刷新控件
*/
@BindView(R.id.home_swipe)
SwipeRefreshLayout swipeRefreshLayout;
/**
* 聲明Presenter
*/
private HomeContract.Presenter mPresenter;
/**
* recycler的adapter
*/
private Adapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//初始化presenter
mPresenter = new HomePresenter(this,this);
setContentView(R.layout.activity_main);
//綁定控件
ButterKnife.bind(this);
//綁定刷新監聽
swipeRefreshLayout.setOnRefreshListener(this);
initRecyclerView();
mPresenter.start();
}
private void initRecyclerView() {
//設置recyclerview的layoutManager
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//初始化adapter
mAdapter = new Adapter(this,null);
recyclerView.setAdapter(mAdapter);
//設置加載更多監聽
mAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
@Override
public void onLoadMoreRequested() {
//加載更多
mPresenter.loadMoreNote();
}
});
//設置側滑、拖拽
ItemDragAndSwipeCallback itemDragAndSwipeCallback = new ItemDragAndSwipeCallback(mAdapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemDragAndSwipeCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
mAdapter.enableSwipeItem();
//初始化側滑監聽
OnItemSwipeListener onItemSwipeListener = new OnItemSwipeListener() {
@Override
public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) {}
@Override
public void clearView(RecyclerView.ViewHolder viewHolder, int pos) {}
@Override
public void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) {
//刪除note
mPresenter.removeNote(mAdapter.getItem(pos).getId());
}
@Override
public void onItemSwipeMoving(Canvas canvas, RecyclerView.ViewHolder viewHolder, float v, float v1, boolean b) {
}
};
//綁定側滑監聽
mAdapter.setOnItemSwipeListener(onItemSwipeListener);
//添加點擊監聽
recyclerView.addOnItemTouchListener(new OnItemClickListener() {
@Override
public void onSimpleItemClick(BaseQuickAdapter baseQuickAdapter, View view, int i) {
//把note的id傳入intent,啓動編輯的activity
Note note = (Note) baseQuickAdapter.getItem(i);
Intent intent = new Intent(getApplicationContext(),EditNoteActivity.class);
intent.putExtra("id",note.getId());
startActivityForResult(intent,REQUEST_EDIT);
}
});
}
//綁定添加按鈕的監聽
@OnClick(R.id.home_add)
void add() {
Intent intent = new Intent(this,EditNoteActivity.class);
startActivityForResult(intent,REQUEST_EDIT);
}
@Override
public void onRefresh() {
mPresenter.refreshNote();
}
@Override
public void showSwipe(boolean isShow) {
//設置刷新動畫是否開啓
swipeRefreshLayout.setRefreshing(isShow);
}
@Override
public void getNoteSuccess(List<Note> notes) {
//重新設置新的數據並刷新
mAdapter.setNewData(notes);
}
@Override
public void loadMoreNoteSuccess(List<Note> notes) {
//加入更多數據
mAdapter.addData(notes);
mAdapter.loadMoreComplete();
}
@Override
public void loadEnd(boolean canLoad) {
if(canLoad) {
}else {
// mAdapter.setEnableLoadMore(canLoad);
//顯示沒有更多數據
mAdapter.loadMoreEnd();
}
}
/**
* BaseItemDraggableAdapter是一個可以拖拽的適配器,如果不需要可以繼承BaseQuickAdapter。
*/
private class Adapter extends BaseItemDraggableAdapter<Note,BaseViewHolder> {
private Context context;
public Adapter(Context context,List<Note> data) {
//傳入佈局
super(R.layout.home_note_item, data);
this.context = context;
}
@Override
protected void convert(BaseViewHolder baseViewHolder, final Note note) {
//設置標題
baseViewHolder.setText(R.id.home_note_item_title,note.getTitle());
//設置內容
baseViewHolder.setText(R.id.home_note_item_content,note.getContent());
//設置時間
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(note.getAddTime());
baseViewHolder.setText(R.id.home_note_item_time,formatter.format(date));
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//請求編輯並且返回成功則刷新note列表
if(requestCode == REQUEST_EDIT && resultCode == RESULT_OK) {
mPresenter.refreshNote();
}
}
}