在活动中永久隐藏导航栏

Posted

技术标签:

【中文标题】在活动中永久隐藏导航栏【英文标题】:Permanently hide Navigation Bar in an activity 【发布时间】:2013-05-18 19:23:37 【问题描述】:

是否可以永久删除活动上的导航栏?我想删除显示在平板电脑屏幕按钮上的按钮栏,而不是操作栏。 Here.

我知道不建议这样做,我没有做出这个决定,但我需要这样做。在我的布局上,还有另一个按钮可以离开活动。我的应用程序的其余部分可以具有并且确实具有导航栏。

我找到了这段代码并对其进行了一些调整。问题是即使我隐藏了导航栏,也会留下一个黑色空间。我猜系统在计算屏幕尺寸时会考虑导航栏?

public static class Content extends ImageView implements View.OnSystemUiVisibilityChangeListener, View.OnClickListener, ActionBar.OnMenuVisibilityListener 
    Activity mActivity;
    TextView mTitleView;
    Button mPlayButton;
    SeekBar mSeekView;
    boolean mAddedMenuListener;
    boolean mMenusOpen;
    boolean mPaused;
    boolean mNavVisible;
    int mLastSystemUiVis;

    Runnable mNavHider = new Runnable() 
        @Override public void run() 
            setNavVisibility(false);
        
    ;

    public Content(Context context, AttributeSet attrs) 
        super(context, attrs);
        setOnSystemUiVisibilityChangeListener(this);
        setOnClickListener(this);
    

    public void init(Activity activity, TextView title, Button playButton,
            SeekBar seek) 
        // This called by the containing activity to supply the surrounding
        // state of the video player that it will interact with.
        mActivity = activity;
        mTitleView = title;
        mPlayButton = playButton;
        mSeekView = seek;
        mPlayButton.setOnClickListener(this);
        setPlayPaused(true);
    

    @Override protected void onAttachedToWindow() 
        super.onAttachedToWindow();
        if (mActivity != null) 
            mAddedMenuListener = true;
            mActivity.getActionBar().addOnMenuVisibilityListener(this);
        
    

    @Override protected void onDetachedFromWindow() 
        super.onDetachedFromWindow();
        if (mAddedMenuListener) 
            mActivity.getActionBar().removeOnMenuVisibilityListener(this);
        
    

    @Override public void onSystemUiVisibilityChange(int visibility) 
        // Detect when we go out of nav-hidden mode, to clear our state
        // back to having the full UI chrome up.  Only do this when
        // the state is changing and nav is no longer hidden.
        int diff = mLastSystemUiVis ^ visibility;
        mLastSystemUiVis = visibility;
        if ((diff&SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
                && (visibility&SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) 
            setNavVisibility(true);
        
    

    @Override protected void onWindowVisibilityChanged(int visibility) 
        super.onWindowVisibilityChanged(visibility);

        // When we become visible or invisible, play is paused.
        setPlayPaused(true);
    

    @Override public void onClick(View v) 
        if (v == mPlayButton) 
            // Clicking on the play/pause button toggles its state.
            setPlayPaused(!mPaused);
         else 
            // Clicking elsewhere makes the navigation visible.
            setNavVisibility(true);
        
    

    @Override public void onMenuVisibilityChanged(boolean isVisible) 
        mMenusOpen = isVisible;
        setNavVisibility(true);
    

    void setPlayPaused(boolean paused) 
        mPaused = paused;
        mPlayButton.setText(paused ? R.string.play : R.string.pause);
        setKeepScreenOn(!paused);
        setNavVisibility(true);
    

    void setNavVisibility(boolean visible) 
        int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | SYSTEM_UI_FLAG_LAYOUT_STABLE;
        if (!visible) 
            newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN
                    | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
        

        // If we are now visible, schedule a timer for us to go invisible.
        if (visible) 
            Handler h = getHandler();
            if (h != null) 
                h.removeCallbacks(mNavHider);
                if (!mMenusOpen && !mPaused) 
                    // If the menus are open or play is paused, we will not auto-hide.
                    h.postDelayed(mNavHider, 1500);
                
            
        

        // Set the new desired visibility.
        setSystemUiVisibility(newVis);
        mTitleView.setVisibility(visible ? VISIBLE : INVISIBLE);
        mPlayButton.setVisibility(visible ? VISIBLE : INVISIBLE);
        mSeekView.setVisibility(visible ? VISIBLE : INVISIBLE);
    


【问题讨论】:

你是如何使用这段代码的? @steve 我有一个问题,我的活动根布局是RelativeLayout,它有一个设置为android:layout_alignParentBottom="true"的子视图,导航栏消失但子视图没有移动到屏幕的底部边缘,好像导航栏设置为不可见没有消失,你能帮忙吗? 【参考方案1】:

有一个从 KitKat (4.4.2) 开始的解决方案,称为沉浸式模式:https://developer.android.com/training/system-ui/immersive.html

基本上,您应该将此代码添加到您的 onResume() 方法中:

View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(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_STICKY);

【讨论】:

@radu122 谢谢,但我有一个问题,我的活动根布局是RelativeLayout,它有一个设置为android:layout_alignParentBottom="true"的子视图,导航栏消失但孩子视图没有移动到屏幕的底部边缘,好像导航栏设置为不可见没有消失,你能帮忙吗?【参考方案2】:

你可以

两种方式(都需要设备root):

1-第一种方法,在adb window command中打开设备,然后运行如下:

 adb shell >
 pm disable-user --user 0 com.android.systemui >

要取回它,只需执行相同操作,但将 disable 更改为 enable

2- 第二种方式,将以下行添加到您设备的 build.prop 文件的末尾:

qemu.hw.mainkeys = 1

然后要取回它,只需将其删除。

如果您不知道如何编辑 build.prop 文件:

在您的设备上下载EsExplorer并搜索build.prop,然后更改它的读写权限,最后添加该行。 下载专门的 build.prop 编辑器应用,例如 build.propEditor。 或参考that link。

【讨论】:

你知道 com.android.systemui 有哪些功能吗? @JohnyTex 是的,它是安全的,因为它只处理 UI 而不是系统核心,关于软导航按钮,它们甚至根本不存在,因为它们主要存在于导航栏中跨度> 这应该是选择的答案,我稍后会为这个答案添加更多可用性 @meditat 是的,没错,都需要root,我会相应地编辑我的答案 我已经删除了我之前的评论。方法 1 适用于 Polestar 2 模拟器,我不得不重新启动模拟器。【参考方案3】:

你可以隐藏导航栏,只要在你的onCreate()上调用这个方法,

 public void FullScreencall() 
    if(Build.VERSION.SDK_INT < 19) 
        View v = this.getWindow().getDecorView();
        v.setSystemUiVisibility(View.GONE);
     else 
            //for higher api versions.    
        View decorView = getWindow().getDecorView(); 
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        decorView.setSystemUiVisibility(uiOptions);
    

这将隐藏整个导航面板。希望它可以帮助你

【讨论】:

嗨,无论如何要在显示关键字的 web 视图中输入焦点后隐藏按钮? 错字?评论应该说 // 对于高级 APIs @Evish 谢谢,但我有一个问题,我的活动根布局是RelativeLayout,它有一个设置为android:layout_alignParentBottom="true" 的子视图,导航栏消失但孩子视图没有移动到屏幕的底部边缘,好像导航栏设置为不可见没有消失,你能帮忙吗?我正在 Android 8.0 设备上进行测试【参考方案4】:

在观看了 DevBytes video(由 Roman Nurik 撰写)并阅读了文档中的最后一行之后:

注意:如果您喜欢 IMMERSIVE_STICKY 的自动隐藏行为,但也需要显示自己的 UI 控件,只需使用 IMMERSIVE 结合 Handler.postDelayed() 或类似的东西几秒钟后重新进入沉浸式模式。

radu122 给出的答案对我有用。只需设置一个处理程序,您就可以开始了。

这是对我有用的代码:

@Override
protected void onResume() 
    super.onResume();
    executeDelayed();



private void executeDelayed() 
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() 
        @Override
        public void run() 
            // execute after 500ms
            hideNavBar();
        
    , 500);



private void hideNavBar() 
    if (Build.VERSION.SDK_INT >= 19) 
        View v = getWindow().getDecorView();
        v.setSystemUiVisibility(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_STICKY);
    

Google 说“几秒钟后” - 但我想尽快提供此功能。也许我稍后会更改该值,如果必须,我会更新此答案。

【讨论】:

嗯,这是最可怕的做法,但谷歌建议以这种方式使用.. 真的他们不能提供这样做的好方法吗?多么白痴 我和你在一起。也许该平台现在提供了更好的解决方案。 恐怕没有...我目前正在尝试寻找但没有办法...只是 Google 在提供真正有用的 api 方面浪费了很多时间 嗯,恕我直言,这个平台非常好,而且有据可查。但是有些功能很难实现和/或很难实现,你是对的。 @MartinPfeffer 谢谢,但我有一个问题,我的活动根布局是RelativeLayout,它有一个设置为android:layout_alignParentBottom="true"的子视图,导航栏消失但孩子视图没有移动到屏幕的底部边缘,好像导航栏设置为不可见没有消失,你能帮忙吗?【参考方案5】:

AFAIK,如果没有 root 访问权限,这是不可能的。能够拥有无法通过系统按钮退出的应用程序将是一个安全问题。

编辑,见这里:Hide System Bar in Tablets

【讨论】:

【参考方案6】:

更改清单中的主题。

如果你想隐藏一个活动的导航栏,你可以使用这个:

<activity
        android:name="Activity Name"
        android:theme="@android:style/Theme.Black.NoTitleBar"
        android:label="@string/app_name" >

如果你想隐藏整个应用程序的导航栏,你可以使用这个:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Black.NoTitleBar" >

【讨论】:

我想删除导航栏,而不是操作栏。我想隐藏出现在平板电脑屏幕底部的按钮。 嗨史蒂夫,这些答案存在一些阅读理解问题。每个人都希望您删除操作栏。哈哈。你有没有想过 4.0 及更高版本?谢谢【参考方案7】:

我的解决方案,只隐藏导航栏,是:

protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

    final View decorView = getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener (new View.OnSystemUiVisibilityChangeListener() 
        @Override
        public void onSystemUiVisibilityChange(int visibility) 
            if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) 
                decorView.setSystemUiVisibility(
                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
            
        
    );


@Override
protected void onResume() 
    super.onResume();
    final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
    final View decorView = getWindow().getDecorView();
    decorView.setSystemUiVisibility(uiOptions);

【讨论】:

你从哪里得到getWindow()?最后它说:**无法读取符号getWindow()。** 如果来自片段,请尝试getActivity().getWindow()【参考方案8】:

首先隐藏在活动的 OnResume() 中,然后继续隐藏,如下所示:

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) 
                            //visible
                            hideSystemUI();
                         
                    
                    
                );`

    public void hideSystemUI() 
        // Set the IMMERSIVE flag.
        // Set the content to appear under the system bars so that the content
        // doesn't resize when the system bars hide and show.
        decorView.setSystemUiVisibility(
                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 // hide nav bar
                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                        | View.SYSTEM_UI_FLAG_IMMERSIVE);
    

【讨论】:

【参考方案9】:

来自谷歌文档:

您可以在 Android 4.0 及更高版本上使用 SYSTEM_UI_FLAG_HIDE_NAVIGATION 标志隐藏导航栏。 这个 sn -p 隐藏了导航栏和状态栏:

View decorView = getWindow().getDecorView();
// Hide both the navigation bar and the status bar.
// SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as
// a general rule, you should design your app to hide the status bar whenever you
// hide the navigation bar.
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
              | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);

http://developer.android.com/training/system-ui/navigation.html

【讨论】:

以上是关于在活动中永久隐藏导航栏的主要内容,如果未能解决你的问题,请参考以下文章

UINavigationContoller interactivePopGestureRecognizer 在导航栏隐藏时不活动

Android导航栏隐藏与浮现(二)

Electron菜单栏&导航栏隐藏

呈现一个模态视图控制器,但不要隐藏导航栏

vue中导航栏的显示和隐藏

Android 显示、隐藏状态栏和导航栏