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);
}
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 ?
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());
}
});
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);
I want to turn off keys(home, back, recent apps) lights on the activity. Here is my code.
Settings.System.putInt(getApplicationContext().getContentResolver(), "button_key_light", 0);
It works well on Samsung phone, but it doesn't work on other devices such as Google Pixel 2.
Please help me.
You can try this-:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
Log.d("Test", "Back button pressed!");
}
else if(keyCode == KeyEvent.KEYCODE_HOME)
{
Log.d("Test", "Home button pressed!");
}
return super.onKeyDown(keyCode, event);
}
I have solved this problem by using Immersive Full-Screen Mode.
https://github.com/superdev0714/DisableHome.java/blob/master/DisableHome.java
I solved myself. It works well.
private void disableHomebutton() {
final 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 // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE;
mainView.setSystemUiVisibility(uiOptions);
mainView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int visibility) {
mainView.setSystemUiVisibility(uiOptions);
}
});
mHomeKeyLocker.lock(this);
}
I've read up on a lot of questions about immersive sticky mode on Android, but I cannot find a specific answer for my question.
I have read onBackPressed function not working under IMMERSIVE STICKY mode, but my app goes back successfully when an ImageButton is pressed.
I want to remain in immersive sticky mode for the whole duration of the app. There is no problem when I launch a new activity, with and without a shared element transition. However, when I go back, the system bars sometimes appears then soon slide out of view again. This happens especially when I stay on an activity for a while.
This transition is called from _TrickPage.class:
public void setBorroRingsOnClickListener(View view){
dBHelper.close();
Intent intent = new Intent(this, _DominoScene.class);
startActivity(intent);
}
And I call finish() to get back to _TrickPage.class from _Domino.class:
findViewById(R.id.picture).setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
dBHelper.close();
finish();
}
});
Another transition I use is a shared element transition. The following is an inner class of ButtonAdapter, which extends BaseAdapter, an object in my _Submenu Activity:
class MyOnClickListener implements View.OnClickListener {
private final int position;
public MyOnClickListener(int position){
this.position = position;
}
#Override
public void onClick(View v) {
...
//link clicked button to _TrickPage button for shared transition
v.setTransitionName("trick");
//make and start shared transition to _TrickPage
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
(Activity)mContext,
new Pair<View, String>(v, "trick")
);
Intent intent = new Intent(v.getContext(), _TrickPage.class);
v.getContext().startActivity(intent, options.toBundle());
}
}
Finally, to get back to _Submenu from _TrickPage, I call finishaftertransition():
picture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dBHelper.close();
hideMainContent();
finishAfterTransition();
}
});
I set the UI flags in the onCreate() and onResume() methods of the Activities involved: _Submenu, _TrickPage, and _DominoScene. I also have the following in each activity:
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//if (hasFocus)
getWindow().getDecorView().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);
if (hasFocus && playAnimations) {
//showMainContent();
playAnimations = false;
}
}
This is my first time asking a question on Stack Overflow, so please ask for any other parts of my code if you think there could be a problem there. Thanks!
Call this method on your onCreate method from every Activity(right after your setContentView method). And also on the onWindowsFocusChanged
public void goImmersive()
{
getWindow().getDecorView().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);
}