Отключить скроллинг в детском Recyclerview android
У меня есть макет состоит из родительского RecyclerView с вложенным RecyclerView в нем
я знаю, что нехорошо помещать список в другой список, но мне нужно, чтобы я мог использовать функции подсписка, такие как перелистывание и перетаскивание
Моя проблема в том, что дочерний Recyclerview получает фокус и останавливает прокрутку родителя, если точка касания была на нем, просто я хочу, если касание было вертикально на дочернем Recyclerview, родитель прокручивает вверх и вниз, и если касание было горизонтальным или щелчок затем дочерний элемент списка Recyclerview смахивает влево и вправо. Любая помощь для достижения этого?
10 ответов
Я наконец нашел решение.
Создать пользовательский LinearLayoutManager
public class CustomLinearLayoutManager extends LinearLayoutManager {
public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
// it will always pass false to RecyclerView when calling "canScrollVertically()" method.
@Override
public boolean canScrollVertically() {
return false;
}
}
Затем создайте экземпляр для вертикальной прокрутки
CustomLinearLayoutManager customLayoutManager = new CustomLinearLayoutManager(getActivity(),LinearLayoutManager.VERTICAL,false);
Наконец, установите пользовательский макет в качестве диспетчера макетов представления переработчика
recyclerView.setLayoutManager(customLayoutManager);
android:nestedScrollingEnabled="false"
в дочернем RecyclerView
Можете добавить
android:nestedScrollingEnabled="false"
к вашему RecyclerView в XML или
childRecyclerView.setNestedScrollingEnabled(false);
к вашему RecyclerView в Java.
РЕДАКТИРОВАТЬ:-
childRecyclerView.setNestedScrollingEnabled(false);
будет работать только в android_version>21 устройства. для работы на всех устройствах используйте следующее
ViewCompat.setNestedScrollingEnabled(childRecyclerView, false);
В вашем ActivityName.java внутри метода onCreate() напишите:
RecyclerView v = (RecyclerView) findViewById(R.id.your_recycler_view_id);
v.setNestedScrollingEnabled(false);
Любым способом, если вы используете Layout Coordinator, в случае, если вы хотите упростить вещи, и вы хотите отключить вложенную прокрутку.
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/activitiesListRV"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v4.widget.NestedScrollView>
И снова вы применяете тот же принцип: в вашем ActivityName.java внутри метода onCreate() напишите:
RecyclerView v = (RecyclerView) findViewById(R.id.your_recycler_view_id);
v.setNestedScrollingEnabled(false);
Так что в основном в XML вы должны указать приложение: layout_behavior
app:layout_behavior="@string/appbar_scrolling_view_behavior">
Хотя использование встроенных представлений переработчика может быть нецелесообразным, иногда этого нельзя избежать. Нечто подобное может работать:
public class NoScrollRecycler extends RecyclerView {
public NoScrollRecycler(Context context){
super(context);
}
public NoScrollRecycler(Context context, AttributeSet attrs){
super(context, attrs);
}
public NoScrollRecycler(Context context, AttributeSet attrs, int style){
super(context, attrs, style);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev){
//Ignore scroll events.
if(ev.getAction() == MotionEvent.ACTION_MOVE)
return true;
//Dispatch event for non-scroll actions, namely clicks!
return super.dispatchTouchEvent(ev);
}
}
Это отключит событие прокрутки, но не события щелчка. Используйте этот класс для "дочернего" RecyclerView. Вы хотите, чтобы прокручивать представление PARENT, а не ребенок. Что ж, это должно быть сделано, так как родитель будет просто стандартным RecyclerView, но дочерним будет этот пользовательский, без прокрутки, но обрабатывающий щелчки. Возможно, нужно отключить щелчок для родительского RecyclerView.. Не уверен, так как я не проверял это, так что рассмотрите это просто как пример...
Кроме того, чтобы использовать это в XML (если вы не знали), сделайте следующее:
<com.yourpackage.location.NoScrollRecycler
...
... >
...
...
</com.yourpackage.location.NoScrollRecycler>
Ты можешь использовать setNestedScrollingEnabled(false);
на суб RecyclerView
который перестает прокручивать внутри саба RecyclerView
,
В моем случае код был
mInnerRecyclerView.setNestedScrollingEnabled(false);
где mInnerRecyclerView
быть внутренним RecyclerView
,
Я думаю, что я опоздал, но здесь я нашел решение, если это все еще кого-то раздражает:
RecyclerView v = (RecyclerView);
findViewById(R.id.your_recycler_view_id);
v.setNestedScrollingEnabled(false);
sensorsRecyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
Я перепробовал много предложенных решений и не смог найти подходящего в моем случае. У меня есть более 1 RecyclerView внутри ScrollView с помощью GridLayoutManager. В результате предложения, приведенного выше, ScrollView прекращал прокручивать всякий раз, когда я поднимал палец (он не скользил по верху или низу обзора, когда мой палец был поднят над RecyclerView)
Просматривая источник RecyclerView, внутри onTouchEvent происходит вызов менеджера макета:
final boolean canScrollHorizontally = mLayout.canScrollHorizontally();
final boolean canScrollVertically = mLayout.canScrollVertically();
Если вы переопределите их в пользовательском менеджере макета, верните false, и он перестанет прокручиваться. Это также устраняет проблему, при которой ScrollView внезапно прекращает прокрутку.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_marginTop="2dp"
android:layout_marginLeft="2dp"
android:layout_marginBottom="10dp"
android:layout_marginRight="2dp"
android:nestedScrollingEnabled="false"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
поместите код в макет linner... не нужно ничего делать прагматично
Если вы не хотите создавать пользовательский вид, другой вариант - создать макет того же размера перед RecyclerView и сделать его кликабельным.
РЕДАКТИРОВАТЬ: Но, к сожалению, он также блокирует события для элемента списка.
В
Kotlin
способ:
recyclerView.layoutManager = object: LinearLayoutManager(recyclerView.context) {
override fun canScrollVertically(): Boolean {
return false
}
}