如果用户在ViewPager中向左或向右滑动,是否可以拦截触摸事件并转移到ListView

时间:2014-09-25 20:43:25

标签: android android-viewpager swipe ontouchlistener ontouch

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

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

以下是我正在使用的可转换列表视图库:https://github.com/timroes/EnhancedListView

1 个答案:

答案 0 :(得分:4)

我认为您可以自定义ViewPager并控制ListView canScroll方法中ViewPager滑动的行为。

我试了一个样本,似乎工作正常。您可以使用此自定义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时才会阻止滑动。这些是onTouchEventEnhancedListView中的更改。

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

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

     .....

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

如果问题或答案不明确,以下是示例应用的一些屏幕截图。

  • 应用由ViewPager和两个片段页面组成。每个页面都有EnhanedListView(提供“滑动到解除/删除”功能)。由于可以刷换父ViewPager和子列表项,因此会导致冲突。默认情况下,子ListItem会抓取滑动,这会阻止父ViewPager滑动。

    enter image description here

必需的解决方案:

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

    enter image description here

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

    enter image description here

  • 在其他情况下,应刷过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);
        }

    }