【问题标题】:Can not scroll recyclerview无法滚动回收站视图
【发布时间】:2019-06-02 17:39:47
【问题描述】:

我正在尝试实现 Recyclerview,但无法使其可滚动。我在 StackOverflow 中阅读了几个线程,但我找不到一个来解决我的问题。我认为这与 MapView 相关,因为我有另一个类似的活动,但没有可以滚动的地图,但在这种情况下我仍然不知道如何解决。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"
  tools:context=".activities.BookmarkActivity">

  <com.google.android.gms.maps.MapView android:id="@+id/bk_mapView" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintHeight_default="percent" app:layout_constraintHeight_percent="0.4" android:layout_marginTop="0dp" app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" />

  <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/bk_linearlayout" android:visibility="visible" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/bk_mapView">

    <TextView android:id="@+id/radlabel" android:layout_width="wrap_content" android:layout_height="25dp" android:layout_marginStart="4dp" android:layout_marginTop="2dp" android:layout_marginBottom="8dp" android:hint="@string/bk_radiusName" android:textAlignment="center"
      android:textSize="15sp" android:textStyle="bold" app:layout_constraintBottom_toTopOf="@+id/bk_textName" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />

    <SeekBar android:id="@+id/bk_seekBar" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:layout_marginEnd="8dp" android:max="1000" android:min="10" android:progress="50" app:layout_constraintEnd_toStartOf="@+id/bk_imageButton"
      app:layout_constraintHorizontal_weight="1" app:layout_constraintStart_toEndOf="@+id/radlabel" app:layout_constraintTop_toTopOf="parent" />


    <ImageButton android:id="@+id/bk_imageButton" android:layout_width="25dp" android:layout_height="25dp" android:layout_marginEnd="8dp" android:background="@android:drawable/ic_input_add" app:layout_constraintEnd_toEndOf="parent" />

    <EditText android:id="@+id/bk_textName" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="2dp" android:layout_marginTop="4dp" android:layout_marginEnd="8dp" android:hint="@string/bk_bookmarkName" android:inputType="textCapWords"
      android:maxLength="30" android:textSize="15sp" app:layout_constraintEnd_toStartOf="@+id/bk_notify" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/bk_seekBar" />

    <CheckBox android:id="@+id/bk_notifyWifiOnly" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="WifiOnly" android:visibility="gone" android:layout_marginTop="4dp" android:layout_marginEnd="4dp" android:layout_marginBottom="2dp"
      app:layout_constraintBottom_toBottomOf="@+id/bk_textName" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/bk_seekBar" />

    <CheckBox android:id="@+id/bk_notify" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Notify" android:layout_marginTop="4dp" android:layout_marginEnd="4dp" android:layout_marginBottom="2dp" app:layout_constraintBottom_toBottomOf="@+id/bk_textName"
      app:layout_constraintEnd_toStartOf="@+id/bk_notifyWifiOnly" app:layout_constraintTop_toBottomOf="@+id/bk_seekBar" />

  </androidx.constraintlayout.widget.ConstraintLayout>


  <FrameLayout android:id="@+id/emptyFrameLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="2dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:visibility="invisible"
    app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/bk_linearlayout">

    <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginStart="2dp" android:layout_marginTop="4dp" android:textAlignment="center" android:layout_marginBottom="150dp" android:textSize="20sp" android:textStyle="bold|italic"
      android:text="None Here" app:layout_constraintTop_toTopOf="parent" />

  </FrameLayout>


  <FrameLayout android:id="@+id/topFrameLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:layout_marginEnd="2dp" android:visibility="visible" app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/bk_linearlayout">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/bk_swipeRefreshLayout" android:layout_width="match_parent" android:layout_height="wrap_content">

      <androidx.recyclerview.widget.RecyclerView android:id="@+id/bk_recycler_view" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="vertical" />

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

  </FrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

实际布局截图在这里:

【问题讨论】:

    标签: android android-recyclerview scroll


    【解决方案1】:

    将您的RecyclerView 放入ScrollViewSwipeRefreshLayout 扩展 ViewGroup 并用于允许用户通过垂直滑动手势刷新/更新视图的内容。因此,它可以检测用户做出的垂直滑动手势,但它本身的内外行为并不像滚动视图。

    您的代码应该按照以下几行进行转换:

    <FrameLayout
            android:id="@+id/topFrameLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:layout_marginEnd="2dp"
            android:visibility="visible"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/bk_linearlayout">
    
            <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
                android:id="@+id/bk_swipeRefreshLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                <ScrollView
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                    <androidx.recyclerview.widget.RecyclerView
                        android:id="@+id/bk_recycler_view"
                        app:layout_behavior="@string/appbar_scrolling_view_behavior"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:scrollbars="vertical" />
    
                </ScrollView>
    
            </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
    
        </FrameLayout>
    

    要了解如何使用SwipeRefreshLayout,请参阅此article。另外,请参阅official documentation

    关于 SwipeRefreshLayout 的总结(来自官方文档)

    只要用户可以通过垂直滑动手势刷新视图的内容,就应该使用 SwipeRefreshLayout。实例化此视图的活动应添加一个 OnRefreshListener,以便在完成滑动刷新手势时收到通知。 SwipeRefreshLayout 会在每次手势再次完成时通知监听器;侦听器负责正确确定何时实际启动其内容的刷新。如果侦听器确定不应该有刷新,它必须调用 setRefreshing(false) 来取消任何刷新的视觉指示。如果一个活动希望只显示进度动画,它应该调用 setRefreshing(true)。要禁用手势和进度动画,请在视图上调用 setEnabled(false)。

    此布局应作为将因手势刷新的视图的父级,并且只能支持一个直接子级。此视图也将成为手势的目标,并将强制匹配此布局中提供的宽度和高度。 SwipeRefreshLayout 不提供可访问性事件;相反,必须提供一个菜单项以允许在使用此手势时刷新内容。

    【讨论】:

    • 我试过了,tks!但不幸的是,它没有奏效。也尝试使用 NestedScrollView ,但还是不行。