在我的应用程序中,我有垂直父级
RecyclerView
,其 ViewHolders
内有几个水平子级。但我有一个非常烦人的滚动问题 - 在我垂直滚动父房车后,我想滚动我的一个子房车,但父房只是拦截所有运动事件,直到我将手指从屏幕上移开然后放回去。这是这种令人讨厌的行为的示例。
https://i.imgur.com/dPtmAXD.gif
我尝试了这个问题的所有解决方案 - Nested RecyclerView。如何防止子RecyclerView滚动时父RecyclerView滚动?
没有什么对我有用。
看起来 Google Play 市场具有相同的 RV 层次结构,但 ofc 滚动完全没问题。我尝试实施其他主题的一些解决方案,但没有任何效果按预期进行。
我不知道应该发布什么代码,但这是我的父 RV 的 ViewHolder 示例,其中包含嵌套 RV。
private class UserEventsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private RecyclerView rvUserEvents;
private HomeUserEventsRVAdapter rvAdapter;
public UserEventsViewHolder(View v) {
super(v);
rvUserEvents = v.findViewById(R.id.rv_user_events);
rvUserEvents.setLayoutManager(new LinearLayoutManager(itemView.getContext(), LinearLayoutManager.HORIZONTAL, false));
rvUserEvents.setNestedScrollingEnabled(false);
rvUserEvents.setRecycledViewPool(viewPool);
rvAdapter = new HomeUserEventsRVAdapter(presenter);
rvUserEvents.setAdapter(rvAdapter);
v.findViewById(R.id.btn_all_user_events).setOnClickListener(this);
}
private void bind(UserItemViewModel userItem) {
rvAdapter.updateAdapter(userItem);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_all_user_events:
presenter.openUserEventsList();
break;
}
}
}
编辑:我的活动的 XML 代码
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cl_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<android.support.design.widget.AppBarLayout
android:id="@+id/ab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="190dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="@android:color/white"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:id="@+id/iv_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/ic_home_screen_background"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.5"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="7dp"
android:theme="@style/ToolbarTheme"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/sr_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="-6dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_results"
android:clipToPadding="false"
android:scrollbars="vertical"
android:scrollbarThumbVertical="@color/orange_juice_80"
android:scrollbarSize="2dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape_rounded_top_grey"
android:fitsSystemWindows="true" />
</android.support.v4.widget.SwipeRefreshLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab_add"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginEnd="15dp"
app:backgroundTint="@color/dark_background"
app:layout_anchor="@id/rv_results"
app:layout_anchorGravity="top|right|end"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:srcCompat="@drawable/ic_vector_plus_white" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:descendantFocusability="blocksDescendants"
android:layout_height="wrap_content"
android:scrollbars="none" />
在嵌套的 recyclerview 中使用
android:descendantFocusability="blocksDescendants"
属性
嵌套 RecyclerView 的问题是无法正确检测手指滑动的正确斜率。
这里是一段代码,实际计算了正确的fling斜率https://github.com/minarja1/NestedRecyclerSample/blob/developv2/app/src/main/java/com/example/nestedrecyclersample/utils/ViewExtensions .kt
将类添加到代码库后,您可以使用 Kotlin 扩展调用该函数。
fun RecyclerView.enforceSingleScrollDirection() {
val enforcer = SingleScrollDirectionEnforcer()
addOnItemTouchListener(enforcer)
addOnScrollListener(enforcer)
}
有点晚了,但想分享一下,以便将来有人遇到此问题。
如果您在 UI 中使用 XML 专门的 ConstraintLayout -> 然后将RelativeLayout 用于特定的recyclerview 子级。 在RelativeLayout中编写recyclerview(androidx.recyclerview.widget.RecyclerView)。它使用相对布局平滑滚动。
您不需要任何额外的标签或属性 例如:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<androidx.core.widget.NestedScrollView
android:fillViewport="true"
android:id="@+id/nestedView"
android:layout_height="match_parent"
android:layout_marginTop="40dp"
android:layout_width="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
.
.
.
<RelativeLayout
android:id="@+id/rvPasser1"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:layout_constraintTop_toBottomOf="@+id/llPassingFromMenuA">
<androidx.recyclerview.widget.RecyclerView
android:background="@drawable/list_box"
android:id="@+id/rv"
android:layout_height="wrap_content"
android:layout_width="match_parent" />
</RelativeLayout>
.
.
.
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
您在这一行禁用了 RecyclerView 的嵌套滚动
rvUserEvents.setNestedScrollingEnabled(false);
您需要将此行替换为下面的内容才能正常滚动
ViewCompat.setNestedScrollingEnabled(rvUserEvents,true);
recyclerView.setNestedScrollingEnabled(false);