アプリの開発では、より良い視覚効果を提供するために、フルスクリーン表示と没入型表示の両方が一般的です。私の過去の開発経験では、これを実現するために、通常、サードパーティのライブラリであるImmersionBarを使用しています。今日は、公式APIを使って実装する方法を紹介します。
没入型ディスプレイ
没入型の表示とは、ステータスバーを引き続き表示できることを意味しますが、ステータスバーの背景は透明であり、アプリのUIから明確に分離されていません。
非没入型画像:
没入型コードは次のように実装されます。
//修改全局主题中statusBarColor和navigationBarColor为透明
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.ExampleDemo" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<!-- Customize your theme here. -->
</style>
</resources>
class ImmersionActivity : AppCompatActivity() {
private lateinit var windowInsetsController: WindowInsetsControllerCompat
lateinit var binding: LayoutImmersionActivityBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.layout_immersion_activity)
WindowCompat.setDecorFitsSystemWindows(window, false)
windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
windowInsetsController.isAppearanceLightNavigationBars = false
binding.btnChangeToLightBar.setOnClickListener {
//顶部布局为亮色
lightBar()
}
binding.btnChangeToDarkBar.setOnClickListener {
//顶部布局为深色
darkBar()
}
}
private fun lightBar() {
binding.topView.setBackgroundColor(ContextCompat.getColor(this, R.color.white))
binding.tvTitle.setTextColor(ContextCompat.getColor(this, R.color.black))
setBarStatus(true)
}
private fun darkBar() {
binding.topView.setBackgroundColor(ContextCompat.getColor(this, R.color.color_23242a))
binding.tvTitle.setTextColor(ContextCompat.getColor(this, R.color.white))
setBarStatus(false)
}
//改变状态栏文字和图标的颜色(根据顶部布局的背景色来决定)
private fun setBarStatus(light: Boolean) {
windowInsetsController.isAppearanceLightStatusBars = light
}
}
効果は図のようになります。
間隔を設定する
アプリの上部にあるタイトルとステータスバーが非常に小さいことがわかります。これは私が望む効果とは異なり、下部のドットコントロールも透明なナビゲーションバーによってブロックされています。オフィシャルは、これらの状況に対処するための対応するAPIを提供します。
コードは次のように表示されます。
//重复的部分省略了
class ImmersionActivity : AppCompatActivity() {
...
private var hadChange = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, windowInsets ->
//此回调会触发多次,所以用布尔值来控制仅触发一次
if (!hadChange) {
hadChange = true
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
//状态栏高度
val statusBarHeight = insets.top
//调整顶部控件的高度
binding.topView.run {
updateLayoutParams<ConstraintLayout.LayoutParams> {
height += statusBarHeight
}
updatePadding(top = paddingTop + statusBarHeight)
}
binding.tvTitle.run {
updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin += statusBarHeight
}
}
//导航栏高度
val navigationBarHeight = insets.bottom
//调整圆点控件不被导航栏遮挡
binding.bottomView.run {
updateLayoutParams<ConstraintLayout.LayoutParams> {
bottomMargin += navigationBarHeight
}
}
}
WindowInsetsCompat.CONSUMED
}
...
}
...
}
効果は図のようになります。
フルスクリーンディスプレイ
フルスクリーン表示とは、ステータスバーとナビゲーションバーを非表示にすることを意味します。最新の公式APIは非常にシンプルです。
コードは次のように表示されます。
class FullScreenActivity : AppCompatActivity() {
lateinit var binding: LayoutFullScreenActivityBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.layout_full_screen_activity)
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
//控制系统栏的行为
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
}
}
注:systemBarsBehavior
ユーザーの動作を制御するために使用されるシステムバーへの変更には、次の3つのタイプがあります。
- WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_TOUCH
- WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE
- WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
BEHAVIOR_SHOW_BARS_BY_TOUCHとBEHAVIOR_SHOW_BARS_BY_SWIPEはどちらもタッチまたはスワイプで表示されるため、表示後にシステムバーが自動的に非表示になることはありません。効果は次のとおりです。
BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPEは、システムバーを表示するタッチまたはスライドとして表示され、短時間で自動的に非表示になります。効果は次のとおりです。