问题描述
Android R + Pixel 4模拟器:当我隐藏状态栏时,主视图向下移动,黑色正方形(与状态栏大小相同)出现在顶部。 它在Android 11之前运行。 看起来很简单,但我找不到解决方案...而且我需要全屏模式。
我尝试使用SYstem_UI_FLAG_FULLSCREEN(现已弃用)和controller.hide(WindowInsets.Type.statusBars()); 两种方式有相同的问题。
这是主要代码: MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonShow = findViewById(R.id.b1);
buttonShow.setonClickListener(new View.OnClickListener() {
public void onClick(View v) {
showBars();
}
});
Button buttonHide = findViewById(R.id.b2);
buttonHide.setonClickListener(new View.OnClickListener() {
public void onClick(View v) {
hideBars();
}
});
showBars();
}
public void showBars(){
View decorView = getwindow().getDecorView();
int uiOptions = View.SYstem_UI_FLAG_LAYOUT_STABLE
| View.SYstem_UI_FLAG_LAYOUT_FULLSCREEN;
decorView.setsystemUIVisibility(uiOptions);
getwindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
getwindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// New code For Android 11,same effect...
/*
WindowInsetsController controller = getwindow().getInsetsController();
if(controller != null) {
controller.show(WindowInsets.Type.navigationBars());
controller.show(WindowInsets.Type.statusBars());
controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}*/
}
public void hideBars(){
View decorView = getwindow().getDecorView();
int uiOptions = View.SYstem_UI_FLAG_LAYOUT_STABLE
| View.SYstem_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYstem_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYstem_UI_FLAG_HIDE_NAVIGATION
| View.SYstem_UI_FLAG_FULLSCREEN
| View.SYstem_UI_FLAG_IMMERSIVE;
decorView.setsystemUIVisibility(uiOptions);
getwindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
getwindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// New code For Android 11,same effect...
/* WindowInsetsController controller = getwindow().getInsetsController();
if(controller != null) {
controller.hide(WindowInsets.Type.navigationBars());
controller.hide(WindowInsets.Type.statusBars());
controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}*/
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:background="@color/purple_200"
android:id="@+id/layoutMain">
<Button
android:id="@+id/b1"
android:layout_marginTop="200dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="show" />
<Button
android:id="@+id/b2"
android:layout_marginTop="100dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hide"
/>
</RelativeLayout>
解决方法
试试这个代码片段。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
}
,
我遇到了同样的问题,全屏试试这个:
fun makeActivityFullScreen(activity: Activity) {
//set full screen
activity.window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN)
activity.window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
activity.window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val attributes = activity.window.attributes
attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
activity.window.setDecorFitsSystemWindows(true)
} else {
hideSystemUI(activity)
}
}
private fun hideSystemUI(activity: Activity) {
activity.window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
// Hide the nav bar and status bar
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN)
}
这是回到正常模式:
fun makeActivityNormalScreen(activity: Activity) {
//set normal screen
activity.window.setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN)
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val attributes = activity.window.attributes
attributes.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
activity.window.setDecorFitsSystemWindows(false)
} else {
// Show the system bar
showSystemUI(activity)
}
}
private fun showSystemUI(activity: Activity) {
activity.window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_VISIBLE)
}
,
这对我有用:
使用 v27 配置为您想要的活动创建一个样式资源文件,用于全屏且无剪切:
<style name="Theme.MyApp.ActivityFullscreenNoCutout">
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
并在清单中为您的活动分配样式:
<activity android:name=".MyActivity"
android:theme="@style/Theme.MyApp.ActivityFullscreenNoCutout"/>
链接:https://developer.android.com/guide/topics/display-cutout
如果您有操作栏/应用栏,则必须将工具栏添加到您的活动中,而不是使用默认工具栏。
链接:https://developer.android.com/training/appbar/setting-up
,活动代码中的某处...
@TargetApi(Build.VERSION_CODES.R)
void hideStatusBar_with_API30() {
View decorView = getWindow().getDecorView();
// Order swiped status bar to appear semitransparent.
// If you do not that
// then once appeared bar will not disappear after nor few seconds nor you gesture.
decorView.getWindowInsetsController().setSystemBarsBehavior(
WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
// Hide the status bar.
decorView.getWindowInsetsController().hide(WindowInsets.Type.statusBars());
// The status bar is allowed to appear with a swipe gesture.
// When it is then app layout is resized.
// To prevent changing the layout,you need to add:
getWindow().setDecorFitsSystemWindows(false);
// The status bar will appear over stable layout
}