Android.隐藏导航栏有时会失败

dfddblmv  于 2023-01-07  发布在  Android
关注(0)|答案(2)|浏览(319)

下面的代码用于在用户每次点击屏幕时切换导航栏的可见性。除了一个场景外,它工作正常--非常快地点击屏幕。在某些情况下,当用户点击非常快时,导航栏会停留在屏幕上,尽管触发了onClick事件。
下面是主活动的代码:

package com.example.ui_test;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RelativeLayout;

public class MainActivity extends Activity {

private final String DEBUG_TAG = "UI TEST";
int uiOptions = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RelativeLayout r = (RelativeLayout) findViewById(R.id.main_layout);
    r.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            toggleUiVisibility();
        }
    });

    View decorView = getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
        @Override
        public void onSystemUiVisibilityChange(int visibility) {
            Log.d(DEBUG_TAG, "Visibility changed. New flags: " + Integer.toString(visibility, 2));
            uiOptions = visibility;
        }
    });
}

protected void toggleUiVisibility() {
    uiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;        
    getWindow().getDecorView().setSystemUiVisibility(uiOptions);
    Log.d(DEBUG_TAG, "Set visibility to: " + Integer.toString(uiOptions, 2));
};

}
我尝试了不同的布局(无视图、TextView、全屏ImageView),行为无差异。这是LogCat输出,请查看第6行。setSystemUiVisibility()调用后未记录onSystemUiVisibilityChange事件:

09-21 18:24:19.871: D/UI TEST(3901): Visibility changed. New flags: 0
09-21 18:24:21.139: D/UI TEST(3901): Set visibility to: 10
09-21 18:24:21.171: D/UI TEST(3901): Visibility changed. New flags: 10
09-21 18:24:23.478: D/UI TEST(3901): Visibility changed. New flags: 0
09-21 18:24:24.321: D/UI TEST(3901): Set visibility to: 10
09-21 18:24:25.245: D/UI TEST(3901): Set visibility to: 0
09-21 18:24:25.927: D/UI TEST(3901): Set visibility to: 10
09-21 18:24:25.959: D/UI TEST(3901): Visibility changed. New flags: 10
09-21 18:24:33.625: D/UI TEST(3901): Visibility changed. New flags: 0
09-21 18:24:35.458: D/UI TEST(3901): Set visibility to: 10
09-21 18:24:35.490: D/UI TEST(3901): Visibility changed. New flags: 10
09-21 18:24:36.607: D/UI TEST(3901): Visibility changed. New flags: 0
09-21 18:24:38.294: D/UI TEST(3901): Set visibility to: 10
09-21 18:24:38.326: D/UI TEST(3901): Visibility changed. New flags: 10

我使用的Android 5.1.1设备和22目标/最低API级别.

tv6aics1

tv6aics11#

好吧,事实证明这是一个功能,而不是一个bug。问题是setSystemUiVisibility连续呼叫之间的间隔,而不是屏幕上的快速点击。我不得不挖掘Android源代码,我发现了这个:

...

// We don't allow the system's nav bar to be hidden
// again for 1 second, to prevent applications from
// spamming us and keeping it from being shown.
 newVal = mForceClearedSystemUiFlags |
          View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
 if (mForceClearedSystemUiFlags != newVal) {
     mForceClearedSystemUiFlags = newVal;
     changed = true;
     mHandler.postDelayed(mClearHideNavigationFlag, 1000);
 }

...

这是PhoneWindowManager.java中的HideNavInputEventReceiver。我也在Xperia Z2上的相册应用程序中重现了这个“bug”。

3mpgtkmj

3mpgtkmj2#

在我的情况下,活动可能开始晚了,那么导航栏可能没有隐藏。作为解决方案:
创建时:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    }

关于恢复:

@Override
    protected void onResume() {
        super.onResume();
        Handler handler = new Handler();
        handler.postDelayed(this::hideSystemUI, 1000);
    }

隐藏系统用户界面:

private void hideSystemUI() {
        View mDecorView = getWindow().getDecorView();
        mDecorView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }

注意:此方法还会隐藏ActionBar。如果要显示它,请将ActionBar内容添加到Activity布局中。

相关问题