3

范围

我有一个包含 ViewPager 的片段。viewpager 的每个页面都包含一个项目片段。当我对项目片段执行操作时,我会在项目片段中显示一个快餐栏。小吃栏是项目片段的一部分(CoordinatorLayout 是项目片段布局的一部分)。

问题

我面临的问题是我不允许关闭snackbar,因为viewpager 拦截了滑动事件并更改页面而不是让snackbar 被关闭。

问题

我希望viewpager不要拦截对snackbar的触摸,但仍然拦截对项目片段其余部分的触摸(当不在snackbar上滑动时,用户应该仍然能够滑动以更改页面)。有谁知道这样做的方法?

我创建了一个示例应用程序来演示该问题。它可在https://github.com/gfrederick/ViewPagerSnackbar获得

4

1 回答 1

2

在github上查看我的解决方案。

如果链接由于某种原因被删除,我会解释我做了什么。

  1. 我将相关的 Snackbar 类复制到我的项目中。
  2. 这个对类似问题的回答的启发,我修改了 Snackbar 的 Behavior 子类以在查看器中工作。具体来说,我发现在视图层次结构中是否有一个 viewpager 作为快餐栏的父级。然后,当触摸 Snackbar 时,我禁用该 viewpagers 处理触摸事件。我在放开 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;
    }
}
于 2016-01-05T11:14:31.720 回答