Immersive fullscreen on Android 11, show navigation bar with soft keyboard - android

The navigation bar won't appear with the soft-keyboard when in immersive fullscreen on Android 11, but on api < 30 the nav bar will show with the soft-keyboard.
private void hideSystemUI() {
if(Build.VERSION.SDK_INT < 30) {
#SuppressLint("WrongConstant") 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;
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().getDecorView().setSystemUiVisibility(flags);
final View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int i) {
if((i & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
decorView.setSystemUiVisibility(flags);
}
}
});
} else {
getWindow().setDecorFitsSystemWindows(false);
WindowInsetsController controller = getWindow().getInsetsController();
if (controller != null) {
controller.hide(WindowInsets.Type.systemBars());
controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
getWindow().getAttributes().layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; }
}
This is using a Searchview in Android 11 which brings up the soft-keyboard:
How can I make the navigation bar appear when the soft-keyboard appears?

Related

Disable android 10 back gestures on the left and right side

I want to disable back gestures in an activity. I tried this code but it does not work
Target: Disable left and right side edge back swipe gesture
1st try
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
hideSystemUI();
}
}
// Hide the system bars by adding flags
private void hideSystemUI() {
// Enables regular immersive mode.
// For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
// Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
}
Result: click on the activity all navigation work without an issue.
2nd try
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// Set the system navigation gesture exclusions
this.setSystemGestureExclusions();
}
private void setSystemGestureExclusions() {
if (Build.VERSION.SDK_INT < 29) {
return;
}
List<Rect> exclusionRects = new ArrayList();
Rect visibleRect = new Rect();
this.getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleRect);
exclusionRects.add(visibleRect);
getWindow().setSystemGestureExclusionRects(exclusionRects);
}
Result: Navigation work without an issue.
3rd try
ConstraintLayout coordinatorLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
coordinatorLayout = (ConstraintLayout) findViewById(R.id.activity_root);
coordinatorLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
coordinatorLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
updateGestureExclusion(MainActivity.this);;
}
}
});
}
static List<Rect> exclusionRects = new ArrayList<>();
public static void updateGestureExclusion(AppCompatActivity activity) {
if (Build.VERSION.SDK_INT < 29) return;
exclusionRects.clear();
Rect rect = new Rect(0, 0, dpToPx(activity, 16), getScreenHeight(activity));
exclusionRects.add(rect);
activity.findViewById(android.R.id.content).setSystemGestureExclusionRects(exclusionRects);
}
public static int getScreenHeight(AppCompatActivity activity) {
DisplayMetrics displayMetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
return displayMetrics.heightPixels;
}
public static int dpToPx(Context context, int i) {
return (int) (((float) i) * context.getResources().getDisplayMetrics().density);
}
Result: Navigation work without an issue.
Any suggestions ??

How to dynamic change a status-bar color using palettes?

I am using of Palette for dynamic status bar background color . for white color the status bar color should be in TranslucentStatus and for other color should be transparent color and with set color by Palette.
Glide.with(fragmentContext)
.load(offerData.getOfferImage())
.into(new ImageViewTarget<GlideDrawable>(imgViewOffer) {
#Override
protected void setResource(GlideDrawable resource){
setImage(resource);
extractColor(resource);
}
private void setImage(GlideDrawable resource) {
imgViewOffer.setImageDrawable(resource.getCurrent());
}
private void extractColor(GlideDrawable resource) {
Bitmap b = ((GlideBitmapDrawable) resource.getCurrent()).getBitmap();
Palette p = Palette.from(b).generate();
int defaultColor = fragmentContext.getResources().getColor(R.color.white);
int whiteColor = fragmentContext.getResources().getColor(R.color.white);
int color = p.getDarkVibrantColor(defaultColor);
if ((whiteColor == color)) {
setTransparentStatusBar(false);
} else {
setTransparentStatusBar(true);
}
}
});private void setTransparentStatusBar(boolean isCheckStatus) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window w = getActivity().getWindow();
if (isCheckStatus) {
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
} else {
w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
}
Note that I changed your Palette, Palette works better with AsyncListener.
Also, You don't need anything else.
Because Here you are extracting DOMINANT Color of the image, So no doubt it picks the best color for you
Glide.with(fragmentContext).load(offerData.getOfferImage())
.into(new ImageViewTarget < GlideDrawable > (imgViewOffer) {
#Override
protected void setResource(GlideDrawable resource) {
setImage(resource);
extractColor(resource);
}
private void setImage(GlideDrawable resource) {
imgViewOffer.setImageDrawable(resource.getCurrent());
}
private void extractColor(GlideDrawable resource) {
Bitmap b = ((GlideBitmapDrawable) resource.getCurrent()).getBitmap();
Palette.from(b).generate(new Palette.PaletteAsyncListener() {
#Override
public void onGenerated(Palette palette) {
int defaultColor = fragmentContext.getResources().getColor(R.color.white);
int color = palette.getDominantColor(defaultColor);
setTransparentStatusBar(color);
}
});
}
});
private void setTransparentStatusBar(int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
float lightness = Lightness(color);
if (lightness >= 0.5) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else if (lightness < 0.5) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
Don't forget to Add the private Float Lightness(...)...
You can change the status bar color only for api greater than 21 use the palette library for extracting the palette from image(refer this and Palette documentation) and then set the status bar color using
window.setStatusBarColor
I'm gonna suggest another way to do this, and it's not only as good as palette but better and faster and way easier.
Write this float method at the of any activity you want, you insert a Color into it and it can give you the brightness of that color.
public float Lightness(int color){
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
float hsl[] = new float[3];
ColorUtils.RGBToHSL(red, green, blue, hsl);
return hsl[2];
}
Now you can use this everywhere like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
float lightness = Lightness(YOUR_COLOR);
if (lightness >= 0.5) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else if (lightness < 0.5) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
You can use this in palette as well, like below:
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
#Override
public void onGenerated(Palette palette) {
float color = Lightness(palette.getVibrantColor(Enter_A_Default_Color_Here));
if (color >= 0.5) {
// ---- Use Dark Color
} else if (color < 0.5) {
// ---- Use Light Color
}
}
});

Navigation Bar gets visible again after open and close keyboard

private int currentApiVersion;
private void hideNavigationBar() {
currentApiVersion = android.os.Build.VERSION.SDK_INT;
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;
// This work only for android 4.4+
if (currentApiVersion >= Build.VERSION_CODES.KITKAT) {
getWindow().getDecorView().setSystemUiVisibility(flags);
// Code below is to handle presses of Volume up or Volume down.
// Without this, after pressing volume buttons, the navigation bar will
// show up and won't hide
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(flags);
}
}
});
}
}
#SuppressLint("NewApi")
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (currentApiVersion >= Build.VERSION_CODES.KITKAT && 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);
}
}
i called hideNavigationBar method from onCreate, but its not work for me. when i open keybard on clicking EditText and then close keyboard, but navigation bar not get invisible.
You have to hide navigation bar when closing the keyboard. Refer below code for this. It will help you
final View activityRootView = ((ViewGroup) getActivity().findViewById(android.R.id.content)).getChildAt(0);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
private final int DefaultKeyboardDP = 100;
private final int EstimatedKeyboardDP = DefaultKeyboardDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);
private final Rect r = new Rect();
private boolean wasOpened;
#Override
public void onGlobalLayout() {
// Convert the dp to pixels.
int estimatedKeyboardHeight = (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, activityRootView.getResources().getDisplayMetrics());
// Conclude whether the keyboard is shown or not.
activityRootView.getWindowVisibleDisplayFrame(r);
int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
boolean isShown = heightDiff >= estimatedKeyboardHeight;
if (isShown == wasOpened) {
Log.d("Keyboard state", "Ignoring global layout change...");
return;
}
wasOpened = isShown;
if (isShown) {
// Show keyborad
} else {
// Hide keyboard
}
}
});

Hide navigatiobar

I'm trying to hide navigationbar on my project. Here is my code
private void hideNavigationBar() {
View decorView = getWindow().getDecorView();
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
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
}
I call this function on my onResume() function.
But when I'm opening popupwindow in my activity the navigationbar appears again. How can I solve my problem?
Try this out for full screen
public void fullScreenCall() {
if(Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
View v = this.getWindow().getDecorView();
v.setSystemUiVisibility(View.GONE);
} else if(Build.VERSION.SDK_INT >= 19) {
//for new api versions.
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
}
}
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);
}
You should use it in onWindowFocusChanged callback.
#Override
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);
}
}
From android doc
With this approach, touching anywhere on the screen causes the navigation bar (and status bar) to reappear and remain visible. The
user interaction causes the flags to be be cleared.
Once the flags have been cleared, your app needs to reset them if you want to hide the bars again. See Responding to UI Visibility Changes for a discussion of how to listen for UI visibility changes so that your app can respond accordingly.

My class extends ActionBarActivity for full screen How to Hide and show the ActionBar on touch event

I am new to android, help me. When I click an image, it will show in
full screen but on touch it is not showing ActionBar and if I touch
it should hide ActionBar also in full screen mode
public void startFullScreen() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
} else {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
#TargetApi(Build.VERSION_CODES.KITKAT)
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
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);
}
}
Thanks
For Hiding ActionBar:
ActionBar bar = getSupportActionBar();
bar.hide();
And
For Showing ActionBar:
ActionBar bar = getSupportActionBar();
bar.show();
~hope it helps

Categories

Resources