我搜索了文档,但只找到了这个:
链接。这是用来使酒吧半透明?我想做的是使状态栏完全透明(如下图所示),并使它向后兼容APK<19:
我的styles.xml:
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="android:actionBarStyle">@style/ThemeActionBar</item>
<item name="android:windowActionBarOverlay">true</item>
<!-- Support library compatibility -->
<item name="actionBarStyle">@style/ThemeActionBar</item>
<item name="windowActionBarOverlay">true</item>
</style>
<style name="ThemeActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid">
<item name="android:background"> @null </item>
<!-- Support library compatibility -->
<item name="background">@null</item>
<item name="android:displayOptions"> showHome | useLogo</item>
<item name="displayOptions">showHome|useLogo</item>
</style>
</resources>
我能做的是:
对于API > 23日/夜支持,您可以使用下面的扩展。要理解的重要部分是android:fitsSystemWindows="true"使用填充来在嵌入内移动(就像你会用一个工具栏)。因此,将它放在根布局中是没有意义的(除了DrawerLayout, CoordinatorLayout,…它们使用自己的实现)。
<style name="Theme.YourApp.DayNight" parent="Theme.MaterialComponents.DayNight.NoActionBar">
...
<item name="android:windowLightStatusBar">@bool/isDayMode</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<androidx.constraintlayout.widget.ConstraintLayout
...>
<com.google.android.material.appbar.MaterialToolbar
...
android:fitsSystemWindows="true">
</androidx.constraintlayout.widget.ConstraintLayout
fun Activity.transparentStatusBar() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
} else {
window.setDecorFitsSystemWindows(false)
}
}
然后像这样称呼它:
class YourActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
transparentStatusBar()
}
}
看看克里斯·巴内斯的这些幻灯片:成为窗户安装大师
编辑:如果你对导航栏后面的浮动内容有问题,请使用
// using Insetter
binding.yourViewHere.applySystemWindowInsetsToPadding(bottom = true)
你所需要做的就是在你的主题中设置这些属性:
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
你的活动/容器布局,你希望有一个透明的状态栏需要这个属性集:
android:fitsSystemWindows="true"
这通常是不可能执行这肯定在预kitkat,看起来你可以这样做,但一些奇怪的代码使它如此。
编辑:我推荐这个lib: https://github.com/jgilfelt/SystemBarTint为许多前棒棒糖状态栏颜色控制。
经过深思熟虑,我了解到完全禁用状态栏和棒棒糖导航栏上的半透明或任何颜色的答案是在窗口上设置这个标志:
// In Activity's onCreate() for instance
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
没有其他主题是必要的,它产生如下内容:
这个解决方案是为那些谁想要一个完全透明的状态栏和导航栏不受影响。令人难以置信的是,这听起来如此简单,以至于导致包括我在内的不止一个人头疼。
这就是我所说的最终结果
结果
我们只需要两个函数,我建议在我们的活动的OnCreate中调用,第一个是setStatusBar(),这是负责使透明的同一个。
private fun setStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.apply {
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else {
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
statusBarColor = Color.TRANSPARENT
}
}
第二个函数setedges()负责设置与顶部受限的视图相对应的边距,否则,这些视图将在StatusBar下面被看到。
private fun setMargins() {
ViewCompat.setOnApplyWindowInsetsListener(
findViewById(R.id.your_parent_view)
) { _, insets ->
val view = findViewById<FrameLayout>(R.id.your_child_view)
val params = view.layoutParams as ViewGroup.MarginLayoutParams
params.setMargins(
0,
insets.systemWindowInsetTop,
0,
0
)
view.layoutParams = params
insets.consumeSystemWindowInsets()
}
}
最终代码看起来像这样:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.your_layout))
setStatusBar()
setMargins()
}
private fun setStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.apply {
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else {
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
statusBarColor = Color.TRANSPARENT
}
}
private fun setMargins() {
ViewCompat.setOnApplyWindowInsetsListener(
findViewById(R.id.your_parent_view)
) { _, insets ->
val view = findViewById<FrameLayout>(R.id.your_child_view)
val params = view.layoutParams as ViewGroup.MarginLayoutParams
params.setMargins(
0,
insets.systemWindowInsetTop,
0,
0
)
view.layoutParams = params
insets.consumeSystemWindowInsets()
}
}
你可以在下面的文章中找到更详细的解释
我还留下了一个测试项目,这些概念在其中发挥作用。