美文网首页资料 | 汇总Android实用技术Android技术知识
MVP实战心得(四)---封装优化,拆分Toolbar与Cont

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

作者: Jlanglang | 来源:发表于2017-02-23 00:23 被阅读1438次

    转载请标明出处: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;
     
        }
    
        @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
    如果觉得有用就点个星吧.哈哈,


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

    相关文章

      网友评论

      本文标题:MVP实战心得(四)---封装优化,拆分Toolbar与Cont

      本文链接:https://www.haomeiwen.com/subject/wulvwttx.html