44

Is it possible to permanently remove the Navigation Bar on an activity? I want to remove the bar with the buttons that appear at the button of the screen on a tablet, not the Action Bar. Here.

I know it is not recommended to do that, I did not make this decision, but I need to do it. On my layout, there is another button to leave the activity. The rest of my app can have and does have the Navigation Bar.

I found this code and adapted it a little bit. The problem is that even when I hide the Navigation Bar, there is a black space left behind. I guess the system calculates the screen size having into account the navigation bar?

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);
    }

}
Daniel
  • 2,355
  • 9
  • 23
  • 30
steve_patrick
  • 735
  • 2
  • 9
  • 19
  • How you are using this code? – Shajeel Afzal Aug 26 '15 at 16:55
  • @steve I have a problem, My activity root layout is RelativeLayout, and it has a child view that is set android:layout_alignParentBottom="true", the navigation bar disappear but the child view doesn't move to bottom edge of the screen, as if the navigation bar is set to invisible not gone, could you help? – Jack Oct 21 '18 at 20:31

9 Answers9

70

There is a solution starting with KitKat (4.4.2), called Immersive Mode: https://developer.android.com/training/system-ui/immersive.html

Basically, you should add this code to your onResume() method:

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);
Denim Datta
  • 3,740
  • 3
  • 27
  • 53
radu122
  • 2,865
  • 24
  • 24
  • 4
    @radu122 Thank you, but I have a problem, My activity root layout is RelativeLayout, and it has a child view that is set android:layout_alignParentBottom="true", the navigation bar disappear but the child view doesn't move to bottom edge of the screen, as if the navigation bar is set to invisible not gone, could you help? – Jack Oct 21 '18 at 20:30
26

You can

There are Two ways (both requiring device root) :

1- First way, open the device in adb window command, and then run the following:

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

and to get it back just do the same but change disable to enable.

2- second way, add the following line to the end of your device's build.prop file :

qemu.hw.mainkeys = 1

then to get it back just remove it.

and if you don't know how to edit build.prop file:

  • download EsExplorer on your device and search for build.prop then change it's permissions to read and write, finally add the line.
  • download a specialized build.prop editor app like build.propEditor.
  • or refer to that link.
Dakkaron
  • 5,930
  • 2
  • 36
  • 51
Muhammed Refaat
  • 8,914
  • 14
  • 83
  • 118
16

You can hide navigation bar, just call this method on your 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);
    }
}

This will hide whole nagiation panel.hope it helps you

Nick
  • 2,593
  • 3
  • 30
  • 59
Evish Verma
  • 1,037
  • 9
  • 4
  • 1
    Hi, anyway to hide the buttons after a input focus in a webview that shows up the keyword? – Patrick Sep 23 '15 at 17:04
  • Typo ? comment should say // for Higher APIs – user1010160 Sep 24 '16 at 03:32
  • 1
    @Evish Thank you, but I have a problem, My activity root layout is RelativeLayout, and it has a child view that is set android:layout_alignParentBottom="true", the navigation bar disappear but the child view doesn't move to bottom edge of the screen, as if the navigation bar is set to invisible not gone, could you help? I'm testing on Android 8.0 device – Jack Oct 21 '18 at 20:33
9

After watching the DevBytes video (by Roman Nurik) and reading the very last line in the docs, which says:

Note: If you like the auto-hiding behavior of IMMERSIVE_STICKY but need to show your own UI controls as well, just use IMMERSIVE combined with Handler.postDelayed() or something similar to re-enter immersive mode after a few seconds.

the answer, radu122 gave, worked for me. Just setup a handler and your will be good to go.

Here is the code which works for me:

@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 says "after a few seconds" - but I want to provide this functionality as soon as possible. Maybe I will change the value later, if I have to, I will update this answer.

Martin Pfeffer
  • 12,471
  • 9
  • 59
  • 68
  • 2
    Well this is the most horrible way to do, but google advised to use in a such way.. Really they can't provide a good way to do this? What an idiocracy – Android Developer Jan 20 '18 at 21:15
  • I am with you. Maybe the platform provides a better solution right now. – Martin Pfeffer Jan 20 '18 at 21:24
  • I am afraid no...I am currently trying to find but no way...just Google sucks big time at giving really helpful apis – Android Developer Jan 20 '18 at 22:18
  • Hmm, imho the platform is quite nice and very well documented. But some features are hard and/or ugly to implement, you're right. – Martin Pfeffer Jan 20 '18 at 22:22
  • @MartinPfeffer Thank you, but I have a problem, My activity root layout is RelativeLayout, and it has a child view that is set android:layout_alignParentBottom="true", the navigation bar disappear but the child view doesn't move to bottom edge of the screen, as if the navigation bar is set to invisible not gone, could you help? – Jack Oct 21 '18 at 20:35
  • As long as there will not be documented APIs to simply do that, these kind of workarounds do work! If you want to achieve that without root, this is one of the way to go. This is a very and clever answer to the question! It simply works. – 1111161171159459134 Nov 19 '19 at 02:47
5

Change the theme in your manifest.

If you want to hide nav bar for one activity you can use this:

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

If you want to hide nav bar for entire application you can use this:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Black.NoTitleBar" >
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
android_dev
  • 1,477
  • 12
  • 18
  • 3
    I would like to remove the navigation bar, not the action bar. I want to hide the buttons that appear at the bottom of the screen for tablets. – steve_patrick May 23 '13 at 13:24
  • 1
    hi steve, there are some reading incomprehension problems with these answers. everyone wants you to remove the action bar. LOL. did you ever figure it out for 4.0 and above? thanks – steveh Jul 03 '14 at 00:00
5

AFAIK, this is not possible without root access. It would be a security issue to be able to have an app that cannot be exited with system buttons.

Edit, see here: Hide System Bar in Tablets

Community
  • 1
  • 1
stevis
  • 425
  • 1
  • 4
  • 9
4

My solution, to only hide the navigation bar, is:

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);
}
mrmcmeg
  • 51
  • 5
2

Start by hiding in OnResume() of the activity then also keep hiding as shown below:

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);
    }
Prafulla Kumar Sahu
  • 9,321
  • 11
  • 68
  • 105
0

From Google documentation:

You can hide the navigation bar on Android 4.0 and higher using the SYSTEM_UI_FLAG_HIDE_NAVIGATION flag. This snippet hides both the navigation bar and the status bar:

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

nemcaninz
  • 96
  • 1
  • 8