转载请标明出处: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
如果觉得有用就点个星吧.哈哈,
您的喜欢与建议是我最大的动力-_-
网友评论