如何通过编程方式禁用RecyclerView的滚动 [英] How to disable scrolling of RecyclerView except programmatically
问题描述
我有一个 RecyclerView
,其中 LinearLayoutManager
的方向为 HORIZONTAL
.其中的每个项目都可以具有交互元素(包括垂直的 ScrollView
s).有没有一种方法可以轻松地使 RecyclerView
忽略用户的任何尝试而水平滚动或弹出 RecyclerView
而不会拦截孩子的触摸事件?
I have a RecyclerView
with a LinearLayoutManager
in orientation HORIZONTAL
. Each item in it can have interactive elements (including vertical ScrollView
s). Is there a way to easily make the RecyclerView
ignore any attempts by the user to scroll or fling the RecyclerView
horizontally without intercepting touch events to the children?
我正在以编程方式控制 RecyclerView
的滚动,直到用户扔掉它之前,滚动条都很好用.
I am programmatically controlling the scroll of the RecyclerView
which works great until the user flings it.
我尝试了一种非常简单的方法,即当我响应某些事件而调用smoothScrollToPosition时,启用滚动并禁用触摸事件,直到滚动稳定为止.像这样:
I have tried something very simple where the idea is when I call smoothScrollToPosition in response to some event, I enable scrolling and disable touch events until the scroll settles. Like this:
private class NoScrollHorizontalLayoutManager extends LinearLayoutManager {
ScrollingTouchInterceptor interceptor = new ScrollingTouchInterceptor();
protected boolean canScroll;
public NoScrollHorizontalLayoutManager(Context ctx) {
super(ctx, LinearLayoutManager.HORIZONTAL, false);
}
public RecyclerView.OnItemTouchListener getInterceptor() {
return interceptor;
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
canScroll = true;
super.smoothScrollToPosition(recyclerView, state, position);
}
@Override
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
if(state == RecyclerView.SCROLL_STATE_IDLE) {
canScroll = false;
}
}
@Override
public boolean canScrollHorizontally() {
return canScroll;
}
public class ScrollingTouchInterceptor implements RecyclerView.OnItemTouchListener {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
return canScrollHorizontally();
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
}
并像这样使用它.
NoScrollHorizontalLayoutManager layout = new NoScrollHorizontalLayoutManager(context);
recycler.setLayoutManager(layout);
recycler.addOnItemTouchListener(layout.getInterceptor());
实际上几乎可以正常工作的
...但是当平滑滚动运动时,我仍然可以通过点击屏幕来固定程序化滚动.显然,我缺少明显的东西,或者有更聪明的方法来做到这一点.
which actually almost works... but I can still screw up the programmatic scroll by tapping the screen when the smooth scroll is in motion. clearly I'm missing something obvious or there is a much smarter way to do this.
UPDATE the non-RecyclerView solution was found here: How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?
/**
* ViewPager that doesn't allow swiping.
*/
public class NonSwipeableViewPager extends ViewPager {
public NonSwipeableViewPager(Context context) {
super(context);
}
public NonSwipeableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Never allow swiping to switch between pages
return false;
}
}
推荐答案
覆盖onInterceptTouchEvent可以避免点击行为停止.
Overriding onInterceptTouchEvent you avoid the stop on click behaviour.
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
return false;
}
这篇关于如何通过编程方式禁用RecyclerView的滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!