Respond to UI visibility changes
This lesson describes how to register a listener so that your app can get notified of system UI visibility changes. This is useful if you want to synchronize other parts of your UI with the hiding/showing of system bars.
Register a Listener
To get notified of system UI visibility changes, register an View.OnSystemUiVisibilityChangeListener
to your view. This is typically the view you are using to control the navigation visibility.
For example, you could add this code to your activity’s onCreate()
method:
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
// Note that system bars will only be "visible" if none of the
// LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
// TODO: The system bars are visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
} else {
// TODO: The system bars are NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
}
}
});
It’s generally good practice to keep your UI in sync with changes in system bar visibility. For example, you could use this listener to hide and show the action bar in concert with the status bar hiding and showing.
准备
IDE:
Android Studio 4.1.1
Build #AI-201.8743.12.41.6953283, built on November 5, 2020
Runtime version: 1.8.0_242-release-1644-b01 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
Android Virtual Devices:
Name: Pixel_2_API_28
CPU/ABI: Google Play Intel Atom (x86)
Path: C:\Users\86188\.android\avd\Pixel_2_API_28.avd
Target: google_apis_playstore [Google Play] (API level 28)
Skin: pixel_2
SD Card: 512M
fastboot.chosenSnapshotFile:
runtime.network.speed: full
hw.accelerometer: yes
hw.device.name: pixel_2
hw.lcd.width: 1080
hw.initialOrientation: Portrait
image.androidVersion.api: 28
tag.id: google_apis_playstore
hw.mainKeys: no
hw.camera.front: emulated
avd.ini.displayname: Pixel 2 API 28
hw.gpu.mode: auto
hw.ramSize: 1536
PlayStore.enabled: true
fastboot.forceColdBoot: no
hw.cpu.ncore: 4
hw.keyboard: yes
hw.sensors.proximity: yes
hw.dPad: no
hw.lcd.height: 1920
vm.heapSize: 256
skin.dynamic: yes
hw.device.manufacturer: Google
hw.gps: yes
hw.audioInput: yes
image.sysdir.1: system-images\android-28\google_apis_playstore\x86\
showDeviceFrame: yes
hw.camera.back: virtualscene
AvdId: Pixel_2_API_28
hw.lcd.density: 420
hw.arc: false
hw.device.hash2: MD5:55acbc835978f326788ed66a5cd4c9a7
fastboot.forceChosenSnapshotBoot: no
fastboot.forceFastBoot: yes
hw.trackBall: no
hw.battery: yes
hw.sdCard: yes
tag.display: Google Play
runtime.network.latency: none
disk.dataPartition.size: 6442450944
hw.sensors.orientation: yes
avd.ini.encoding: UTF-8
hw.gpu.enabled: yes
注意:以下示例仅在安卓虚拟设备上运行测试,并没有在真实的设备上运行测试。
项目
效果:
新建项目,选择 Empty Activity,在配置项目时,Minimum SDK
选择 API 16: Android 4.1 (Jelly Bean)
编辑 src\main\res\layout\activity_main.xml
布局文件,添加一个 Button
组件:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/buttonImmersive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="Immersive"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
编辑 MainActivity
文件:
package com.mk;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
// Note that system bars will only be "visible" if none of the
// LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set.
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
// The system bars are visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
Toast.makeText(MainActivity.this, "Visible", Toast.LENGTH_LONG).show();
} else {
// The system bars are NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
Toast.makeText(MainActivity.this, "Invisible", Toast.LENGTH_LONG).show();
}
}
});
((Button) findViewById(R.id.buttonImmersive)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
immersive();
}
});
}
private void immersive() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
);
}
}