Viewpager拦截了snackbar dismiss

时间:2015-11-03 14:52:12

标签: android android-viewpager android-snackbar

范围

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

问题

我面临的问题是我不能解雇小吃吧,因为viewpager拦截滑动事件并更改页面而不是让小吃店被解雇。

问题

我希望viewpager不要截取小吃栏上的触摸,但仍然会拦截项目片段剩余部分的触摸(当不在小吃栏上滑动时,用户仍然可以滑动以更改页面)。有谁知道这样做的方法?

我创建了一个示例应用来演示此问题。它位于https://github.com/gfrederick/ViewPagerSnackbar

1 个答案:

答案 0 :(得分:2)

github上查看我的解决方案。

如果链接因某种原因被删除,我会解释我的所作所为。

  1. 我将相关的Snackbar类复制到我的项目中。
  2. 受到this answer的启发,类似的问题我修改了Snackbar的Behavior子类以在viewpager中工作。具体来说,我发现是否有一个viewpager作为视图层次结构中的snackbar的父级。然后,当触摸Snackbar时,我禁用该浏览器处理触摸事件。当我放开Snackbar时(触摸事件结束时)我重新启用它。
  3. 这是重要的代码:

    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;
        }
    }