首页 > 学院 > 开发设计 > 正文

MVP实战心得(四)---封装优化,拆分Toolbar与ContentView

2019-11-08 00:27:17
字体:
来源:转载
供稿:网友

转载请标明出处:http://www.jianshu.com/p/6b4d764fbb24  本文出自:Jlanglang

前言:

最近发现之前封装的结构,如果作为一个module依赖来开发时 就不是很好用了.只能慢慢改了.

之前不好的地方:

1.Toolbar与ContentView写死在layout,如想要封装loadingView(根据请求状态,显示不同页面),非常麻烦. 2.Toolbar复用是通过include,改动即需要修改layout,也需要修改代码. 3.PResenter不能很好的控制Toolbar.

传送门:MVP实战心得(三)—封装Retrofit2.0+RxAndroid+RxBus

思路:

1.参考源码非NoactionBar主题,Toolbar应该与ContentView分开。 2.参考源码,base_layout的结构可以是LinearLayout里面一个ViewStub(生成toolbar),一个Framlayout(ContentVIew). 3.一个快速开发框架,应该有默认的模板,默认的样式。 4.Toolbar属于View范围,初始化应该在View里面,而不是在Presenter 5.参考AppCompatDelegate实现,提供多种默认的layout,根据layout生成不同的Toolbar。 6.继承BaseActivity,可以通过复写方法,控制是否需要Toolbar,以及自定义Toolbar。 7.ContentView应该使用Framlayout,可以被自由改造,比如:loadingView。。 8,参考AppCompatDelegate,具体实现使用ToolbarHelper的实现类,来代理创建设置Toolbar….BaseActivity不需要去关心这个过程.

来张丑丑的图:


m.png

新增的类:

UIView:

界面View,尽量让Frgament与Activity之间的切换,变的方便.只需改动极少的代码就能进行切换 Presenter,可以通过ToolbarHelper,控制Toolbar进行一些通用的设置.

ToolbarHelper

包含一些通用方法,如:getToolbar,setTitle,通过静态方法Create()传入不同的toolbarLayout的id,返回不同的实现类.

DefuatlToolbarHelperImplV1

默认的Toolbar实现.继承BaseToolBarHelperImpl

BaseToolBarHelperImpl

继承ToolbarHelper,否则创建toolbar,如果使用默认布局,则通过ViewStub 创建,如果使用自定义布局,则直接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. * 用户页面,操作页面,对应Activity,frgament... */public interface UIView extends BaseView { /** * id查找控件 * 省去findviewById的强转操作 * * @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风格 * * @return */ boolean isMaterialDesign(); /** * MaterialDesign风格,普通风格之间转换 * * @param isMaterialDesign */ void setMaterialDesignEnabled(boolean isMaterialDesign); /** * 获取Acitivity * * @return */ Activity getActivity(); /** * Frgament跳转. * * @param tofragment */ void startFragment(Fragment tofragment); /** * Frgament跳转. * * @param tofragment */ void startFragment(Fragment tofragment, String tag); /** * 获得getSupportActionBar * * @return */ ActionBar getSupportActionBar(); /** * 设置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() { } /** * 创建具体的ToolbarHelper * * @param uiView 可以通过uiView,设置acitivity,fragment * @param toolbarLayout toolbarLayout的id * @return ToolbarHelper的具体实现 */ 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进行一些设置 */ public abstract void initToolbar(); /** * 获取创建的toolbar. * @return */ public abstract Toolbar getToolbar(); /** * 设置显示MaterialDesign风格, * @param isMaterialDesign 设置是否显示 */ public abstract void setMaterialDesignEnabled(boolean isMaterialDesign); /** * 设置title * * @param str */ public abstract void setTitle(@NonNull String str); public abstract void setTitle(@StringRes int str); /** * 设置左边 * * @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); /** * 设置右边 * * @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; 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) { }}

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(); } }); } /** * 应该保证在调用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<>(); //创建presenter mPresenter = initPresenter(); //绑定Activity mPresenter.onAttch(this); //是否完全自定义layout if (isCustomLayout()) { initContentView(LayoutInflater.from(this), savedInstanceState); } else { super.setContentView(R.layout.activity_base); //创建contentView View view = initContentView(LayoutInflater.from(this), savedInstanceState); //添加contentView FrameLayout base_content = findView(R.id.base_content); if (view != null) { //交给Persenter去扩展 mPresenter.initContentView(base_content, view); } //创建toolbar createToolbar(); } mPresenter.onCreate(); Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { mPresenter.LoadData(); return false; } }); } //复写setContentView,如果不设置完全自定义布局,则不能调用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; }}

参考了很多,想了很久,死了很多脑细胞.- -

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

mvpDemo 如果觉得有用就点个星吧.哈哈,


您的喜欢与建议是我最大的动力-_-


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表