轉(zhuǎn)載請標(biāo)明出處:http://www.jianshu.com/p/6b4d764fbb24 本文出自:Jlanglang
前言:
最近發(fā)現(xiàn)之前封裝的結(jié)構(gòu),如果作為一個(gè)module依賴來開發(fā)時(shí) 就不是很好用了.只能慢慢改了.
之前不好的地方:
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里面一個(gè)ViewStub(生成toolbar),一個(gè)Framlayout(ContentVIew). 3.一個(gè)快速開發(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)心這個(gè)過程.
來張丑丑的圖:

新增的類:
UIView:
界面View,盡量讓Frgament與Activity之間的切換,變的方便.只需改動極少的代碼就能進(jìn)行切換 Presenter,可以通過ToolbarHelper,控制Toolbar進(jìn)行一些通用的設(shè)置.
包含一些通用方法,如:getToolbar,setTitle,通過靜態(tài)方法Create()傳入不同的toolbarLayout的id,返回不同的實(shí)現(xiàn)類.
默認(rèn)的Toolbar實(shí)現(xiàn).繼承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();} 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);}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; ActionBar supportActionBar = mUIView.getSupportActionBar(); if (supportActionBar != null) { supportActionBar.setDisplayUseLogoEnabled(isMaterialDesign); supportActionBar.setDisplayShowHomeEnabled(isMaterialDesign); supportActionBar.setDisplayShowCustomEnabled(isMaterialDesign); supportActionBar.setDisplayHomeAsUpEnabled(isMaterialDesign); supportActionBar.setDisplayShowTitleEnabled(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) { }}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)個(gè)星吧.哈哈,
您的喜歡與建議是我最大的動力-_-