高效开发,打造通用Toolbar,适应90%的使用场景

2018-03-01 11:18:03来源:https://www.jianshu.com/p/552d8b9688ea作者:FrankChoo人点击

分享


临近过年, 这次不分析源码, 给大家带来一个通用的 Toolbar, 希望能带给大家点儿帮助
封装目的

选择自定义 View 实现 Toolbar, 是为了更好的实现两用性


既可以在XML文件中配合 CoordinatorLayout 使用实现炫酷的效果, 也可以通过代码直接构建


更加方便的使用添加返回按键, 标题, 菜单等


更加方便的添加点击事件


给用户自定义标题的权限


效果展示

非沉浸式




非沉浸式.png


沉浸式




沉浸式.png


自定义标题




定义标题栏.png


使用方式

在 style.xml 中,将主题改为 NoActionBar 的样式


基本用法


        GenericToolbar.Builder(this)
.addTitleImage(R.mipmap.ic_launcher)// 标题头像
.addTitleText("FrankChoo")// 标题文本
.setBackgroundColorResource(R.color.colorAccent)// 背景颜色
.addLeftIcon(1, R.drawable.icon_back) {}// 响应左部图标的点击事件
.addLeftText(2, "Left") {}// 响应左部文本的点击事件
.addRightText(3, "Right") {}// 响应右部文本的点击事件
.addRightIcon(4, R.drawable.icon_left) {}// 响应右部图标的点击事件
.setTextColor(Color.BLACK)// 会全局设置字体的颜色, 自定义标题除外
.apply()

调整图标和文本大小
    // 图标宽高
GenericToolbar.Builder(this)
.addLeftIcon(1, R.drawable.icon_back, /*Width*/50, /*Height*/50) {}
...
// 文本大小
GenericToolbar.Builder(this)
.addLeftText(2, "Left", 20f) {}// 响应左部文本的点击事件

自定义标题
    // 1. 创建View
val titleView = LayoutInflater.from(this).inflate(R.layout.toolbar_title,
window.decorView as ViewGroup, false)
// 2. 动态填充
GenericToolbar.Builder(this)
.addCustomTitle(titleView)
...

状态栏
public enum Style {
TRANSPARENT,// 全透明
TRANSLUCENCE,// 半透明
HIDE,// 隐藏
DEFAULT// 默认
}
// 直接使用的方式
AppBarHelper.with(this).setStatusBarStyle(Style.TRANSPARENT).apply()
// 通过Builder直接构建的方式
GenericToolbar.Builder(this)
.setStatusBarStyle(Style.TRANSPARENT)// 只需要在这里集成即可

实现思路

看完了集成方式, 下面看看实现思路:


技术难点:


动态集成:
分析过 setContentView() 源码(https://www.jianshu.com/p/3872219cc07a)的我们都知道, DecorView 是系统默认的 Window 下的顶层View, DecorView 的内部只有一个子View, 但这个子 View, 会根据不同的特征去 inflate 系统提供的不同的布局
这个系统布局中有一个共性: 存在一个 @id 为 com.android.internal.R.id.content 的 FrameLayout 容器
这就是我们 setContentView() 的父容器(不考虑继承自AppCompatActivity时, 其在内部进行的多次填充处理)

好的, 我们就把 Toolbar 添加到这个容器中的第 0 个位置, 然后让之前的 View margin 一个 ActionBar 的高度就完成了, 完美的保证了通用性


沉浸式状态栏: 为了支持沉浸式状态栏, 需要根据用户传入的参数, 动态的改变 GenericToolbar 的 padding 值, 以完美的适应沉浸式状态栏
相关
代码, 详情见底部 GitHub 传送门
        // 动态的调整以适应 Toolbar 的嵌入
private void adjustLayout() {
if (mContentParent != null
&& !(mContentParent instanceof LinearLayout)) {
// 将我们的主体布局移动到Toolbar的下方
MarginLayoutParams params = (MarginLayoutParams)
mContentParent.getChildAt(1).getLayoutParams();
params.topMargin += getNeedMarginHeight();
mContentParent.getChildAt(1).setLayoutParams(params);
}
}

// 获取需要 Margin 的值
private int getNeedMarginHeight() {
int toolbarCurHeight = mToolbar.getHeight();
if (isAdjustTransparentStatusBar(mStyle)) {
// 若设置了沉浸式状态栏
// toolbar的高度最小为getStatusBarHeight() + getActionBarHeight()
if (toolbarCurHeight < getStatusBarHeight() + getActionBarHeight()) {
toolbarCurHeight = getStatusBarHeight() + getActionBarHeight();
}
}
return toolbarCurHeight;
}

GitHub传送门

https://github.com/FrankChoo/GenericToolbar/tree/master
把这三个文件拷走即可使用, 不要吝啬你们的小星星哦~~哈哈哈




必要文件.png







最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台