Android Viewpager截取snackbar

Android Viewpager截取snackbar,android,android-viewpager,android-snackbar,Android,Android Viewpager,Android Snackbar,范围 我有一个片段包含一个ViewPager。viewpager的每个页面都包含一个项目片段。当我对项目片段执行操作时,我会在项目片段中显示一个snackbar。snackbar是项目片段的一部分(CoordinatorLayout是项目片段布局的一部分) 问题 我面临的问题是,不允许我关闭snackbar,因为viewpager会截取刷卡事件并更改页面,而不是让snackbar关闭 问题 我希望viewpager不要截取snackbar上的触摸,但仍然截取项目片段其余部分上的触摸(当用户不在s

范围

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

问题

我面临的问题是,不允许我关闭snackbar,因为viewpager会截取刷卡事件并更改页面,而不是让snackbar关闭

问题

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

我创建了一个示例应用程序来演示这个问题。可在

上查看我的解决方案

如果链接因某种原因被删除,我将解释我所做的

  • 我将相关的Snackbar类复制到我的项目中
  • 受一个类似问题的启发,我修改了Snackbar的行为子类,使其在viewpager中工作。具体地说,我发现视图层次结构中是否有一个viewpager作为snackbar的父级。然后,当触摸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;
        }
    }
    
    final类行为扩展了SwipedSmissBehavior{
    @凌驾
    公共布尔值onInterceptTouchEvent(CoordinatorLayout父级、SnackbarLayout子级、,
    运动(事件){
    ViewPager vp=getViewPagerParent(子级);
    if(parent.isPointInChildBounds(child,(int)event.getX(),(int)event.getY()){
    开关(event.getActionMasked()){
    case MotionEvent.ACTION\u DOWN:
    ViewPagerSnackbarManager.getInstance().cancelTimeout(mManagerCallback);
    //如果触摸Snackbar,请告诉viewpager不要截取触摸事件
    如果(vp!=null){
    请求副总裁不允许WinterCeptTouchEvent(真实);
    }
    打破
    case MotionEvent.ACTION\u UP:
    case MotionEvent.ACTION\u取消:
    //一旦此事件(触摸Snackbar)结束,请告诉viewpager继续拦截触摸事件
    如果(vp!=null){
    请求副总裁不允许WinterCeptTouchEvent(假);
    }
    ViewPagerSnackbarManager.getInstance().restoreTimeout(mManagerCallback);
    打破
    }
    }
    返回super.onInterceptTouchEvent(父、子、事件);
    }
    //在视图层次结构中向上移动以搜索Viewpager并在找到时返回它的helper方法。如果未找到,则返回Null。
    私有ViewPager getViewPagerParent(查看子视图){
    ViewParent=child.getParent();
    while(父级!=null){
    parent=child.getParent();
    if(ViewPager的父实例){
    返回(ViewPager)父对象;
    }else if(!(视图的父实例)){
    返回null;
    }否则{
    子项=(视图)父项;
    }
    }
    返回null;
    }
    }
    
    我遇到了同样的问题,另外,如果我向左/向右滚动,snackbar就会从页面上滚下来。我不知道这对你的场景是否有帮助,但我最终做的是将snackbar放在带有viewpager的布局中,而不是放在内部片段的布局中。然后,我将一条消息发送回持有视图寻呼机的片段,并从那里启动snackbar。我现在可以忽略它,它不会随着寻呼机滚动,这正是我想要的。希望有帮助!谢谢我最初尝试过这种方法,但我正在尝试将snackbar与它所属的片段保存在ViewPager中。如果用户在ViewPager中滑动片段,我希望snackbar可以与片段一起滑动。效果非常好。非常感谢。NP我开了一家商店。