如何通过在抽屉外触摸来防止关闭导航抽屉
How to prevent closing Navigation drawer by touch outside the drawer
我有一个带导航抽屉的 Activity。如果用户设备是 table 并且方向是横向 - 我不需要通过单击抽屉中的项目来关闭抽屉:
if (!isTablet || context.getResources().getConfiguration().orientation==1) {
mDrawerLayout.closeDrawer(Gravity.START);
}
有效。但是如果用户触摸打开的抽屉外面的屏幕 - 抽屉关闭。
使用 DrawerLayout.LOCK_MODE_LOCKED_OPEN 是不合适的 table 因为我需要保存抽屉滑动功能。
当用户触摸抽屉外部时,如何防止关闭导航抽屉?
请帮忙。
基于我写的另一个答案。我已经修改了代码以适合您的问题。请检查。
查看有关触摸层次结构的更多信息here
dispatchTouchEvent()
方法应该在 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);
}
}
注意:正如问题评论中提到的,这是反对Android guidelines的。所以尽量避免它,除非它是强制性的。
对我有用的 Noundla 答案的简化版本。我写了我的自定义抽屉,它扩展了 DrawerLayout
并实现了 dispatchTouchEvent()
方法。
@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);
}
此外,如果您想在抽屉打开时与主要内容片段保持交互,您应该在方法的开头添加这一行。
getChildAt(0).dispatchTouchEvent(event);
使用抽屉实例来防止非常简单
1.实施 DrawerLayout.DrawerListener
2。在这个方法中添加这个语句 us
@Override
public void onDrawerOpened(View drawerView) {
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);//DrawerLayout instance
}
我有一个带导航抽屉的 Activity。如果用户设备是 table 并且方向是横向 - 我不需要通过单击抽屉中的项目来关闭抽屉:
if (!isTablet || context.getResources().getConfiguration().orientation==1) {
mDrawerLayout.closeDrawer(Gravity.START);
}
有效。但是如果用户触摸打开的抽屉外面的屏幕 - 抽屉关闭。 使用 DrawerLayout.LOCK_MODE_LOCKED_OPEN 是不合适的 table 因为我需要保存抽屉滑动功能。 当用户触摸抽屉外部时,如何防止关闭导航抽屉?
请帮忙。
基于我写的另一个答案
查看有关触摸层次结构的更多信息here
dispatchTouchEvent()
方法应该在 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);
}
}
注意:正如问题评论中提到的,这是反对Android guidelines的。所以尽量避免它,除非它是强制性的。
对我有用的 Noundla 答案的简化版本。我写了我的自定义抽屉,它扩展了 DrawerLayout
并实现了 dispatchTouchEvent()
方法。
@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);
}
此外,如果您想在抽屉打开时与主要内容片段保持交互,您应该在方法的开头添加这一行。
getChildAt(0).dispatchTouchEvent(event);
使用抽屉实例来防止非常简单
1.实施 DrawerLayout.DrawerListener
2。在这个方法中添加这个语句 us
@Override
public void onDrawerOpened(View drawerView) {
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);//DrawerLayout instance
}