Android MVP 框架 Demo

這個項目簡單封裝了一個簡單的MVP設計框架,根據框架能夠很容易的在你本身的項目中實現 MVP 設計模式。繼承我封裝好的 BaseActivity,BaseFragmentActivity,BaseSwipeRefreshActivity,BaseFragment,BaseSwipseRefreshFragment 能夠很好的實現 MVP 模式的項目開發。
也許你知道 所謂的MVP 設計模式就是:git

M就是Model ,這裏主要負責的就是業務處理,數據的獲取,例如數據庫的讀寫,http的網絡數據的處理。
V就是View ,顧名思義視圖的意思,這裏主要的任務就是處理各個界面ui控件的處理。
P就是Presenter ,控制器,這裏負責的是Model與View之間的聯繫操做。

其實簡單的用一句話描述就是:將View層抽象成view接口,將業務邏輯通通交給 Presenter 層去作。github

也許還不太瞭解或是已經瞭解的能夠來看下面的 demo 數據庫

下面的一個 activity 須要完成的功能是 設計模式

(1)顯示初始化數據 list data
(2)下拉刷新能加載新數據
(3)數據加載成功,或出錯作一些提示交互。網絡

其實這些基本內容是咱們常常和大量用到的一些場景。那來看看我們怎麼利用mvp模式來分層實現:
首先繼承我封裝好了的 BaseSwipeRefreshActivity ,而且 本身 實現 MainPresenter 類 和 IRefreshView 接口,那麼 MainActivity 就能夠實現 簡單的 mvp 設計模式了。app

先分析 MVP 中 V層的實現,及 MainActivity 的實現:框架

public class MainActivity extends BaseSwipeRefreshActivity<MainPresenter> implements IRefreshView<String> {

    @Bind(R.id.toolbar)
    protected Toolbar mToolbar;

    @Bind(R.id.swipe_refresh_layout)
    protected SwipeRefreshLayout mSwipeRefreshLayout;

    @Bind(R.id.main_RecyclerView)
    RecyclerView main_RecyclerView;

    private DataAdapter mMianActivityAdapter;
    private List<String> adapterList = new ArrayList<String>();

    @Override
    protected Toolbar getToolbar() {
        return mToolbar;
    }
    
    @Override
    protected SwipeRefreshLayout getSwipeRefreshLayout() {
        return mSwipeRefreshLayout;
    }
    
    @Override
    protected int getLayout() {
        return R.layout.activity_main;
    }

    @Override
    protected void initPresenter() {
        mPresenter = new MainPresenter(this, this);
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        initRecycleView();
        
    }

    /**
     * 初始化請求數據
     */
    @Override
    protected void intiData() {
        // 初始化數據
        mPresenter.initData();
        // 可刷新狀態準備好了
        mPrepareRefresh = true;
    }

    /**
     * 刷新請求數據
     */
    @Override
    protected void onRefreshStarted() {
        mPresenter.addMoreData();

    }

    @Override
    public void showEmptyView() {
        SnackbarUtil.PrimarySnackbar(mContext,mToolbar,"請求數據爲空");
    }

    @Override
    public void showErrorView(Throwable throwable) {
        SnackbarUtil.PrimarySnackbar(mContext,mToolbar,"請求數據出錯");
    }

    @Override
    public void hasNoMoreData() {
        SnackbarUtil.PrimarySnackbar(mContext,mToolbar,"無更多數據");
    }

    /**
     * 初始化填充數據
     * @param mData
     */
    @Override
    public void fillData(List mData) {

        mMianActivityAdapter.insertedAllItem(mData);
    }

    /**
     * 加載更多數據
     * @param mData
     */
    @Override
    public void appendMoreDataToView(List mData) {
        mMianActivityAdapter.appendMoreItem(mData);
    }
    
    @Override
    protected int getMenuRes() {
        return R.menu.mian_menu;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id){
            case R.id.menu_1:
                SnackbarUtil.PrimarySnackbar(mContext,mToolbar,"FragmentActivity");
                Intent intent = new Intent(MainActivity.this,FragmentActivity.class);
                startActivity(intent);
                break;

        }
        return super.onOptionsItemSelected(item);
    }

    private void initRecycleView() {
        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        main_RecyclerView.setLayoutManager(layoutManager);
        mMianActivityAdapter = new DataAdapter(mContext,adapterList);
        main_RecyclerView.setAdapter(mMianActivityAdapter);
    }
}

代碼看的有點多,不過相對那種把什麼功能都放在 activity 來說已經不多了,並且看上面代碼結構清晰,功能明確,職責分明,耦合度低,很適合擴展。 ^-^ ///ide

其實上面的 activity 主要負責
(1) view 的 一些初始化,如:ui

@Bind(R.id.toolbar)
    protected Toolbar mToolbar;

    @Bind(R.id.swipe_refresh_layout)
    protected SwipeRefreshLayout mSwipeRefreshLayout;

    @Bind(R.id.main_RecyclerView)
    RecyclerView main_RecyclerView;
private void initRecycleView() {
        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        main_RecyclerView.setLayoutManager(layoutManager);
        mMianActivityAdapter = new DataAdapter(mContext,adapterList);
        main_RecyclerView.setAdapter(mMianActivityAdapter);
    }

(2)view 的一些更新,如:this

@Override
    public void showEmptyView() {
        SnackbarUtil.PrimarySnackbar(mContext,mToolbar,"請求數據爲空");
    }
/**
     * 初始化填充數據
     * @param mData
     */
    @Override
    public void fillData(List mData) {

        mMianActivityAdapter.insertedAllItem(mData);
    }

而數據的請求部分只有單單兩句:

mPresenter.initData();
 mPresenter.addMoreData();

那麼再來看一眼 什麼是 MVP 設計模式:

M就是Model ,這裏主要負責的就是業務處理,數據的獲取,例如數據庫的讀寫,http的網絡數據的處理。
V就是View ,顧名思義視圖的意思,這裏主要的任務就是處理各個界面ui控件的處理。
P就是Presenter ,控制器,這裏負責的是Model與View之間的聯繫操做。

我們的 activity 就是 mvp 中的 v 層 ,並且職責明確,只負責 ui 處理的 部分。

其餘都交給了 Presenter 去作, 那我們接下來再來分析分析 Presenter 是怎麼作到 操做
model 和 view 之間的聯繫的。

分析 MVP 中 P 層的實現 及 MainPresenter:

先看 activity 有繼承 IRefreshView 這個接口

public class MainActivity extends BaseSwipeRefreshActivity<MainPresenter> implements IRefreshView<String> {
}

那麼我們在 Presenter 取得數據 並調用 IRefreshView 接口,並在 MainActivity 實現 該接口的方法,這不就是:

P就是Presenter ,控制器,這裏負責的是Model與View之間的聯繫操做。

具體看一下 MainPresenter 類:

public class MainPresenter extends BasePresenter<IRefreshView>{

    public MainPresenter(Activity context, IRefreshView view) {
        super(context, view);
    }

    public void initData(){

        mView.showRefresh();

        List<String> strList = new ArrayList<String>();
        for (int i=0;i<10;i++){
            strList.add(""+i);
        }

        mView.getDataFinish();
        mView.fillData(strList);

    }

    public void addMoreData(){

        mView.showRefresh();

        List<String> strList = new ArrayList<String>();
        for (int i=0;i<10;i++){
            strList.add("more_"+i);
        }

        mView.getDataFinish();
        mView.appendMoreDataToView(strList);

    }

}

mPresenter.initData();
 mPresenter.addMoreData();

就是 MainPresenter 類 裏面的 方法 ,及Presenter 層,其實請求數據應該是 Model 層的,但我們的示例代碼請求模擬數據太簡單的,就沒有再弄個 類(及Model 層)來封裝。
數據請求前有個:

mView.showRefresh();

數據請求後有個:

mView.getDataFinish();

這就是 persenter 層控制 model 層和 view 層的 做用了。

接下來看一下 抽象 view :

public interface IRefreshView<T> extends ISwipeRefreshView {

    void fillData(List<T> mData);

    void appendMoreDataToView(List<T> mData);

    void hasNoMoreData();
 
}
public interface ISwipeRefreshView extends IBaseView {


    void getDataFinish();

    void showEmptyView();

    void showErrorView(Throwable throwable);

    void showRefresh();

    void hideRefresh();
}

好了,看到這裏不知道明白了 MVP 設計模式的原理和好處了沒。大概終結一下:
activity 或 fragment 或是 視圖層要作的一些數據請求從而跟新 視圖,能夠將中間這些操做交給 persenter 去作,視圖只負責 ui 的處理,而 persenter 須要 去操做 modle 獲得數據後通知跟新視圖,怎麼通知呢,就是 利用 接口回調 的形式 更新視圖。也就是這開頭講的這麼一句話:

將View層抽象成view接口,將業務邏輯通通交給 Presenter 層去作。

建議能夠下載源碼結合本片介紹,會有助於理解,本片博只是簡單介紹一下流程,源碼作了一點封裝,能夠到個人github clone ,歡迎stars ,此項目會繼續更新維護

相關文章
相關標籤/搜索