如何阻止 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?