I have an Activity with Navigation Drawer. if user device is table and orientation is landscape - I not need to close drawer by click on item in drawer:
if (!isTablet || context.getResources().getConfiguration().orientation==1) {
mDrawerLayout.closeDrawer(Gravity.START);
}
It work. But if user touch the screen outside opened drawer - drawer closing. Using DrawerLayout.LOCK_MODE_LOCKED_OPEN is unsuitable bacause I need to save drawer sliding functions. How to prevent closing Navigation drawer when user touch outside the drawer?
Please, help.
The navigation drawer is a UI panel that shows your app's main navigation menu. The drawer appears when the user touches the drawer icon in the app bar or when the user swipes a finger from the left edge of the screen.
When a user opens the drawer, Flutter adds the drawer to the navigation stack. Therefore, to close the drawer, call Navigator. pop(context) .
Based on the other answer which I wrote here. I have modified the code to suit your question. Please check.
Check more about touch hierarchy here
dispatchTouchEvent()
method should be overridden in Activity
class
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (isDrawerOpen()) { //Your code here to check whether drawer is open or not.
View content = findViewById(R.id.drawer); //drawer view id
int[] contentLocation = new int[2];
content.getLocationOnScreen(contentLocation);
Rect rect = new Rect(contentLocation[0],
contentLocation[1],
contentLocation[0] + content.getWidth(),
contentLocation[1] + content.getHeight());
if (!(rect.contains((int) event.getX(), (int) event.getY()))) {
isOutSideClicked = true;
} else {
isOutSideClicked = false;
}
} else {
return super.dispatchTouchEvent(event);
}
} else if (event.getAction() == MotionEvent.ACTION_DOWN && isOutSideClicked) {
isOutSideClicked = false;
return super.dispatchTouchEvent(event);
} else if (event.getAction() == MotionEvent.ACTION_MOVE && isOutSideClicked) {
return super.dispatchTouchEvent(event);
}
if (isOutSideClicked) {
return true; //restrict the touch event here
}else{
return super.dispatchTouchEvent(event);
}
}
Note: As mentioned in the question comments, this is against of Android guidelines. So try to avoid it until unless it is mandatory.
Simplified version of Noundla's answer which works for me. I wrote my custom Drawer which extends DrawerLayout
and implement dispatchTouchEvent()
method.
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (!this.isDrawerOpen(Gravity.LEFT)) {
return super.dispatchTouchEvent(event);
}
boolean isOutSideClicked = false;
if (event.getAction() == MotionEvent.ACTION_UP) {
View content = findViewById(R.id.drawer_view);
int[] contentLocation = new int[2];
content.getLocationOnScreen(contentLocation);
Rect rect = new Rect(contentLocation[0],
contentLocation[1],
contentLocation[0] + content.getWidth(),
contentLocation[1] + content.getHeight());
isOutSideClicked = !(rect.contains((int) event.getX(), (int) event.getY()));
}
this.setDrawerLockMode(isOutSideClicked ? DrawerLayout.LOCK_MODE_LOCKED_OPEN : DrawerLayout.LOCK_MODE_UNLOCKED);
return super.dispatchTouchEvent(event);
}
Also if you want to keep interact with main content fragment while drawer is open you should add this line at the beginning of the method.
getChildAt(0).dispatchTouchEvent(event);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With