转载了两篇文章我都感觉帮助不大…就开始自己摸索了
首先 我们需要了解 我们为什么要让系统栏变得透明?
还不是辣鸡Android 一开始就没有一个统一的设计规范导致软件设计五花八门 现在的Android已经拥有了手势导航 但显示效果依然并不乐观 当你看到你的应用下方有一个大大的白块时 你是不是强迫症犯了?
1. fitsSystemWindows
据说 这个属性那是特别特别神奇 可以完美避开所有系统区域 只需要在根布局中加上这个属性就能上天了!
事实真的如此吗?
我们来试一下
有什么问题吗?
当我们在根布局中加上这个属性的时候 你的应用一定出现了上下白边吧?
(失误点到了状态栏导致图片中没有出现状态栏 顶部是有白边的)
那好 Toolbar需要下移 我们给Toolbar设置属性 可以吗?
也并不可以 我们可以看到 Toolbar虽然正确地设置了上方填充 但是多了一个我们不需要的下方填充 设想如果用户使用2键或3键导航时 他们的表情会是如何
啊那就有人会问了 给根布局设置上一个有颜色的背景 然后再往里面加一个布局 这个布局中再应用我们的属性
先不做 分析一下可行性
- 这样做就会导致状态栏和导航栏中具有相同颜色的填充 不是我们需要的
- 底部布局无法延伸到导航栏 跟没做一样
怎么办?
另一种思路
再想想 我们是不是可以直接获取系统栏的高度 然后对我们需要处理的View设置Padding?
这个可以
我们用的是 WindowInset
我们需要获取到一个 inset
然后再调用其方法获取系统栏高度 再给控件设置对应的Padding
代码如下:
view.setOnApplyWindowInsetsListener { myView, windowInsets ->
myView.setPadding(myView.paddingLeft, windowInsets.systemWindowInsetTop, myView.paddingRight, myView.paddingBottom)
windowInsets
}
这样就能给控件顶部设置一个填充
以此类推 我们就得到了以下工具类中的方法:
internal object MyClass {
const val INSERT_TOP: Int = 0
const val INSERT_BOTTOM: Int = 1
const val INSERT_LEFT: Int = 2
const val INSERT_RIGHT: Int = 3
fun setInsert(type: Int, view: View) {
when(type) {
INSERT_TOP -> {
view.setOnApplyWindowInsetsListener { myView, windowInsets ->
myView.setPadding(myView.paddingLeft, windowInsets.systemWindowInsetTop, myView.paddingRight, myView.paddingBottom)
windowInsets
}
}
INSERT_BOTTOM -> {
view.setOnApplyWindowInsetsListener { myView, windowInsets ->
myView.setPadding(myView.paddingLeft, myView.paddingTop, myView.paddingRight, windowInsets.systemWindowInsetBottom)
windowInsets
}
}
INSERT_LEFT -> {
view.setOnApplyWindowInsetsListener { myView, windowInsets ->
myView.setPadding(windowInsets.systemWindowInsetLeft, myView.paddingTop, myView.paddingRight, myView.paddingBottom)
windowInsets
}
}
INSERT_RIGHT -> {
view.setOnApplyWindowInsetsListener { myView, windowInsets ->
myView.setPadding(myView.paddingLeft, myView.paddingTop, windowInsets.systemWindowInsetRight, myView.paddingBottom)
windowInsets
}
}
}
}
}
当然它还能简化 我暂时不想搞…
当我们需要使用的时候 只需这样:
setInsert(MyClass.INSERT_TOP, toolbar)
爽爆!