我有一个 CollapsingToolbar 和一个底部导航栏,如图所示:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:fitsSystemWindows="true"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintTop_toTopOf="parent">
<!-- Scrollable view here -->
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="@dimen/height335"
android:background="@drawable/ic_appbar_bg"
android:fitsSystemWindows="true"
app:elevation="0dp">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="@color/colorPrimaryDark"
app:toolbarId="@+id/toolbar"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/transparent"
android:contentInsetStart="0dp"
android:contentInsetLeft="0dp"
android:gravity="center"
app:contentInsetEnd="0dp"
app:contentInsetEndWithActions="0dp"
app:contentInsetLeft="0dp"
app:contentInsetRight="0dp"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="2dp"
app:layout_collapseMode="pin"
app:theme="@style/ToolbarTheme">
<include
android:id="@+id/toolbar_header_view"
layout="@layout/widget_header_view_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
bind:cardDetails="@{viewModel}" />
</androidx.appcompat.widget.Toolbar>
<include
layout="@layout/widget_header"
bind:cardDetails="@{viewModel}" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!-- just a nestedscrollview
override fun onTouchEvent(ev: MotionEvent): Boolean {
return scrollable && super.onTouchEvent(ev)
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
return scrollable && super.onInterceptTouchEvent(ev)
}
fun setScrollingEnabled(enabled: Boolean) {
scrollable = enabled
} -->
<com.android.utils.LockableNestedScrollView
android:id="@+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:clipChildren="false"
android:clipToPadding="false"
android:fillViewport="true">
<LinearLayout>
<Some views...
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:layout_width="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_height="match_parent" />
</LinearLayout>
</com.android.utils.LockableNestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->viewModel.fabClicked()}"
android:src="@drawable/ic_plus"
app:fabCustomSize="@dimen/fab70"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
android:elevation="@dimen/elevation3"
android:paddingTop="@dimen/padding10"
app:itemTextAppearanceActive="@style/BottomNavigationViewTextStyle"
app:itemTextAppearanceInactive="@style/BottomNavigationViewTextStyle"
app:labelVisibilityMode="labeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/nav_view" />
单击导航栏项目时,片段容器将替换为片段。问题是在其中一个片段中我有一个回收 View 。 recyclerview 中所有项目的 onBindView 都会同时被调用。我需要避免这种情况主要是因为我正在尝试像这样实现分页:
override fun onBindViewHolder(holder: TopUpViewHolder, position: Int) {
val item = myDataset[position]
holder.bind(item)
if (position == this.itemCount - 1){
// do your load more task here
viewModel.fetchTopUpData()
}
}
(我尝试附加滚动监听器并实现像 this 这样的分页。但是即使用户尚未到达末尾,canScrollVertically(1) 也会被调用,这可能是因为nestedscrollview本身。)
这是我的 recyclerview 片段:
<?xml version="1.0" encoding="utf-8"?>
<data>
<import type="android.view.View" />
<variable
name="viewmodel"
type="com.android.ui.topup.viewmodel.TopUpViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:padding="@dimen/padding15">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/status_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/padding20"
android:visibility="@{viewmodel.headerVisibility}">
<TextView
android:id="@+id/recentLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin20"
android:text="@string/recent_top_ups"
android:textAllCaps="true"
android:textColor="@color/topup_label_text_color"
android:textSize="@dimen/text12"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/viewAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin20"
android:onClick="@{()->viewmodel.viewAllClicked()}"
android:text="@string/view_all"
android:textColor="@color/topup_label_color_orenge"
android:textSize="@dimen/text14"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/topUpRCView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
android:clipChildren="false"
android:clipToPadding="false"
app:scrollListener="@{viewmodel.scrollListener}" />
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="@{viewmodel.fetchingFlag?View.VISIBLE:View.GONE}" />
</LinearLayout>
<LinearLayout
android:id="@+id/empty_list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{viewmodel.listEmpty}"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_illustration_receipt"/>
<TextView
android:id="@+id/empty_list_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/you_have_no_topup_requests"
android:fontFamily="@font/colfaxregular"
android:textColor="#333547"
android:layout_marginTop="36dp"
android:textSize="@dimen/text16"
android:alpha=".3"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
我尝试过的事情:
- 在 recyclerview 中添加了
android:nestedScrollingEnabled="false"
- 添加了
app:layout_behavior="@string/appbar_scrolling_view_behavior"
- 将 recyclerview 的高度更改为
match_parent
wrap_content
也为 0 并将布局权重设置为 1(RCV 位于线性布局内) - https://stackoverflow.com/a/44470106/6341943 => 由于某种原因添加标题 View
- https://stackoverflow.com/a/37558761/6341943 => 不能这样做,因为我有一个底部导航栏
现在是奇怪的部分 如果我将片段保留在 View 页面中,由于某种原因,问题不会发生。 (即使这个 hack 也不可用,因为它弄乱了我的 collpsingToolbarLayout)
最佳答案
我已经浪费了至少一周的时间,唯一有效的解决方案是删除 nestedscrollview
。要使 recyclerview 实际上回收 View ,您必须删除 nestedscrollview
。如果您碰巧有多个 view
而不仅仅是 recyclerview
,则必须通过设置不同的 viewholder 将它们添加为 recyclerview
的项目,然后添加
app:layout_behavior="@string/appbar_scrolling_view_behavior"
到recyclerview或recyclerview
的父级(父级不能有除Recyclerview之外的任何其他 View 才能正常工作)。
就我而言,要求如下:
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:fitsSystemWindows="true"
app:layout_constraintTop_toTopOf="parent">
<!-- Scrollable view here -->
<com.google.android.material.appbar.AppBarLayout
.... >
<com.google.android.material.appbar.CollapsingToolbarLayout
....>
<androidx.appcompat.widget.Toolbar
....>
<include
android:id="@+id/toolbar_header_view"
.... />
</androidx.appcompat.widget.Toolbar>
<include layout="@layout/widget_header" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
....>
<LinearLayout orientation="vertical" ....>
<View .../> <!-- I needed to have these two views along with recyclerview and i wanted them to do nestedscroll along with recyclerview -->
<View .../>
<androidx.recyclerview.widget.RecyclerView
.... />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
在recyclerview
之前我需要有两个 View ,并且我希望它们与recyclerview
一起进行nestedscroll。唯一有效的方法是将它们删除到 View 中并将它们添加为 recyclerview
的前两项,然后添加
app:layout_behavior="@string/appbar_scrolling_view_behavior"
到swipetorefresh
布局
希望这对某人有帮助。如果需要,我会添加更多信息。
关于android-fragments - nestedscrollview 内 RecyclerView 的 onBindViewHolder 立即为所有项目调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59169890/