I am trying to hide the Bottom navigation bar only and not the status bar. Most of the code I am getting is hiding both the navigation bar and the status bar.
Try the below function. Owing to changes in Android R, View.SYSTEM_UI_FLAG_HIDE_NAVIGATION, setSystemUiVisibility etc are being deprecated. I have made the function to handle this scenario.
public void hideBottomNavigationBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
getWindow().setDecorFitsSystemWindows(false);
WindowInsetsController controller = getWindow().getInsetsController();
if(controller != null) {
controller.hide(WindowInsets.Type.navigationBars());
controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}
} else {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
}
Another thing to note about using View.SYSTEM_UI_FLAG_HIDE_NAVIGATION from the docs:
There is a limitation: because navigation controls are so important, the least user interaction will cause them to reappear immediately. When this happens, both this flag and SYSTEM_UI_FLAG_FULLSCREEN will be cleared automatically, so that both elements reappear at the same time.
Inorder to work around this limitation you can set View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY as well like this:
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
But this only works SDK 19 onwards.
View v = getWindow().getDecorView();
int options = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN;
v.setSystemUiVisibility(options);
Related
I call this function in onCreate of every activity of my app project:
public void hideDeviceBottomNav ()
{
View decorView = getWindow().getDecorView();
final int flags =
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;
decorView.setSystemUiVisibility(flags);
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.
decorView.setSystemUiVisibility(flags);
} 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.
}
}
});
}
and still every time I touch the search icon in my SearchView to search in my ListView or create and show new custom Dialog, the bottom navigation bar appears... .
In addition, how can I hide the bottom navigation only without hiding the upper bar ?
Thank you in advance!
I decided to implement a Snackbar with this method (which will later be called in onClick method):
public void showSnackbar(int selector, int textSelector){
String sOne = (String) getResources().getText(R.string.charPart1);
String sTwo = String.valueOf(selector);
String sThree = (String) getResources().getText(R.string.charPart2);
String sFour = sOne.concat(sTwo.concat(sThree));
String sFive = (String) getResources().getText(R.string.charPart4);
String sSix = sFour.concat(sFive);
Snackbar notification = Snackbar.make(getWindow().getDecorView().getRootView(), "PLACEHOLDER", Snackbar.LENGTH_SHORT);
if (textSelector==1){
notification.setText(sFour);
notification.show();
}
else if (textSelector==2){
notification.setText(sSix);
notification.show();
}
}
I am facing this problem:
The Snackbar is displayed behind the system navigation bar:
My first idea was, that i could use the method Snackbar.setAnchorView(View anchorView) to position the Snackbar above the system navigation bar / soft navigation bar. Description of setAnchorView(View anchorView):
By default, Snackbars will be anchored to the bottom edge of their parent view. However, you can use the setAnchorView method to make a Snackbar appear above a specific view within your layout, e.g. a FloatingActionButton. This is especially helpful if you would like to place a Snackbar above navigational elements at the bottom of the screen, such as a BottomAppBar or BottomNavigationView.
I would like to position the Snackbar above the system navigation bar, but i donĀ“t know how to query the view id of the system navigation bar.
Snackbar notification = Snackbar.make(getWindow().getDecorView().getRootView(), "PLACEHOLDER", Snackbar.LENGTH_SHORT);
// View systemNavigationView = findViewById(int id) ;
notification.setAnchorView(systemNavigationView);
notification.show();
Is it at all possible to assume that the android system navigation bar has an assigned id that can be retrieved?
I only found this method for detecting if it exists, but no approach for getting the View or the id of the view:
public boolean hasNavBar (Resources resources)
{
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
return id > 0 && resources.getBoolean(id);
}
You should place your snackbar inside a CoordinatorLayout view.
I have an app that should be full screen most of the time. However, I want users to be able to easily go back when using the keyboard. How can I make the navigation bar visible only when the keyboard is open? When the keyboard is turned off, the navigation bar should disappear again.
I added this library to my project. So I was able to type what to do when the keyboard is open:
implementation 'com.github.ravindu1024:android-keyboardlistener:1.0.0'
Then I created two values, one to show and one to hide:
private int showSystemBars() {
return SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
SYSTEM_UI_FLAG_LAYOUT_STABLE;
}
private int hideSystemBars() {
return SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
Then I used the library I added:
KeyboardUtils.addKeyboardToggleListener(this, isVisible -> {
if (isVisible) {
Toast.makeText(context, "Visible", Toast.LENGTH_SHORT).show();
getWindow().getDecorView().setSystemUiVisibility(showSystemBars());
}else {
Toast.makeText(context, "Invisible", Toast.LENGTH_SHORT).show();
getWindow().getDecorView().setSystemUiVisibility(hideSystemBars());
}
});
This question specific to the issue with Xiomi devices with MIUI over it.
How can I detect Fullscreen Mode (Gesture) or Navigation Button (soft navigation) is selected?
I Have tried a few solutions, but that does work on other devices but didn't work on Xiomi or MIUI.
I have tried this solution available on SO, so please provide another if you have.
1
public boolean hasNavBar (Resources resources)
{
int id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
return id > 0 && resources.getBoolean(id);
}
2
boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
if (hasBackKey && hasHomeKey) {
// no navigation bar, unless it is enabled in the settings
} else {
// 99% sure there's a navigation bar
}
3
View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener
(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
// TODO: The navigation bar is visible. Make any desired
// adjustments to your UI, such as showing the action bar or
// other navigational controls.
} else {
// TODO: The navigation bar is NOT visible. Make any desired
// adjustments to your UI, such as hiding the action bar or
// other navigational controls.
}
}
});
Any idea of how can I get to know that the navigation bar is currently visible or not?
I also tried to calculate the real width and available width, it seems like MIUI always returning the reserved with of navigation bar.
Thanks.
There is no need to detect if Soft input navigation bar is visible or hidden for full screen activity you can create style and apply style to activity.
<style name="Theme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowDrawsSystemBarBackgrounds" tools:targetApi="lollipop">false</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
and add following line in activity :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
This is led you to stop the layout overlap from soft input navigation.
I have the same problem too. I found 2 solution:
This solution works for me for versions above Android Q.
public static int isEdgeToEdgeEnabled(Context context) {
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("config_navBarInteractionMode", "integer", "android");
if (resourceId > 0) {
return resources.getInteger(resourceId);
}
return 0;
}
If this method returns 2 then Full screen mode is enabled.
2.This solution works for me above Android Q and below it:
ViewCompat.setOnApplyWindowInsetsListener(
findViewById(android.R.id.content)
) { _: View?, insets: WindowInsetsCompat ->
navigationBarHeight = insets.systemWindowInsetBottom
insets
}
I used 2 method myself
My app runs in fullscreen (immersive mode).
The status bar is hidden at the top.
On some Samsung phones, there is a stylus pen. If the pen is removed, the status bar re-appears and won't go away.
I tried adding a listener for this event but it doesn't get called.
View decorView = getActivity().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.
System.out.print("Change event");
} 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.
System.out.print("Change event");
}
}
});
Do you know how I can know if the status bar has re-appeared?
In my activity I do this to get it re-hide the status bar:
#Override
public void onWindowFocusChanged(boolean hasFocus)
{
System.out.println("Gotcha");
super.onWindowFocusChanged(hasFocus);
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run() {
System.out.println("Hiding");
_root.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}, 6000);
}