嵌套Android ViewPager,在ListView中水平滑动ListItems

时间:2012-04-21 07:35:11

标签: android listview nested android-viewpager

我在活动的根级别上有一个ViewPager。

寻呼机的每个页面都包含一个ListFragment(由FragmentPagerAdapter支持)。

某些列表视图项应另外包含ViewPagers以支持滑动这些项的内容(例如列表项中的水平图库)。

如何嵌套查看寻呼机? ViewPager - > ListView(在页面中) - > ViewPager(在列表项内)

我可以水平滑动ListFragments,我可以垂直滑动整个列表,但我无法在列表项内滑动。

3 个答案:

答案 0 :(得分:11)

我在内部OnTouchListener添加了ViewPager

private OnTouchListener mSuppressInterceptListener = new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(
                event.getAction() == MotionEvent.ACTION_DOWN &&
                v instanceof ViewGroup
        ) {
                ((ViewGroup) v).requestDisallowInterceptTouchEvent(true);
        }
        return false;
    }
};

这只是检测内部ViewPager上的ACTION_DOWN触摸事件,并阻止外部人员拦截它。因为它返回false,所以只应该触发ACTION_DOWN事件;所有其他事件都将被忽略。您可以将此侦听器添加到您希望“保护”外部ViewPager滚动的每个元素,但很明显,如果您想要在这些元素上拾取任何其他触摸行为,则需要在内部处理它们触控倾听者,可能会有更好的倾听者。

归功于@Rodja,他首先给了我这个想法。

答案 1 :(得分:3)

虽然它不是最好的交互设计,但可以通过覆盖根级活动的 dispatchTouchEvent(MotionEvent ev)方法并使用 requestDisallowInterceptTouchEvent(true)来实现这一点在mainPager和当前的ListView上以防止其他滚动。看看这个例子:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {

    Fragment listFragment = getSupportFragmentManager().findFragmentByTag(
            "android:switcher:" + R.id.pager + ":" + (mainPager.getCurrentItem()));
    mainPager.getChildAt(mainPager.getCurrentItem());
    if (listFragment == null)
        return super.dispatchTouchEvent(ev);
    ViewPager embeddedPager = (ViewPager) listFragment.getView().findViewById(R.id.videopager);
    if (embeddedPager != null) {
        int[] position = new int[2];
        embeddedPager.getLocationOnScreen(position);
        if (ev.getY() > position[1] && ev.getY() < position[1] + embeddedPager.getHeight()) {
            mainPager.requestDisallowInterceptTouchEvent(true);
            if (embeddedPager.getScrollX() % embeddedPager.getWidth() != 0) {
                ListView listView = (ListView) listFragment.getView().findViewById(
                        android.R.id.list);
                listView.requestDisallowInterceptTouchEvent(true);
            }
        }
    }

    return super.dispatchTouchEvent(ev);
}

答案 2 :(得分:0)

您无法真正嵌套需要相同手势来控制它们的元素。由于视图寻呼机已经捕获了水平运动,因此嵌套元素将无法获取它。您可以通过管理焦点等来做很多工作来解决这个问题 - 但最终您的应用会让用户感到困惑。最好不要嵌套使用相同交互的元素......在这种情况下,两个视图寻呼机都在观察左右移动。