一、简介
Android 开发中,Activity 屏幕中存在状态栏、标题栏和导航栏,如下所示:
二、隐藏标题栏
1、通过代码隐藏
- 对于继承自 AppCompatActivity 的 Activty,可在 onCreate() 方法中调用supportRequestWindowFeature 或 getSupportActionBar 方法来隐藏标题栏。
- 采用 supportRequestWindowFeature 方法时,必须在调用 setContentView 方法之前调用。
- 采用 getSupportActionBar 方法时,没有位置限制。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 隐藏标题栏方法1,必须在 setContentView 方法之前调用
hideTitleBarBeforeSetContentView(this)
setContentView(R.layout.activity_second)
// 隐藏标题栏方法2, 调用位置没有限制
hideTitleBar(this)
}
/**
* 隐藏标题栏,必须在 setContentView 方法之前调用
*/
private fun hideTitleBarBeforeSetContentView(activity: AppCompatActivity) {
// 继承自 AppCompatActivity 的 activity
activity.supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
// 普通 activity
// activity.requestWindowFeature(Window.FEATURE_NO_TITLE)
}
/**
* 隐藏标题栏,调用位置没有限制
*/
private fun hideTitleBar(activity: AppCompatActivity) {
// 使用兼容库场景,在 API 7 及以上版本使用
activity.supportActionBar?.hide()
// API 11 及以上使用,并且没有使用兼容库
activity.actionBar?.hide()
}
2、通过主题隐藏
- 在 /res/values/themes.xml 中可自定义主题,并设置 windowFullscreen 字段为 true。
<style name="MyNoActionTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="android:windowFullscreen">true</item>
</style>
- 在 AndroidManifest.xml 文件中,为 <application> 标签或特定 <activity> 标签设置主题。
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/MyNoActionTheme"
tools:targetApi="31">
......
<activity android:name=".SecondActivity"
android:theme="@style/MyNoActionTheme"/>
三、隐藏状态栏
1、通过代码隐藏
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
hideNavigationBar(this)
}
/**
* 隐藏导航栏
*/
@Suppress("DEPRECATION")
private fun hideNavigationBar(activity: AppCompatActivity) {
// 隐藏屏幕底部的导航栏
LogUtils.d(TAG, "[hideNavigationBar] version: ${Build.VERSION.SDK_INT}")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
hideNavigationBarSinceApi29(activity)
} else {
hideNavigationBarSinceApi16(activity)
}
}
/**
* 隐藏状态栏和导航栏,Android 10(API 29) 及以上版本
*/
@RequiresApi(Build.VERSION_CODES.R)
private fun hideNavigationBarSinceApi29(activity: AppCompatActivity) {
activity.window?.insetsController?.let { controller ->
controller.hide(
WindowInsets.Type.navigationBars() or
WindowInsets.Type.statusBars()
)
controller.systemBarsBehavior =
WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
}
/**
* 隐藏导航栏,Android 4.1(API 16) 及以上版本
* 必须在 View 可见时调用才有效,建议在 onResume 中调用
*/
@Suppress("DEPRECATION")
private fun hideNavigationBarSinceApi16(activity: AppCompatActivity) {
val decorView: View = activity.window.decorView
val uiOptions: Int = View.SYSTEM_UI_FLAG_FULLSCREEN or
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
decorView.systemUiVisibility = uiOptions
}
2、通过主题隐藏
- 通过主题方式隐藏状态栏时,跟隐藏标题栏的方法一样。
四、隐藏导航栏
- 隐藏导航栏需要通过代码方式实现,实现方法跟隐藏状态栏的代码完全一样。
五、完整示例
1、res/values/themes.xml 中自定义主题
<style name="MyNoActionTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="android:windowFullscreen">true</item>
</style>
2、AndroidManifest.xml 中添加主题
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:name=".MyApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/MyNoActionTheme"
tools:targetApi="31" >
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
3、代码实现
package com.android.androidfunctiondemo
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.WindowInsets
import android.view.WindowInsetsController
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
class MainActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
hideNavigationBar(this)
}
/**
* 隐藏导航栏
*/
private fun hideNavigationBar(activity: AppCompatActivity) {
// 隐藏屏幕底部的导航栏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
hideNavigationBarSinceApi29(activity)
} else {
hideNavigationBarSinceApi16(activity)
}
}
/**
* 隐藏状态栏和导航栏,Android 10(API 29) 及以上版本
*/
@RequiresApi(Build.VERSION_CODES.R)
private fun hideNavigationBarSinceApi29(activity: AppCompatActivity) {
activity.window?.insetsController?.let { controller ->
controller.hide(
WindowInsets.Type.navigationBars() or
WindowInsets.Type.statusBars()
)
controller.systemBarsBehavior =
WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
}
/**
* 隐藏导航栏,Android 4.1(API 16) 及以上版本
* 必须在 View 可见时调用才有效,建议在 onResume 中调用
*/
@Suppress("DEPRECATION")
private fun hideNavigationBarSinceApi16(activity: AppCompatActivity) {
val decorView: View = activity.window.decorView
val uiOptions: Int = View.SYSTEM_UI_FLAG_FULLSCREEN or
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
decorView.systemUiVisibility = uiOptions
}
}