Viewpager 拦截 snackbar dismiss
Viewpager intercepts snackbar dismiss
范围
我有一个包含 ViewPager 的片段。 viewpager 的每个页面都包含一个项目片段。当我对项目片段执行操作时,我会在项目片段中显示一个小吃店。 snackbar 是项目片段的一部分(CoordinatorLayout 是项目片段布局的一部分)。
问题
我面临的问题是不允许我关闭 snackbar,因为 viewpager 拦截滑动事件并更改页面而不是让 snackbar 被关闭。
问题
我希望 viewpager 不拦截 snackbar 上的触摸,但仍拦截项目片段其余部分的触摸(用户在不滑动 snackbar 时仍应能够滑动以更改页面)。有谁知道这样做的方法吗?
我创建了一个示例应用程序来演示该问题。可在 https://github.com/gfrederick/ViewPagerSnackbar
购买
在 github 上查看我的解决方案。
如果 link 由于某种原因被删除,我将解释我所做的。
- 我复制了相关的Snackbar 类到我的项目中。
- 受 this answer 类似问题的启发,我修改了 Snackbar 的 Behavior 子类以在 viewpager 中工作。具体来说,我发现在视图层次结构中是否有一个 viewpager 作为 snackbar 的父级。然后,当触摸 Snackbar 时,我禁用 viewpager 处理触摸事件。我在放开 Snackbar 时重新启用它(当触摸事件结束时)。
这是重要的代码:
final class Behavior extends SwipeDismissBehavior<SnackbarLayout> {
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, SnackbarLayout child,
MotionEvent event) {
ViewPager vp = getViewPagerParent(child);
if (parent.isPointInChildBounds(child, (int) event.getX(), (int) event.getY())) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
ViewPagerSnackbarManager.getInstance().cancelTimeout(mManagerCallback);
// If touching Snackbar tell the viewpager not to intercept touch events
if (vp != null) {
vp.requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// As soon as this event (touching the Snackbar) is over tell viewpager to resume intercepting touch events
if (vp != null) {
vp.requestDisallowInterceptTouchEvent(false);
}
ViewPagerSnackbarManager.getInstance().restoreTimeout(mManagerCallback);
break;
}
}
return super.onInterceptTouchEvent(parent, child, event);
}
// helper method that move up the view hierarchy searching for a Viewpager and returns it if found. Null if not found.
private ViewPager getViewPagerParent(View child) {
ViewParent parent = child.getParent();
while (parent != null) {
parent = child.getParent();
if (parent instanceof ViewPager) {
return (ViewPager) parent;
} else if (!(parent instanceof View)) {
return null;
} else {
child = (View) parent;
}
}
return null;
}
}
范围
我有一个包含 ViewPager 的片段。 viewpager 的每个页面都包含一个项目片段。当我对项目片段执行操作时,我会在项目片段中显示一个小吃店。 snackbar 是项目片段的一部分(CoordinatorLayout 是项目片段布局的一部分)。
问题
我面临的问题是不允许我关闭 snackbar,因为 viewpager 拦截滑动事件并更改页面而不是让 snackbar 被关闭。
问题
我希望 viewpager 不拦截 snackbar 上的触摸,但仍拦截项目片段其余部分的触摸(用户在不滑动 snackbar 时仍应能够滑动以更改页面)。有谁知道这样做的方法吗?
我创建了一个示例应用程序来演示该问题。可在 https://github.com/gfrederick/ViewPagerSnackbar
购买在 github 上查看我的解决方案。
如果 link 由于某种原因被删除,我将解释我所做的。
- 我复制了相关的Snackbar 类到我的项目中。
- 受 this answer 类似问题的启发,我修改了 Snackbar 的 Behavior 子类以在 viewpager 中工作。具体来说,我发现在视图层次结构中是否有一个 viewpager 作为 snackbar 的父级。然后,当触摸 Snackbar 时,我禁用 viewpager 处理触摸事件。我在放开 Snackbar 时重新启用它(当触摸事件结束时)。
这是重要的代码:
final class Behavior extends SwipeDismissBehavior<SnackbarLayout> {
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, SnackbarLayout child,
MotionEvent event) {
ViewPager vp = getViewPagerParent(child);
if (parent.isPointInChildBounds(child, (int) event.getX(), (int) event.getY())) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
ViewPagerSnackbarManager.getInstance().cancelTimeout(mManagerCallback);
// If touching Snackbar tell the viewpager not to intercept touch events
if (vp != null) {
vp.requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// As soon as this event (touching the Snackbar) is over tell viewpager to resume intercepting touch events
if (vp != null) {
vp.requestDisallowInterceptTouchEvent(false);
}
ViewPagerSnackbarManager.getInstance().restoreTimeout(mManagerCallback);
break;
}
}
return super.onInterceptTouchEvent(parent, child, event);
}
// helper method that move up the view hierarchy searching for a Viewpager and returns it if found. Null if not found.
private ViewPager getViewPagerParent(View child) {
ViewParent parent = child.getParent();
while (parent != null) {
parent = child.getParent();
if (parent instanceof ViewPager) {
return (ViewPager) parent;
} else if (!(parent instanceof View)) {
return null;
} else {
child = (View) parent;
}
}
return null;
}
}