Android開發之ButterKnife,GreenDao簡單運用,以及推薦並使用一個好用的開源庫BaseRecyclerViewAdapterHelper。

Android開發之ButterKnife,GreenDao簡單運用,以及推薦並使用一個好用的開源庫BaseRecyclerViewAdapterHelper。

在實習的這段時間裏,完成了幾個app的快速開發,最近閒下來,無聊寫了一個NoteDemo,主要使用了一些三方框架,並使用了MVP模式,經驗不足,寫下第一篇博客和大家交流學習。
  1. 一個好用的依賴注入框架ButterKnife
  2. 一個ORM框架GreenDao
  3. 一個快速強大的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

主要特性

  1. 優化Adapter代碼
  2. 添加Item事件
  3. 添加列表加載動畫
  4. 添加頭部、尾部
  5. 上拉加載
  6. 添加分組
  7. 自定義不同的item類型
  8. 設置空佈局
  9. 添加拖拽、滑動刪除
  10. 分組的伸縮欄
  11. 自定義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();
        }
    }

}
臨時看了markdown,寫下這篇,甚是醜陋。簡簡單單隻分享了自己近日來的一些收穫,和大家學習分享自己的小小經驗,提升一下自己。
代碼已經放到github上了:https://github.com/shaogeng1994/NoteDemo
mail:<[email protected]>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章