Android 如果用户在ViewPager中向左或向右滑动,是否可以截取触摸事件并传输到ListView

Android 如果用户在ViewPager中向左或向右滑动,是否可以截取触摸事件并传输到ListView,android,android-viewpager,swipe,ontouchlistener,ontouch,Android,Android Viewpager,Swipe,Ontouchlistener,Ontouch,我有一个ViewPager,它包含两个片段,每个片段都包含带有可切换列表项的ListView。为了方便用户刷卡,我希望这样,如果用户在第一个片段中向左刷卡,则listview将拾取刷卡。如果用户在第二个片段中向右滑动,则listview将拾取该滑动。因为只有两个片段,所以有必要由listview拾取滑动,而不是viewpager,因为在这两个片段之后没有更多的片段可以滚动 那么,是否可以拦截触摸,并根据显示的viewpager页面和滑动方向将其传递给listview 这是我正在使用的可滑动列表视

我有一个ViewPager,它包含两个片段,每个片段都包含带有可切换列表项的ListView。为了方便用户刷卡,我希望这样,如果用户在第一个片段中向左刷卡,则listview将拾取刷卡。如果用户在第二个片段中向右滑动,则listview将拾取该滑动。因为只有两个片段,所以有必要由listview拾取滑动,而不是viewpager,因为在这两个片段之后没有更多的片段可以滚动

那么,是否可以拦截触摸,并根据显示的viewpager页面和滑动方向将其传递给listview


这是我正在使用的可滑动列表视图库:

我认为您可以自定义
ViewPager
并控制
listview
canScroll
中滑动
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);
    }

}
我试过一个样品,看起来效果不错。您可以使用此自定义的
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);
    }

}
我不确定这是否是解决这个问题的完美方案,但效果很好

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

  • 应用程序由带有两个片段页面的
    ViewPager
    组成。每个页面都有一个(可提供滑动关闭/删除功能)。由于父项
    ViewPager
    和子项列表项都可以滑动,因此会导致冲突。默认情况下,滑动由子ListItem拾取,该子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);
        }

    }
公共类ScrollLock扩展了ViewPager{
公共滚动锁(上下文){
超级(上下文);
}
公共滚动锁(上下文、属性集属性){
超级(上下文,attrs);
}
@凌驾
受保护的布尔值可滚动(视图v、布尔值检查v、整数dx、整数x、整数y){
if(v ViewPager实例){
if(getChildAt(getCurrentItem())!=null){
//将其设置为在刷走列表项时不会刷去刷新
SwipeRefreshLayout swipeLayout=(SwipeRefreshLayout)findViewById(R.id.swipe);
//获取当前片段的ListView
EnhancedListView EnhancedListView=(EnhancedListView)getChildAt(getCurrentItem()).findViewById(R.id.listView1);
//如果用户位于第一页并尝试向左滑动,请启用ListView滑动
如果(getCurrentItem()==0&&dx>0){
enhancedListView.enableSwipeToDismiss();
swipeLayout.setEnabled(假);
返回true;
} 
//如果用户位于第二页并试图向右滑动,请启用ListView滑动
else if(getCurrentItem()==1&&dx<0){
enhancedListView.enableSwipeToDismiss();
swipeLayout.setEnabled(假);
返回true;
} 
//通过启用父ViewPager滑动来阻止ListView滑动
否则{
enhancedListView.disableSwipeToDismiss();
}
}
}
返回super.canScroll(v,checkV,dx,x,y);
}
}

我认为您可以自定义
ViewPager
并控制
ListView
canScroll
中滑动
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);
    }

}
我试过一个样品,看起来效果不错。您可以使用此自定义的
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);
    }

}
我不确定这是否是解决这个问题的完美方案,但效果很好

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

  • 应用程序由带有两个片段页面的
    ViewPager
    组成。每个页面都有一个(可提供滑动关闭/删除功能)。由于父项
    ViewPager
    和子项列表项都可以滑动,因此会导致冲突。默认情况下,滑动由子ListItem拾取,该子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);
        }

    }
公共类ScrollLock扩展了ViewPager{
公共滚动锁(上下文){
超级(上下文);
}
公共滚动锁(上下文、属性集属性){
超级(上下文,attrs);
}
@凌驾
受保护的布尔值可滚动(视图v、布尔值检查v、整数dx、整数x、整数y){
if(v ViewPager实例){
if(getChildAt(getCurrentItem())!=null){
//将其设置为在刷走列表项时不会刷去刷新
SwipeRefreshLayout swipeLayout=(SwipeRefreshLayout)