MVP實(shí)戰(zhàn)心得(四)---封裝優(yōu)化,拆分Toolbar與ContentView

轉(zhuǎn)載請標(biāo)明出處:http://www.lxweimin.com/p/6b4d764fbb24
本文出自:Jlanglang

前言:

最近發(fā)現(xiàn)之前封裝的結(jié)構(gòu),如果作為一個module依賴來開發(fā)時
就不是很好用了.只能慢慢改了.

之前不好的地方:

1.Toolbar與ContentView寫死在layout,如想要封裝loadingView(根據(jù)請求狀態(tài),顯示不同頁面),非常麻煩.
2.Toolbar復(fù)用是通過include,改動即需要修改layout,也需要修改代碼.
3.Presenter不能很好的控制Toolbar.

傳送門:MVP實(shí)戰(zhàn)心得(三)---封裝Retrofit2.0+RxAndroid+RxBus

思路:

1.參考源碼非NoactionBar主題,Toolbar應(yīng)該與ContentView分開。
2.參考源碼,base_layout的結(jié)構(gòu)可以是LinearLayout里面一個ViewStub(生成toolbar),一個Framlayout(ContentVIew).
3.一個快速開發(fā)框架,應(yīng)該有默認(rèn)的模板,默認(rèn)的樣式。
4.Toolbar屬于View范圍,初始化應(yīng)該在View里面,而不是在Presenter
5.參考AppCompatDelegate實(shí)現(xiàn),提供多種默認(rèn)的layout,根據(jù)layout生成不同的Toolbar。
6.繼承BaseActivity,可以通過復(fù)寫方法,控制是否需要Toolbar,以及自定義Toolbar。
7.ContentView應(yīng)該使用Framlayout,可以被自由改造,比如:loadingView。。
8,參考AppCompatDelegate,具體實(shí)現(xiàn)使用ToolbarHelper的實(shí)現(xiàn)類,來代理創(chuàng)建設(shè)置Toolbar....BaseActivity不需要去關(guān)心這個過程.

來張丑丑的圖:


m.png

新增的類:

UIView:

界面View,盡量讓Frgament與Activity之間的切換,變的方便.只需改動極少的代碼就能進(jìn)行切換
Presenter,可以通過ToolbarHelper,控制Toolbar進(jìn)行一些通用的設(shè)置.

ToolbarHelper

包含一些通用方法,如:getToolbar,setTitle,通過靜態(tài)方法Create()傳入不同的toolbarLayout的id,返回不同的實(shí)現(xiàn)類.

DefuatlToolbarHelperImplV1

默認(rèn)的Toolbar實(shí)現(xiàn).繼承BaseToolBarHelperImpl

BaseToolBarHelperImpl

繼承ToolbarHelper,否則創(chuàng)建toolbar,如果使用默認(rèn)布局,則通過ViewStub
創(chuàng)建,如果使用自定義布局,則直接findview獲取toolbar.

具體代碼:

UIView:

 package com.baozi.mvpdemo.ui.view;

import android.app.Activity;
import android.content.res.Resources;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.view.View;

/**
 * Created by baozi on 2017/2/20.
 * 用戶頁面,操作頁面,對應(yīng)Activity,frgament...
 */

public interface UIView extends BaseView {
    /**
     * id查找控件
     * 省去findviewById的強(qiáng)轉(zhuǎn)操作
     *
     * @param viewId 控件id
     * @param <V>    控件類型
     * @return V extends View
     */
    <V extends View> V findView(int viewId);

    /**
     * res資源獲取
     *
     * @return
     */
    Resources getResources();

    /**
     * 回退
     */
    void onBack();

    /**
     * 是否自定義布局
     *
     * @return
     */
    boolean isCustomLayout();

    /**
     * 是否使用MaterialDesign風(fēng)格
     *
     * @return
     */
    boolean isMaterialDesign();

    /**
     * MaterialDesign風(fēng)格,普通風(fēng)格之間轉(zhuǎn)換
     *
     * @param isMaterialDesign
     */
    void setMaterialDesignEnabled(boolean isMaterialDesign);

    /**
     * 獲取Acitivity
     *
     * @return
     */
    Activity getActivity();

    /**
     * Frgament跳轉(zhuǎn).
     *
     * @param tofragment
     */
    void startFragment(Fragment tofragment);

    /**
     * Frgament跳轉(zhuǎn).
     *
     * @param tofragment
     */
    void startFragment(Fragment tofragment, String tag);

    /**
     * 獲得getSupportActionBar
     *
     * @return
     */
    ActionBar getSupportActionBar();

    /**
     * 設(shè)置getSupportActionBar
     *
     * @param toolbar
     * @return
     */
    void setSupportActionBar(Toolbar toolbar);
    /**
     * 獲得ToolbarHelper,Presenter可以通過ToolbarHelper的來控制toolbar
     */
     ToolbarHelper getToolbarHelper();
}  


ToolbarHelper

package com.baozi.mvpdemo.helper;

import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.v7.widget.Toolbar;
import android.view.View;

import com.baozi.mvpdemo.R;
import com.baozi.mvpdemo.ui.view.UIView;

/**
 * @author jlanglang  2017/2/21 16:31
 * @版本 2.0
 * @Change
 */
public abstract class ToolbarHelper {
    public static final int DEFUATL_BASE_TOOLBAR_V1 = R.layout.base_toolbar;

    public ToolbarHelper() {

    } 
   /**
     * 創(chuàng)建具體的ToolbarHelper
     *
     * @param uiView        可以通過uiView,設(shè)置acitivity,fragment
     * @param toolbarLayout toolbarLayout的id
     * @return ToolbarHelper的具體實(shí)現(xiàn)
     */
    public static ToolbarHelper Create(@NonNull UIView uiView, @LayoutRes int toolbarLayout) {
        if (toolbarLayout == DEFUATL_BASE_TOOLBAR_V1) {
            return new DefuatlToolbarHelperImplV1(uiView, toolbarLayout);
        } else {
            return new BaseToolBarHelperImpl(uiView, toolbarLayout);
        }
    }
   /**
     * 初始化Toolbar,對toolbar進(jìn)行一些設(shè)置
     */
    public abstract void initToolbar();
  /**
     * 獲取創(chuàng)建的toolbar.
     * @return
     */
    public abstract Toolbar getToolbar();

    /**
     * 設(shè)置顯示MaterialDesign風(fēng)格,
     * @param isMaterialDesign 設(shè)置是否顯示
     */
    public abstract void setMaterialDesignEnabled(boolean isMaterialDesign);

    /**
     * 設(shè)置title
     *
     * @param str
     */

    public abstract void setTitle(@NonNull String str);

    public abstract void setTitle(@StringRes int str);

    /**
     * 設(shè)置左邊
     *
     * @param strId
     */
    public abstract void setLeftText(@StringRes int strId, View.OnClickListener clickListener);

    public abstract void setLeftText(@NonNull String str, View.OnClickListener clickListener);

    public abstract void setLeftButton(Drawable drawable, View.OnClickListener clickListener);

    public abstract void setLeftButton(@DrawableRes int drawableId, View.OnClickListener clickListener);


    /**
     * 設(shè)置右邊
     *
     * @param str
     */
    public abstract void setRightText(@NonNull String str, View.OnClickListener clickListener);

    public abstract void setRightText(@StringRes int strId, View.OnClickListener clickListener);

    public abstract void setRightButton(@NonNull Drawable drawable, View.OnClickListener clickListener);

    public abstract void setRightButton(@DrawableRes int drawableId, View.OnClickListener clickListener);
}

BaseToolBarHelperImpl

package com.baozi.mvpdemo.helper;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewStub;

import com.baozi.mvpdemo.R;
import com.baozi.mvpdemo.ui.view.UIView;

/**
 * @author jlanglang  2017/2/22 16:58
 * @版本 2.0
 * @Change
 */
public class BaseToolBarHelperImpl extends ToolbarHelper {
    protected int mToolbarLayout;
    protected Toolbar mToolbar;
    protected UIView mUIView;
    protected Context mContext;
    protected boolean isMaterialDesign;

    public BaseToolBarHelperImpl(@NonNull UIView uiView, int toolbarLayout) {
        this.mUIView = uiView;
        this.mContext = uiView.getContext();
        this.mToolbarLayout = toolbarLayout;
        ViewStub vs_toolbar = uiView.findView(R.id.vs_toolbar);
        if (vs_toolbar != null) {
            vs_toolbar.setLayoutResource(mToolbarLayout);
            mToolbar = (Toolbar) vs_toolbar.inflate();
        } else {
            mToolbar = uiView.findView(toolbarLayout);
        }
        initToolbar();
    }

    @Override
    public void initToolbar() {

    }

    @Override
    public Toolbar getToolbar() {
        return mToolbar;
    }

    @Override
    public void setMaterialDesignEnabled(boolean isMaterialDesign) {
        this.isMaterialDesign = isMaterialDesign;
 
    }

    @Override
    public void setTitle(@NonNull String str) {

    }

    @Override
    public void setTitle(@StringRes int str) {

    }

    @Override
    public void setLeftText(@StringRes int strId, View.OnClickListener clickListener) {

    }

    @Override
    public void setLeftText(@NonNull String str, View.OnClickListener clickListener) {

    }

    @Override
    public void setLeftButton(Drawable drawable, View.OnClickListener clickListener) {

    }

    @Override
    public void setLeftButton(@DrawableRes int drawableId, View.OnClickListener clickListener) {

    }

    @Override
    public void setRightText(@NonNull String str, View.OnClickListener clickListener) {

    }

    @Override
    public void setRightText(@StringRes int strId, View.OnClickListener clickListener) {

    }

    @Override
    public void setRightButton(@NonNull Drawable drawable, View.OnClickListener clickListener) {

    }

    @Override
    public void setRightButton(@DrawableRes int drawableId, View.OnClickListener clickListener) {

    }


}

DefuatlToolbarHelperImplV1

package com.baozi.mvpdemo.helper;

import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;

import com.baozi.mvpdemo.R;
import com.baozi.mvpdemo.ui.view.UIView;

/**
 * @author jlanglang  2017/2/21 16:44
 * @版本 2.0
 * @Change
 */

public class DefuatlToolbarHelperImplV1 extends BaseToolBarHelperImpl {
    private TextView mLeftText;
    private TextView mRightText;
    private ImageButton mLeftButton;
    private ImageButton mRightButton;
    private TextView mTitle;

    public DefuatlToolbarHelperImplV1(UIView uiView, @LayoutRes int toolbar) {
        super(uiView, toolbar);
    }

    @Override
    public void initToolbar() {
        mLeftText = (TextView) mToolbar.findViewById(R.id.tv_left);
        mRightText = (TextView) mToolbar.findViewById(R.id.tv_right);
        mLeftButton = (ImageButton) mToolbar.findViewById(R.id.ib_left);
        mRightButton = (ImageButton) mToolbar.findViewById(R.id.ib_right);
        mTitle = (TextView) mToolbar.findViewById(R.id.tv_title);
        setLeftButton(R.drawable.back, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mUIView.onBack();
            }
        });

    }

    /**
     * 應(yīng)該保證在調(diào)用Activity.setSupportActionBar()之后使用.
     *
     * @param isMaterialDesign
     */
    @Override
    public void setMaterialDesignEnabled(boolean isMaterialDesign) {
        super.setMaterialDesignEnabled(isMaterialDesign);
        ActionBar supportActionBar = mUIView.getSupportActionBar();
        if (supportActionBar == null) {
            return;
        }
        setTitle(mTitle.getText().toString());
        setLeftButton(mLeftButton.getDrawable(), new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mUIView.onBack();
            }
        });
    }

    @Override
    public void setTitle(@NonNull String title) {
        if (isMaterialDesign) {
            mUIView.getSupportActionBar().setTitle(title);
        } else {
            mTitle.setText(title);
        }
    }

    @Override
    public void setTitle(int titleId) {
        String title = mUIView.getResources().getString(titleId);
        setTitle(title);
    }


    @Override
    public void setLeftText(@NonNull String str, View.OnClickListener clickListener) {
        if (!isMaterialDesign) {
            mLeftButton.setVisibility(View.GONE);
            mLeftText.setVisibility(View.VISIBLE);
            mLeftText.setText(str);
            mLeftText.setOnClickListener(clickListener);
        }
    }

    @Override
    public void setLeftText(@StringRes int strId, View.OnClickListener clickListener) {
        String string = mUIView.getResources().getString(strId);
        setLeftText(string, clickListener);
    }

    @Override
    public void setLeftButton(@NonNull Drawable drawable, View.OnClickListener clickListener) {
        if (isMaterialDesign) {
            mToolbar.setNavigationIcon(drawable);
            mToolbar.setNavigationOnClickListener(clickListener);
            mLeftText.setVisibility(View.GONE);
            mLeftButton.setVisibility(View.GONE);
        } else {
            mLeftText.setVisibility(View.GONE);
            mLeftButton.setVisibility(View.VISIBLE);
            mLeftButton.setImageDrawable(drawable);
            mLeftButton.setOnClickListener(clickListener);
        }
    }

    @Override
    public void setLeftButton(@DrawableRes int drawableId, View.OnClickListener clickListener) {
        setLeftButton(ContextCompat.getDrawable(mUIView.getContext(), drawableId), clickListener);
    }

    @Override
    public void setRightText(@NonNull String str, View.OnClickListener clickListener) {
        if (!isMaterialDesign) {
            mRightButton.setVisibility(View.GONE);
            mRightText.setVisibility(View.VISIBLE);
            mRightText.setText(str);
            mRightText.setOnClickListener(clickListener);
        }
    }

    @Override
    public void setRightText(int strId, View.OnClickListener clickListener) {
        String string = mUIView.getResources().getString(strId);
        setRightText(string, clickListener);
    }

    @Override
    public void setRightButton(@NonNull Drawable drawable, View.OnClickListener clickListener) {
        if (!isMaterialDesign) {
            mRightText.setVisibility(View.GONE);
            mRightButton.setVisibility(View.VISIBLE);
            mRightButton.setImageDrawable(drawable);
        }

    }

    @Override
    public void setRightButton(int drawableId, View.OnClickListener clickListener) {
        setRightButton(ContextCompat.getDrawable(mUIView.getContext(), drawableId), clickListener);
    }
}

BaseActivity的變化

public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity
        implements BaseActivityView {
    protected T mPresenter;
    protected SparseArray<View> mViews;
    private ToolbarHelper mToolbarHelper;
    private boolean isMaterialDesign;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mViews = new SparseArray<>();
        //創(chuàng)建presenter
        mPresenter = initPresenter();
        //綁定Activity
        mPresenter.onAttch(this);
        //是否完全自定義layout
        if (isCustomLayout()) {
            initContentView(LayoutInflater.from(this), savedInstanceState);
        } else {
            super.setContentView(R.layout.activity_base);
            //創(chuàng)建contentView
            View view = initContentView(LayoutInflater.from(this), savedInstanceState);
            //添加contentView
            FrameLayout base_content = findView(R.id.base_content);
            if (view != null) {
                //交給Persenter去擴(kuò)展
                mPresenter.initContentView(base_content, view);
            }
            //創(chuàng)建toolbar
            createToolbar();
        }
        mPresenter.onCreate();
        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                mPresenter.LoadData();
                return false;
            }
        });
    }
    //復(fù)寫setContentView,如果不設(shè)置完全自定義布局,則不能調(diào)用setContentView()方法.
   @Override
    public void setContentView(@LayoutRes int layoutResID) {
        //是否完全自定義布局,也就是不使用base_layout
        if (isCustomLayout()) {
            super.setContentView(layoutResID);
        } else {
            throw new IllegalStateException("please setting Presenter Method isCustomLyout() return true ");
        }
    }
    ......

      /**
     * 通過viewId獲取控件
     *
     * @param viewId 資源id
     * @return
     */
    @Override
    public <V extends View> V findView(@IdRes int viewId) {
        View view = mViews.get(viewId);
        if (view == null) {
            view = findViewById(viewId);
            mViews.put(viewId, view);
        }
        return (V) view;
    }
}  

參考了很多,想了很久,死了很多腦細(xì)胞.- -

再附上githubdemo地址,不定期更新

mvpDemo
如果覺得有用就點(diǎn)個星吧.哈哈,


您的喜歡與建議是我最大的動力-_-

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容