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 ??
Related
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?
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
}
}
});
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
}
}
});
I am stuck with status bar hiding. Let me explain I am Implementing activity and also place manifest file in android:windowSoftInputMode="adjustResize" for keyboard place below edittext, it is working fine but i want also hide navigation bar, so i am using "Theme.Holo.Light.NoActionBar.Fullscreen" theme. But when keyboard appearing app navigation bar also scrolling. How can i restrict scrolling navigation bar and hide notification bar when keyboard appearing.
I think this is help you => http://developer.android.com/reference/android/view/View.html#setSystemUiVisibility(int)
=>setSystemUiVisibility(newVis); //this method help you
=> this is class for information and better understand.
public static class Content extends ScrollView
implements View.OnSystemUiVisibilityChangeListener, View.OnClickListener {
TextView mText;
TextView mTitleView;
SeekBar mSeekView;
boolean mNavVisible;
int mBaseSystemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| SYSTEM_UI_FLAG_LAYOUT_STABLE;
int mLastSystemUiVis;
Runnable mNavHider = new Runnable() {
#Override public void run() {
setNavVisibility(false);
}
};
public Content(Context context, AttributeSet attrs) {
super(context, attrs);
mText = new TextView(context);
mText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
mText.setText(context.getString(R.string.alert_dialog_two_buttons2ultra_msg));
mText.setClickable(false);
mText.setOnClickListener(this);
mText.setTextIsSelectable(true);
addView(mText, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
setOnSystemUiVisibilityChangeListener(this);
}
public void init(TextView title, SeekBar seek) {
// This called by the containing activity to supply the surrounding
// state of the content browser that it will interact with.
mTitleView = title;
mSeekView = seek;
setNavVisibility(true);
}
#Override public void onSystemUiVisibilityChange(int visibility) {
// Detect when we go out of low-profile mode, to also go out
// of full screen. We only do this when the low profile mode
// is changing from its last state, and turning off.
int diff = mLastSystemUiVis ^ visibility;
mLastSystemUiVis = visibility;
if ((diff&SYSTEM_UI_FLAG_LOW_PROFILE) != 0
&& (visibility&SYSTEM_UI_FLAG_LOW_PROFILE) == 0) {
setNavVisibility(true);
}
}
#Override protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
// When we become visible, we show our navigation elements briefly
// before hiding them.
setNavVisibility(true);
getHandler().postDelayed(mNavHider, 2000);
}
#Override protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
// When the user scrolls, we hide navigation elements.
setNavVisibility(false);
}
#Override public void onClick(View v) {
// When the user clicks, we toggle the visibility of navigation elements.
int curVis = getSystemUiVisibility();
setNavVisibility((curVis&SYSTEM_UI_FLAG_LOW_PROFILE) != 0);
}
void setBaseSystemUiVisibility(int visibility) {
mBaseSystemUiVisibility = visibility;
}
void setNavVisibility(boolean visible) {
int newVis = mBaseSystemUiVisibility;
if (!visible) {
newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN;
}
final boolean changed = newVis == getSystemUiVisibility();
// Unschedule any pending event to hide navigation if we are
// changing the visibility, or making the UI visible.
if (changed || visible) {
Handler h = getHandler();
if (h != null) {
h.removeCallbacks(mNavHider);
}
}
// Set the new desired visibility.
setSystemUiVisibility(newVis);
mTitleView.setVisibility(visible ? VISIBLE : INVISIBLE);
mSeekView.setVisibility(visible ? VISIBLE : INVISIBLE);
}
}
I am trying to block status bar and I am successful in doing that by adding a view to status bar. I am trying to remove the added view when onClick is detected, but the view still remains and I am not able to remove the view. Can any one please let me know what am I missing. The current code is as shown below:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
manager = ((WindowManager) getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE));
localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
// this is to enable the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
localLayoutParams.height = (int) (50 * getResources()
.getDisplayMetrics().scaledDensity);
localLayoutParams.format = PixelFormat.TRANSPARENT;
view = new customViewGroup(this);
manager.addView(view, localLayoutParams);
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
m_activateButton = (Button)findViewById(R.id.button);
m_activateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(manager != null){
manager.removeView(view);
}
}});
}
CustomView Class:
public class customViewGroup extends ViewGroup {
public customViewGroup(Context context) {
super(context);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v("customViewGroup", "**********Intercepted");
return true;
}
}