Android View 高级框架一 Builder模式打造通用TitleBar
2017-10-09 20:46
591 查看
1 简介
我们在开发中往往都有一个TitleBar在APP最上面。例如下图这个TitleBar如果每次都写在布局中,则每个Activity都要在布局中展现。会增加布局的复杂度,另外也不便于维护。另外,对于不同的界面,有时候这个TitleBar又会有所差别。因此怎么定制化一个可以复用又方便维护的TitleBar呢?
当然,我们也可以单独写一个布局文件,然后每个Activity的界面include进去,但是这样每个Activity界面都需要要单独的findViewById。后期的维护性其实也不是很强。
2 TitleBar框架
设计的TitleBar框架如下图可以看到,我们采用了Builder设计模式,来构造我们的TitleBar的各种参数。另外,我们在基类中指定了布局的文件及bindView的方法。从而使我们的应用能绑定到Activity的根布局上。
具体的逻辑如下:
/** * 绑定View到ActivityRoot上 */ private void bindViewToActivityRoot() { ViewGroup activityRoot = null; //创建View if (mParams.mActivityRoot == null || activityRoot == null){ //获取Activity的根布局 activityRoot = (ViewGroup) ((Activity)mParams.mContext).findViewById(android.R.id.content); //获取我们在Activity中设置ContentView的View mParams.mActivityRoot = (ViewGroup)activityRoot.getChildAt(0); LogManager.i(TAG,"activityRoot size : " +activityRoot.getChildCount() + " mParams.mActivityRoot:" + mParams.mActivityRoot); } if (mParams.mActivityRoot == null){ return; } mNavigationView = LayoutInflater.from(mParams.mContext) .inflate(bindLayoutId(),activityRoot,false); if (mParams.mActivityRoot instanceof RelativeLayout){ //相对布局 //先构造一个线性布局,指定垂直排列 LinearLayout newActivityRoot = new LinearLayout(mParams.mContext); newActivityRoot.setOrientation(LinearLayout.VERTICAL); //移除原有的activityRoot的parent,否则会报"The specified child already has a parent. " + //"You must call removeView() on the child's parent first. 异常 ViewGroup viewParent = (ViewGroup)mParams.mActivityRoot.getParent(); viewParent.removeAllViews(); //将titleBar添加为第一个child,原来的activityRoot为第二个 newActivityRoot.addView(mNavigationView,0); newActivityRoot.addView(mParams.mActivityRoot,1); //将新的activityRoot添加到android.R.id.content中 activityRoot.addView(newActivityRoot,0); LogManager.i(TAG,"mParams.mActivityRoot,child at 0 view:"); }else { //添加View到mParams.mParent中 mParams.mActivityRoot.addView(mNavigationView,0); } LogManager.i(TAG,"mParams.mActivityRoot,child:" + mParams.mActivityRoot.getChildCount()); //绑定View bindView(); }
这里有一点技巧就是,我们的Activity的布局最终是添加到id为android.R.id.content的一个FrameLayout
布局中的,然后获取我们的Activity界面的根布局,将TitleBar布局添加到根布局的第一个位置处。这样就完成了我们TitleBar布局的添加,省去了在xml中添加了。
一个具体的TitleBar需要继承BaseTitleBar和继承BaseTitleParams,然后实现bindLayoutId()和bindView()。
3 CommonTitleBar
CommonTitleBar是一个具体的例子,效果图如下:我们先来看它的UML类图
可以看到,CommonTitleBar主要继承自BaseTitleBar。它的源码如下:
/** * Email: 1273482124@qq.com * Created by qiyei2015 on 2017/5/14. * Version: 1.0 * Description: */ public class CommonTitleBar extends BaseTitleBar<CommonTitleParams> { protected CommonTitleBar(CommonTitleParams params) { super(params); } /** * 布局文件 * @return */ @Override public int bindLayoutId() { return R.layout.title_bar; } @Override public void bindView() { setText(R.id.title,mParams.mTitle); setText(R.id.right_text,mParams.mRightText); setOnClickListener(R.id.right_text,mParams.mRightClickListener); // 左边 要写一个默认的 finishActivity setOnClickListener(R.id.back,mParams.mLeftClickListener); } /** * 设置Tiltle * @param title */ public void setTitle(String title){ mParams.mTitle = title; setText(R.id.title,mParams.mTitle); } /** * 设置右侧文字 * @param text * @return */ public void setRightText(String text){ mParams.mRightText = text; setText(R.id.right_text,mParams.mRightText); } /** * Builder模式设置各种效果 */ public static class Builder extends BaseTitleBar.Builder{ /** * 所有的效果参数 */ CommonTitleParams mBarParams; public Builder(Context context) { super(context); mBarParams = new CommonTitleParams(context,null); } /** * 设置Title * @param title * @return */ public Builder setTitle(String title){ mBarParams.mTitle = title; return this; } /** * 设置右侧文字 * @param text * @return */ public Builder setRightText(String text){ mBarParams.mRightText = text; return this; } /** * 设置右侧点击事件 * @param listener * @return */ public Builder setRightClickListener(View.OnClickListener listener){ mBarParams.mRightClickListener = listener; return this; } /** * 创建CommonNavigationBar * @return */ @Override public CommonTitleBar build() { return new CommonTitleBar(mBarParams); } } }
CommonTitleBar主要封装了一些公共的返回按钮图标及响应的点击事件,右侧的文字,标题等内容。可根据项目的实际情况进行自定义其他的TitleBar
可以看到这是一个典型的Builder模式,主要的参数都存放在CommonTitleParams这个类中。如果项目有多个类型风格不同的TitleBar,则可以定义不同的TitleBar
详细的源码请参考
github https://github.com/qiyei2015/EssayJoke 中SDK 下的titlebar目录
相关文章推荐
- Android View 高级框架二 Builder模式打造通用对话框
- Android tab导航的几种方法:ActionBar tab +fragment,Viewpager+pagerTitleStrip,开源框架ViewPageIndicator 和 ViewPager
- Android自定义View之TitleBar,通用标题栏
- 【Android自定义View实战】之自定义项目通用的标题栏CustomTitleBar
- Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (上)
- Android打造自己的RecyclerView之通用Adapter(一)
- Android进阶学习-打造一个通用的RecyclerViewAdapter
- 打造Android万能上拉下拉刷新框架--XRefreshView(三)
- Android通用LoadingView加载框架详解
- android 用mvp模式来架构自己的app+打造Recyclerview万能适配器
- Android高级之Volley框架(三):ImageRequest、ImageLoader、NewworkImageView的使用
- Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (下)
- Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (上)
- android高级框架xUtils之ViewUtils
- Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (上)
- Android中ViewPager常用功能5----MagicIndicator(框架)打造ViewPager指示器
- Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (上)
- Android高级之xUtils框架(一):ViewUtils的用法
- Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (下)
- Android高级之xUtils框架(一):ViewUtils的用法