Java ViewPager从子片段中窃取水平触摸事件
因此我有一个Java ViewPager从子片段中窃取水平触摸事件,java,android,android-fragments,Java,Android,Android Fragments,因此我有一个ViewPager,ViewPager包含两个选项卡,每个选项卡包含一个RecyclerView,可以在每个RecyclerView中添加和删除卡片。每个RecyclerView都包含在片段中。每个RecyclerView都使用ItemTouchHelper来管理onsweed()事件。RecyclerView中的卡有几种行为: 向右滑动将打开该卡的编辑器 向左滑动将删除该卡 按住卡并垂直向上或向下拖动可重新定位卡 我的问题是,ViewPager正在拦截每个RecyclerVie
ViewPager
,ViewPager
包含两个选项卡,每个选项卡包含一个RecyclerView
,可以在每个RecyclerView
中添加和删除卡片。每个RecyclerView
都包含在片段中。每个RecyclerView
都使用ItemTouchHelper
来管理onsweed()
事件。RecyclerView
中的卡有几种行为:
- 向右滑动将打开该卡的编辑器
- 向左滑动将删除该卡
- 按住卡并垂直向上或向下拖动可重新定位卡
我的问题是,ViewPager
正在拦截每个RecyclerView
的onsweep()
方法,但是每个RecyclerView
仍然正确接收垂直触摸事件。显然,这归结为一个触碰冲突问题。ViewPager
需要用于更改选项卡的水平触摸事件,RecyclerView
需要用于刷卡的水平触摸事件。但是,ViewPager
正在窃取所有触摸事件。我已禁用了在ViewPager
上的水平滑动(用户更改选项卡的唯一方法是点击选项卡指示器),但RecyclerView
仍然不会接收任何水平触摸事件
以下是禁用刷卡的ViewPager
:
public class NoSwipePager extends ViewPager {
public NoSwipePager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return false;
}
}
下面是一个片段类:
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.pit_tab, container, false);
container.getParent().requestDisallowInterceptTouchEvent(true);
RecyclerView rv = (RecyclerView) view.findViewById(R.id.movie_recycler_view);
return view;
}
下面是管理RecyclerView
的类:
public EditManager(RecyclerView rv, Context act, EditListener listener, ArrayList<Element> elements, boolean editing, boolean pit) {
//rv = (RecyclerView) act.findViewById(R.id.movie_recycler_view);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(act);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
rv.setLayoutManager(linearLayoutManager);
((SimpleItemAnimator) rv.getItemAnimator()).setSupportsChangeAnimations(false);
if(elements != null) elementsAdapter = new ElementsAdapter(listener, act, new LinkedList<>(elements), editing);
else elementsAdapter = new ElementsAdapter(listener, act, null, editing);
rv.setAdapter(elementsAdapter);
ItemTouchHelper.Callback callback = new ElementTouchHelper(elementsAdapter);
ItemTouchHelper helper = new ItemTouchHelper(callback);
helper.attachToRecyclerView(rv);
}
尝试用以下内容替换您的noswiper
:
public class NoSwipePager extends ViewPager {
public NoSwipePager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x,
int y) {
if (v instanceof RecyclerView) {
return(true);
}
return(super.canScroll(v, checkV, dx, x, y));
}
}
我已成功地将此方法用于页面中带有地图的ViewPager
(将SurfaceView
替换为RecyclerView
)。我的猜测是,您将需要用更复杂的测试(并针对您的应用程序进行定制)替换RecyclerView的v instanceof
测试。但是我认为canScroll()
比阻塞onInterceptTouchEvent()
更能满足您的需求,好吧,所以我用您的代码替换了ViewPager
,但它仍然不起作用。如果在屏幕边缘附近开始刷卡,则现在可以通过刷卡来更改选项卡,但是RecyclerView
中的卡仍然不会移动。还有其他想法吗@CommonsWare@wdavies973:在你的if()
测试中,我有v instanceof RecyclerView
,你最终使用了什么?好吧,目前它是一样的(v instanceof RecyclerView
),但我不认为canScroll()
对RecylerViews
接收onsweep()
,有什么影响,你有什么建议吗?我可以检查视图ID,但我不确定。垂直滚动在RecyclerView
上仍然可以正常工作,但卡的左右滑动不起作用@CommonsWare@wdavies973:添加CardView的| | v instanceof
(或任何您的卡)并查看发生了什么。基本上,您希望canScroll()
返回true
,对于任何您希望自己进行滚动/滑动的小部件,否则返回false
。
public class NoSwipePager extends ViewPager {
public NoSwipePager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x,
int y) {
if (v instanceof RecyclerView) {
return(true);
}
return(super.canScroll(v, checkV, dx, x, y));
}
}