如何阻止 ExpandableListView 窃取子触摸事件?

Posted

技术标签:

【中文标题】如何阻止 ExpandableListView 窃取子触摸事件?【英文标题】:How to stop ExpandableListView from stealing child touch events? 【发布时间】:2013-11-20 16:49:25 【问题描述】:

我在 ExpandableListView 的组视图(部分标题)中有一个 ViewPager。正如预期的那样,ViewPager 的滚动有时会变得不稳定,很可能是因为 ExpandableListView 试图拦截触摸事件。作为一种解决方案,我试图阻止 ExpandableListView 拦截用于 ViewPager 的触摸事件。所以,到目前为止,这就是我所做的。

private void fixViewPager(ViewPager vp) 
    vp.setOnTouchListener(new ViewPager.OnTouchListener() 
        @Override
        public boolean onTouch(View v, MotionEvent event) 
            int action = event.getAction();
            switch (action) 
            case MotionEvent.ACTION_DOWN:
                // Disallow ScrollView to intercept touch events.
                Logger.log("Disabling event stealing");
                v.getParent().requestDisallowInterceptTouchEvent(true);
                break;

            case MotionEvent.ACTION_UP:
                // Allow ScrollView to intercept touch events.
                Logger.log("Enabling event stealing");
                v.getParent().requestDisallowInterceptTouchEvent(false);
                break;
            

            // Handle ListView touch events.
            v.onTouchEvent(event);
            return true;
        
    );     

但是,触摸监听器永远不会收到 ACTION_DOWN 事件。它似乎只得到 ACTION_UP 事件。我能做些什么来解决我的问题?谢谢!

【问题讨论】:

【参考方案1】:

在我发布我的问题后不久,我找到了这个答案https://***.com/a/9770373/1036017。基于此,我将代码更改为以下内容。现在,一旦在 ViewPager 中开始水平滚动,ViewPager 就会阻止 ExpandableListView 窃取触摸事件。

private void fixViewPager(ViewPager vp) 
    vp.setOnTouchListener(new ViewPager.OnTouchListener() 
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) 
            view.getParent().requestDisallowInterceptTouchEvent(true);
            switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) 
                case MotionEvent.ACTION_UP:
                    Logger.log("Disabling event stealing.");
                    view.getParent().requestDisallowInterceptTouchEvent(false);
                    break;
            
            return false;
        
    );     

【讨论】:

【参考方案2】:

解决方法是在viewPager中正确使用requestDisallowInterceptTouchEvent()方法。使用以下自定义 viewpager 类:

public class CustomViewPager extends ViewPager 
 boolean xScored = false, yScored = false;

 public CustomViewPager(Context context) 
    super(context);
 

 public CustomViewPager(Context context, AttributeSet attrs) 
    super(context, attrs);
 

 @Override
 public boolean onTouchEvent(MotionEvent ev) 
    mGestureDetector.onTouchEvent(ev);
    if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) 
        xScored = false;
        yScored = false;
        requestDisallowInterceptTouchEvent(false);
    
    return super.onTouchEvent(ev);
 

  GestureDetector.SimpleOnGestureListener mOnGestureListener = new GestureDetector.SimpleOnGestureListener() 
     @Override
     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) 
        if (!yScored && Math.abs(distanceX) > Math.abs(distanceY)) 
            xScored = true;
            yScored = false;
        
        if (xScored) 
            requestDisallowInterceptTouchEvent(true);
         else if (!xScored && Math.abs(distanceY) > Math.abs(distanceX)) 
            xScored = false;
            yScored = true;
            requestDisallowInterceptTouchEvent(false);
        
        return true;
     

  ;
  GestureDetector mGestureDetector = new GestureDetector(getContext(), mOnGestureListener);
 

【讨论】:

以上是关于如何阻止 ExpandableListView 窃取子触摸事件?的主要内容,如果未能解决你的问题,请参考以下文章

如何完全隐藏 ExpandableListView 的 groupIndicator?

如何在scrollview android中使用多个expandablelistview?

iOS如何防止应用程序窃取保存在谷歌驱动器中的文件?

如何清除 ExpandableListView?

如何自定义 ExpandableListView 目前仅显示一项“已扩展”

在键盘中单击完成时如何避免调用 ExpandableListView 中的 getChildView