红橙Darren视频笔记 builder设计模式+navigationBar导航条
思路
套用之前的builder设计模式的思路
Product(NavigationBar)+Builder+Parameter
效果:
mainActivity代码
@Overrideprotected void initTitle() {new DefaultNavigationBar.Builder(this).setTitle("投稿").setRightIcon(R.mipmap.ic_launcher).setRightText("右边").setRightClickListener(v -> Toast.makeText(MainActivity.this, "右边", Toast.LENGTH_SHORT).show()).builder();}
DefaultNavigationBar
public class DefaultNavigationBar<D extendsDefaultNavigationBar.Builder.DefaultNavigationParams> extendsAbsNavigationBar<DefaultNavigationBar.Builder.DefaultNavigationParams> {public DefaultNavigationBar(Builder.DefaultNavigationParams params) {super(params);}@Overridepublic int bindLayoutId() {// 默认title bar布局return R.layout.title_bar;}@Overridepublic void applyView() {// 应用效果setText(R.id.title, getParams().mTitle);setText(R.id.right_text, getParams().mRightText);setOnClickListener(R.id.right_text, getParams().mRightClickListener);// 默认左边button是返回button 作用为finishActivitysetOnClickListener(R.id.back, getParams().mLeftClickListener);}public static class Builder extends AbsNavigationBar.Builder {DefaultNavigationParams P;public Builder(Context context, ViewGroup parent) {super(context, parent);P = new DefaultNavigationParams(context, parent);}public Builder(Context context) {super(context, null);P = new DefaultNavigationParams(context, null);}@Overridepublic DefaultNavigationBar builder() {return new DefaultNavigationBar(P);}// 存储所有效果到DefaultNavigationParamspublic Builder setTitle(String title) {P.mTitle = title;return this;}// 存储右边的文字public Builder setRightText(String rightText) {P.mRightText = rightText;return this;}// 存储右边的点击事件public Builder setRightClickListener(View.OnClickListener rightListener) {P.mRightClickListener = rightListener;return this;}// 存储左边的点击事件public Builder setLeftClickListener(View.OnClickListener rightListener) {P.mLeftClickListener = rightListener;return this;}// 存储右边的图片public Builder setRightIcon(int rightRes) {P.mRightImageId = rightRes;return this;}public static class DefaultNavigationParams extendsAbsNavigationParams {// 存储所有可控制navigationBar的变量public String mTitle;public String mRightText;public View.OnClickListener mRightClickListener;public View.OnClickListener mLeftClickListener = v -> {// 关闭当前Activity((Activity) mContext).finish();};public int mRightImageId;public DefaultNavigationParams(Context context, ViewGroup parent) {super(context, parent);}}}
}
DefaultNavigationParams P;在Builder的构造方法初始化
之后通过各种set方法将属性存放到DefaultNavigationParams
builder方法返回DefaultNavigationBar对象 同时在基类中进行mParams的赋值 createAndBind调用
createAndBind中第一步找到DecorView的第一个子布局 该布局就是navigationBar的父容器
具体参见:
https://blog.csdn.net/u011109881/article/details/111085949
的这张图片
第二步调用applyView将之前各种set方法设置的属性值应用在NavigationBar上
public abstract class AbsNavigationBar<P extends AbsNavigationBar.Builder.AbsNavigationParams> implements INavigationBar {//此处使用泛型 外部传入的参数params有可能是AbsNavigationBar.Builder.NavigationParams的子类(在AbsNavigationBar的具体实现类中)private static final String TAG = "AbsNavigationBar";// 存储默认的配置参数private P mParams;// 存放navigationBar的布局private View mNavigationView;public AbsNavigationBar(P params) {this.mParams = params;createAndBind();}//根据viewId查找导航条上显示的Stringpublic String getString(int viewId) {return this.mParams.mContext.getResources().getString(viewId);}//根据viewId查找导航条上显示的颜色public int getColor(int viewId) {return ContextCompat.getColor(this.mParams.mContext, viewId);}public P getParams() {return mParams;}// 设置文本public void setText(int viewId, CharSequence text) {// 每次都 findViewById 减少findViewById的次数View view = mNavigationView.findViewById(viewId);if (view != null) {try {//利用反射使得所有带有setText(CharSequence)的方法的控件都可以调用setText的方法Class clazz = view.getClass();Method setTextMethod = clazz.getMethod("setText", CharSequence.class);setTextMethod.invoke(view, text);view.setVisibility(View.VISIBLE);} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {Log.e(TAG, "setText: error " + e.getMessage());e.printStackTrace();}}}// 设置点击事件public void setOnClickListener(int viewId, View.OnClickListener listener) {View view = mNavigationView.findViewById(viewId);if (view != null) {view.setOnClickListener(listener);}}// 设置图片public void setImageResource(int viewId, int resourceId) {ImageView imageView = mNavigationView.findViewById(viewId);if (imageView instanceof ImageView) {imageView.setImageResource(resourceId);}else{Log.e(TAG, "设置图片失败");}}/*** 创建和绑定布局*/public void createAndBind() {if(mParams.mParent == null){// 获取DecorViewViewGroup activityRoot = (ViewGroup) ((Activity) mParams.mContext).getWindow().getDecorView();// 获取navigationBar的父容器viewGroup(R.id.content的父布局)mParams.mParent = (ViewGroup) activityRoot.getChildAt(0);}if(mParams.mParent == null){Log.e(TAG, "导航条的布局为空");return;}// 填充navigationBarmNavigationView = LayoutInflater.from(mParams.mContext).inflate(bindLayoutId(), mParams.mParent, false);// 将布局添加到parent的头部mParams.mParent.addView(mNavigationView, 0);applyView();}// 用于构建导航条类 这个类只是定义默认的配置 具体功能的实现由具体的实现类决定public abstract static class Builder {// 构造方法public Builder(Context context, ViewGroup parent) {}// 创建导航条方法public abstract AbsNavigationBar builder();// NavigationParams用于存储默认的配置参数public static abstract class AbsNavigationParams {public Context mContext;// NavigationBar显示的父布局public ViewGroup mParent;public AbsNavigationParams(Context context, ViewGroup parent) {this.mContext = context;this.mParent = parent;}}}
}
INavigationBar的定义
interface INavigationBar {// 绑定布局IDint bindLayoutId();// 给View设置参数void applyView();
}
主体部分就这么多 其他一些资源文件如下
navigationBar默认布局layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"style="@style/title_bar_style"><ImageViewandroid:layout_centerVertical="true"android:id="@+id/back"style="@style/back_view" /><TextViewandroid:id="@+id/title"style="@style/title_text_style"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:ellipsize="end"android:singleLine="true"android:visibility="gone"/><TextViewandroid:id="@+id/right_text"android:visibility="gone"style="@style/title_bar_button"android:layout_alignParentRight="true" />
</RelativeLayout>
各个style
<?xml version="1.0" encoding="utf-8"?>
<resources><style name="title_bar_style"><item name="android:background">@color/title_bar_bg_day</item><item name="android:paddingLeft">0.0dip</item><item name="android:paddingRight">0.0dip</item><item name="android:layout_width">fill_parent</item><item name="android:layout_height">44.0dip</item></style><style name="title_text_style"><item name="android:textSize">18.0sp</item><item name="android:textColor">@color/s9</item></style><style name="title_bar_button"><item name="android:textSize">16.0sp</item><item name="android:textColor">@color/s9</item><item name="android:gravity">center</item><item name="android:background">@null</item><item name="android:paddingLeft">5.0dip</item><item name="android:paddingRight">5.0dip</item><item name="android:layout_width">wrap_content</item><item name="android:layout_height">fill_parent</item><item name="android:layout_marginLeft">0.0dip</item><item name="android:layout_marginRight">10.0dip</item></style><style name="back_view" parent="@style/title_bar_button"><item name="android:layout_height">wrap_content</item><item name="android:gravity">center</item><item name="android:background">@drawable/btn_back</item><item name="android:paddingLeft">0.0dip</item><item name="android:paddingRight">0.0dip</item><item name="android:layout_marginLeft">0.0dip</item><item name="android:layout_marginRight">0.0dip</item><item name="android:text">@null</item><item name="android:drawableLeft">@null</item></style>
</resources>
返回键的资源
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/ic_back_pressed" android:state_pressed="true" /><item android:drawable="@drawable/ic_back_pressed" android:state_enabled="false" /><item android:drawable="@drawable/ic_back_normal" />
</selector><vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="24dp"android:height="24dp"android:viewportWidth="24"android:viewportHeight="24"android:tint="?attr/colorControlNormal"><pathandroid:fillColor="#999"android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
</vector><vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="24dp"android:height="24dp"android:viewportWidth="24"android:viewportHeight="24"android:tint="?attr/colorControlActivated"><pathandroid:fillColor="#FFF"android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
</vector>
红橙Darren视频笔记 builder设计模式+navigationBar导航条相关推荐
- 红橙Darren视频笔记 builder设计模式 navigationbar 导航栏第二版
1.builder设计模式简介 builder的实际应用的典型案例有AlertDialog和OKHttp 例如 // AlertDialogAlertDialog alertDialog = new ...
- 红橙Darren视频笔记 UML图简介
整体架构复制自红橙原视频的课堂笔记 因为他这一课没有博客,所以没有转载链接,CSDN没有转载地址是无法作为转载类型的文章发表的,暂时标记为原创 参考链接 https://blog.csdn.net/r ...
- 红橙Darren视频笔记 代理模式 动态代理和静态代理
红橙Darren视频笔记 代理模式 动态代理和静态代理(Android API 25) 关于代理模式我之前有过相关的介绍: https://blog.csdn.net/u011109881/artic ...
- 红橙Darren视频笔记 类加载机制(API28) 自己写个热修复 查看源码网站
第一部分 类加载机制 一个Activity是如何被Android虚拟机找到的? 在之前的文章 红橙Darren视频笔记 自定义View总集篇(https://blog.csdn.net/u011109 ...
- 红橙Darren视频笔记 利用阿里巴巴AndFix进行热修复
注意 由于AndFix在2017年左右就停止更新了,在最新版本的apk上遇到很多问题,我最终也没有成功进行热修复.本节主要是学习热修复的原理 在上一篇 红橙Darren视频笔记 自己捕获异常并保存到本 ...
- 红橙Darren视频笔记 Behavior的工作原理源码分析
主要coordinatorlayout的代码来自coordinatorlayout-1.0.0-sources.jar 本文从源码介绍 CoordinatorLayout 的 behavior 怎么工 ...
- 红橙Darren视频笔记 仿QQ侧滑效果
这一篇没有什么新的内容 就是改写 红橙Darren视频笔记 仿酷狗侧滑效果 的侧滑的效果 1.去掉淡入淡出效果 2.加上黑色模板效果 效果: 去掉淡入淡出效果很简单 就是注释掉onScrollChan ...
- 红橙Darren视频笔记 ViewGroup事件分发分析 基于API27
本节目标,通过案例,先看程序运行结果,然后跟踪源码,理解为什么会有这样的输出,继而理解view group的分发机制,感觉和证明题很像呢. 考虑以下程序的运行结果: case1: public cla ...
- 红橙Darren视频笔记 万能Dialog builder设计模式
1.Android原生的AlertDialog 我们今天看一下AlertDialog的创建方式以及它使用到的builder设计模式 我们先看看原生Android的AlertDialog创建方式: Al ...
最新文章
- 记录两段经典标定代码
- 解决升级 Office 2010 之后 Outlook 提示“无法打开 Microsoft Outlook”
- httpd设置HTTPS双向认证
- 解决Cacti监控图像断断续续问题
- Midletinfo-探索手机javaME系统信息的实用工具
- Android实现计算器布局(表格布局)
- 社会工程学之《反欺骗的艺术》小结(三)
- 测试金士顿固态硬盘软件,金士顿固态硬盘优化工具(Kingston Toolbox)
- 必须收藏!130 个相见恨晚的超实用网站,一次性分享出来
- 汇编 十六进制转二进制
- android模拟器虚拟机的下载、安装和使用
- 解决Java下载Zip压缩文件,解压后报不可预料的压缩文件末端
- 两个次序统计量的联合密度函数
- 安信天行全方位信息安全态势感知平台建设与运营
- springboot整合logback日志
- ESP32开发路程——环境搭建、引脚、烧录、UART、ADC、WS2812、RFID、DAC、FreeRTOS、CJSON
- 无光照渲染shader-二次元
- URI RUL和URN的区别(看不懂?)
- 蓝图(Blueprint)理解
- 推荐三个 VSCode 摸鱼插件
热门文章
- linux 根目录分配多少好,Linux下硬盘怎么分区才合适:根分区(/)交换分区(/swap)和/boot分区需要多大...
- 《网络对抗》Exp5 MSF基础应用
- IntelliJ IDEA 2017新工具
- Linux下能访问Nginx,本地无法访问
- 检测文件是否有BOM 头,并删除BOM头(php)
- [SQL] 常用查询脚本
- 《Programming with Objective-C》第四章 Encapsulating Data
- Android 之 Window、WindowManager 与窗口管理
- Asp.net(c#)GridView分页时用图片显示上一页,下一页
- C语言课后习题(44)