我在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事件。我该怎么做才能解决我的问题?谢谢!
答案 0 :(得分:3)
我发布问题后不久,我找到了这个答案https://stackoverflow.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;
}
});
}
答案 1 :(得分:0)
解决方案是在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);
}