У меня есть Activity
ниже:
<RecyclerView> // with horizontal LinearLayoutManager and PagerSnapHelper
<RecyclerView> // with vertical LinearLayoutManager
<RecyclcerView /> // with horizontal LinearLayoutManager
<HorizontalScrollView />
// ... and there are other normal list items
</RecyclerView>
<RecyclerView> // another RV with vertical LinearLayoutManager
</RecyclerView>
</RecyclerView>
Проблема в том, что при горизонтальной прокрутке внутренняя горизонтальная RecyclerView
и HorizontalScrollView
не прокручиваются должным образом.
Почему я должен это сделать:
У меня есть несколько ListFragment
с, каждый из которых получает данные из разных источников данных, но имеет элементы списка одного типа. Я не хочу ViewPager
, который либо удерживает все страницы сразу после создания ViewPager
(что может вызвать OutOfMemoryError), либо перезагружает данные из сети после прокрутки пользователем на другие страницы и прокрутки назад. Более того, с помощью вложенного RV страницы могут совместно использовать один и тот же RecyclerViewPool
, что помогает уменьшить общее количество просмотров элементов на всех страницах.
Что я сделал во внешнем горизонтальном RV:
private static final int INVALID_POINTER = -1;
private int mActivePointerId = INVALID_POINTER;
private float lastX;
private GestureDetector mVerticalScrollGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return Math.abs(distanceX) < Math.abs(distanceY);
}
});
private GestureDetector mHorizontalScrollGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return Math.abs(distanceX) > Math.abs(distanceY);
}
});
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
if (mVerticalScrollGestureDetector.onTouchEvent(e) || !mAllowPageScroll) {
return false;
}
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = e.getPointerId(0);
break;
case MotionEvent.ACTION_MOVE:
int pointerIndex = e.findPointerIndex(mActivePointerId);
float x = e.getX(pointerIndex);
float dx = x - lastX;
lastX = x;
if (childCanScroll(this, false, (int) dx, (int) x)) {
Log.d("ScrollX", "not intercept");
return false;
}
Log.d("ScrollX", "maybe intercept");
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mActivePointerId = INVALID_POINTER;
break;
}
return super.onInterceptTouchEvent(e);
}
private boolean childCanScroll(View v, boolean considerSelf, int dx, int x) {
if (v instanceof ViewGroup) {
ViewGroup group = (ViewGroup) v;
int scrollX = v.getScrollX();
for (int i = group.getChildCount() - 1; i >= 0; i--) {
View child = group.getChildAt(i);
if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight()
&& childCanScroll(child, true, dx, x + scrollX - child.getLeft())) {
return true;
}
}
}
return considerSelf && v.canScrollHorizontally(-dx);
}
Теперь он работает с внутренним горизонтальным RV с , иногда без прокрутки , а вообще не работает с HorizontalScrollView
.
Как мне достичь цели, чтобы сделать горизонтальный прокручиваемый вид для прокрутки первым?