У меня есть RecyclerView
с LinearLayoutManager
в ориентации HORIZONTAL
. Каждый элемент в нем может иметь интерактивные элементы (включая вертикальные ScrollView
s). Есть ли способ легко заставить RecyclerView
игнорировать любые попытки пользователя прокручивать или перемещать RecyclerView
по горизонтали, не перехватывая события касания к детям?
Я программно управляю прокруткой RecyclerView
, которая отлично работает, пока пользователь не запустит ее.
Я пробовал что-то очень простое, когда идея заключается в том, что я вызываю smoothScrollToPosition в ответ на какое-то событие, я разрешаю прокручивать и отключать события касания до тех пор, пока свиток не опустится. Вот так:
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());
который на самом деле почти работает... но я все еще могу испортить программную прокрутку, нажав на экран, когда плавный свиток движется. ясно, что я пропускаю что-то очевидное или есть гораздо более умный способ сделать это.
UPDATE решение, не относящееся к RecyclerView, было найдено здесь: Как отключить пейджинг, проверив пальцем в ViewPager, но все же сможете прокручивать программно?
/**
* 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;
}
}