【问题标题】:Nesting Android ViewPager, Swiping ListItems inside a ListView horizontally嵌套 Android ViewPager,在 ListView 内水平滑动 ListItems
【发布时间】:2012-04-21 07:35:11
【问题描述】:

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

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

某些列表视图项目应包含额外的 ViewPager 以支持滑动这些项目的内容(例如,列表项目内的水平画廊)。

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

我可以在 ListFragments 之间水平滑动,也可以垂直滑动整个列表,但不能在列表项内滑动。

【问题讨论】:

    标签: android listview nested android-viewpager


    【解决方案1】:

    我在内部ViewPager添加了一个OnTouchListener

    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,他首先给了我这个想法。

    【讨论】:

    • 哇。干净多了。谢谢!
    • 迄今为止最简单的解决方案。
    • 简直不敢相信它的工作如此简单。非常感谢,Andrew 和 Rodja!
    • 我遇到了类似的问题,这让我可以左右滑动。如果我还想启用点击然后打开选定的视图怎么办?
    • 您可以编写自己的点击监听器,方法是监听 ACTION_DOWN 和 ACTION_UP;如果介于两者之间的所有 ACTION_MOVE 事件的总和小于系统 touch slop(见下文),则将其称为单击。 developer.android.com/reference/android/view/… 具有用于触摸倾斜、长按以及通常您需要的任何内容的常量。
    【解决方案2】:

    虽然它不是最好的交互设计,但可以通过覆盖根级 Activity 的 dispatchTouchEvent(MotionEvent ev) 方法并使用 requestDisallowInterceptTouchEvent(true) 来实现这一点em> 在 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);
    }
    

    【讨论】:

    • 谢谢你——我稍微修改了这个想法,让你把代码放在Activity#dispatchTouchEvent(MotionEvent)函数之外的其他地方,但我使用的想法基本上是你的:)
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多