无法滚动到 NestedScrollView 内的 RecyclerView 中的项目

Posted

技术标签:

【中文标题】无法滚动到 NestedScrollView 内的 RecyclerView 中的项目【英文标题】:Unable to scroll to item in RecyclerView that is inside NestedScrollView 【发布时间】:2021-12-10 08:45:11 【问题描述】:

我正在尝试以编程方式滚动到嵌套在 NestedScrollView 中的 RecyclerView 中的特定项目。

问题

NestedScrollView 滚动到完整的底部,而不是所需的项目。 注意:当所需项目是第二个项目时,它可以正常工作,可能是因为该项目在屏幕上可见。

我尝试过的

我从 *** 搜索了十几个解决方案,并提出了以下功能。 我试过了:

binding.variantsRecyclerView.getChildAt() binding.variantsRecyclerView.findViewWithTag() binding.variantsRecyclerView.findViewHolderForAdapterPosition()

所有这些都返回正确的项目,(我知道,因为该项目中的编辑文本以编码为焦点)但是,NestedScrollView 无法正确滚动到该项目。它几乎总是滚动到底部。但是,有时它会滚动到所需项目之间的某个位置,而不是开始。唯一有效的情况是该项目是第 1 项或第 2 项。 (如前所述)

private fun scrollToPosition(position: Int) 
        if (position in 0 until variantsAdapter.itemCount) 
            val view = binding.variantsRecyclerView.findViewWithTag<ConstraintLayout>("pos_$position")
            if (view != null) 
                val height = binding.nestedScrollView.height
                val target = view.y.toInt()
                binding.nestedScrollView.postDelayed(
                    binding.nestedScrollView.smoothScrollTo(0, target)
                    view.requestFocus()
                , 200)
            
        
    

我的 XML

<?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_
    android:layout_
    android:background="#eff1f4">


    <LinearLayout>...</LinearLayout>

    <androidx.core.widget.NestedScrollView
        android:id="@+id/nestedScrollView"
        android:layout_
        android:layout_
        android:fillViewport="true"
        app:layout_constrainedHeight="true"
        app:layout_constraintVertical_bias="0"
        app:layout_constraintBottom_toTopOf="@+id/btnNextLayout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/toolbarLayout">

        <LinearLayout
            android:layout_
            android:layout_
            android:layout_marginStart="@dimen/ui_10_dp"
            android:layout_marginEnd="@dimen/ui_10_dp"
            android:orientation="vertical">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/variantsRecyclerView"
                android:layout_
                android:layout_
                android:clipToPadding="false"
                android:nestedScrollingEnabled="false"
                android:paddingTop="12dp"
                android:paddingBottom="12dp"
                app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
                tools:itemCount="2"
                tools:listitem="@layout/sell_variant_row_item" />

            <androidx.constraintlayout.widget.ConstraintLayout>
             ...
            </androidx.constraintlayout.widget.ConstraintLayout>

        </LinearLayout>

    </androidx.core.widget.NestedScrollView>

    <LinearLayout>...</LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

我的理解

调试后发现 NestedScrollView 的高度小于所需项的 y 坐标。因此它滚动到视图的底部而不是所需的项目。我的理解可能完全错误,如果是,请纠正我。

【问题讨论】:

【参考方案1】:

我用一个非常简单的方法解决了这个问题。

private fun scrollToPosition(position: Int) 
    if (position in 0 until variantsAdapter.itemCount) 
        val view = binding.variantsRecyclerView.getChildAt(position)
        if (view != null) 
            val target = binding.variantsRecyclerView.top + view.top
            binding.nestedScrollView.scrollY = target 
        
    

我想要的只是将 RecyclerView 中的所需项目放到屏幕顶部。

【讨论】:

以上是关于无法滚动到 NestedScrollView 内的 RecyclerView 中的项目的主要内容,如果未能解决你的问题,请参考以下文章

SwipeRefreshLayout 内的 NestedScrollView 内的 RecyclerView 不能平滑滚动

NestedScrollview 内的 RecyclerView 滚动不顺畅

NestedScrollView 内的回收器视图导致滚动从中间开始

ConstraintLayout 内的 NestedScrollView 不可滚动

NestedScrollView 内的 RecyclerView :使水平滚动更容易

NestedScrollView 内的 RecyclerView ScrollListener