1

我有一个包含两个片段的 ViewPager,每个片段都包含带有可滑动列表项的列表视图。为了让用户更容易滑动,我希望这样如果用户在第一个片段中向左滑动,列表视图会拾取滑动。如果用户在第二个片段中向右滑动,则列表视图会拾取滑动。由于只有两个片段,因此列表视图而不是 viewpager 拾取滑动是有意义的,因为在这两个片段之后没有更多片段可以滚动到。

那么,是否有可能拦截触摸,并根据显示的 viewpager 页面和滑动方向将其传递给列表视图?

这是我正在使用的可滑动列表视图库:https ://github.com/timroes/EnhancedListView

4

1 回答 1

4

我认为您可以自定义并ViewPager控制.ListViewcanScrollViewPager

我尝试了一个示例,它似乎工作正常。您可以使用此自定义ViewPager

public class CustomViewPager extends ViewPager {

    public CustomViewPager(Context context) {
        super(context);
    }

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

    @Override
    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
        if (v instanceof ViewPager) {
            if (getChildAt(getCurrentItem()) != null) {
                //get the ListView of current Fragment
                EnhancedListView enhancedListView = (EnhancedListView) getChildAt(getCurrentItem()).findViewById(R.id.list);
                //If the user is in first page and tries to swipe left, enable the ListView swipe
                if (getCurrentItem() == 0 && dx > 0) {
                    enhancedListView.enableSwipeToDismiss();
                } 
                //If the user is in second page and tries to swipe right, enable the ListView swipe
                else if (getCurrentItem() == 1 && dx < 0) {
                    enhancedListView.enableSwipeToDismiss();
                } 
                //Block the ListView swipe there by enabling the parent ViewPager swiping
                else {
                    enhancedListView.disableSwipeToDismiss();
                }
            }
        }
        return super.canScroll(v, checkV, dx, x, y);
    }

}

EnhancedListView此外,您还必须在库中进行一些更改。因为canScroll方法是在ACTION_DOWN事件之后调用的,如果我们启用刷入canScroll方法 - 它会跳过为ACTION_DOWN事件定义的逻辑,并且可能会导致意外行为。因此,仅当触摸事件为 时才阻止滑动ACTION_MOVE。这些是图书馆的onTouchEvent变化EnhancedListView

//EnhancedListView class
@Override
    public boolean onTouchEvent(MotionEvent ev) {

        if (!mSwipeEnabled && (ev.getAction() == MotionEvent.ACTION_MOVE)) {
            return super.onTouchEvent(ev);
        }

     .....

我不确定这是否是问题的完美解决方案,但它工作得很好。

如果问题或答案不清楚,这里是示例应用程序的一些屏幕截图。

  • 应用程序由ViewPager两个片段页面组成。每个页面都有一个EnhanedListView(它提供 Swipe To Dismiss/Delete 功能)。由于父子ViewPager列表项都可以滑动,所以会导致冲突。默认情况下,子 ListItem 会拾取滑动,这会阻止父ViewPager级滑动。

    在此处输入图像描述

所需解决方案:

  • 如果用户在第一页并向右滑动,则应滑动列表项。

    在此处输入图像描述

  • 如果用户在第二页并向左滑动,则应滑动列表项。

    在此处输入图像描述

  • 在其他情况下,ViewPager应该刷卡。

更新:要修复错误,这里是自定义代码SwipeRefreshLayout的细微变化。ViewPager

 public class ScrollLock extends ViewPager {


        public ScrollLock(Context context) {
            super(context);
        }

        public ScrollLock(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @Override
        protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
            if (v instanceof ViewPager) {
                if (getChildAt(getCurrentItem()) != null) {
                    //set it so it does not swipe to refresh while swiping away a list item
                    SwipeRefreshLayout swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe);

//get the ListView of current Fragment
                    EnhancedListView enhancedListView = (EnhancedListView) getChildAt(getCurrentItem()).findViewById(R.id.listView1);
                    //If the user is in first page and tries to swipe left, enable the ListView swipe
                    if (getCurrentItem() == 0 && dx > 0) {
                        enhancedListView.enableSwipeToDismiss();
                        swipeLayout.setEnabled(false);
                        return true;
                    } 
                    //If the user is in second page and tries to swipe right, enable the ListView swipe
                    else if (getCurrentItem() == 1 && dx < 0) {
                        enhancedListView.enableSwipeToDismiss();
                        swipeLayout.setEnabled(false);
                        return true;
                    } 
                    //Block the ListView swipe there by enabling the parent ViewPager swiping
                    else {
                        enhancedListView.disableSwipeToDismiss();
                    }
                }
            }
            return super.canScroll(v, checkV, dx, x, y);
        }

    }
于 2014-09-29T17:24:15.770 回答