Android:RecyclerView里面的RecyclerView,滚动到底部

Posted

技术标签:

【中文标题】Android:RecyclerView里面的RecyclerView,滚动到底部【英文标题】:Android: RecyclerView inside RecyclerView, scroll to bottom 【发布时间】:2021-03-28 08:59:25 【问题描述】:

这是我的情况:

说明

我有一个RecyclerView,我们称之为parent

它有两个项目:

    静态视图,具有静态高度等 另一辆房车,我们称之为child房车

屏幕某处有一个添加项目按钮。单击此按钮会在子 RV 中添加一个新项目。

基本上,父 RV 将始终只有 2 个项目,即顶部的静态视图和子 RV。

子 RV 将具有动态数量的项目(取决于您单击添加按钮的次数)。

现在,当我单击 添加项目 按钮时,我会更新我的 dataset 并在父级中调用 notifyDataSetChanged() 以显示添加的新项目。我需要在父 RV 中调用它,因为静态容器(父 RV 的第一项)内有视图,它们受 添加新项目操作的影响。

我想要实现的是,在调用notifyDataSetChanged() 之后,我希望整个视图滚动到最底部。

我已经尝试了所有选项:

    smoothScrollToPosition scrollToPosition stackFromEnd = true

等等...但没有任何效果。

你知道如何强制父 RV 在notifyDataSetChanged() 之后滚动到其内容的底部吗?

【问题讨论】:

【参考方案1】:

您可以只使用具有两种不同视图类型的RecyclerView,第一种是您的静态视图。

我假设您的数据集由通用 Item 对象填充,请将此值替换为您的数据集对象类型。

我认为问题与将回收器视图嵌套到另一个视图中滚动方法无法正常工作有关。

我将在 Kotlin 中发布我的代码,如果您需要它的 Java 版本,请告诉我。

这是要使用的回收器视图适配器:

    // Global variables
    private var itemList = mutableListOf<Item>()

    enum class ViewType 
        STATIC_VIEW,
        ITEM_VIEW
    

    inner class RecyclerViewAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() 

        override fun getItemCount(): Int = itemList.size + 1

        override fun getItemViewType(position: Int): Int 
            if (position == 0) 
                return ViewType.STATIC_VIEW.ordinal
            

            return RowMenuType.ITEM_VIEW.ordinal
        

        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) 
            if (getItemViewType(position) == RowMenuType.STATIC_VIEW.ordinal) 
                (holder as ViewHolderStaticView).bind()
             else 
                (holder as ViewHolderItemList).bind(itemList[position - 1])
            
        

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder 
            if (viewType == RowMenuType.STATIC_VIEW.ordinal) 
                val view = layoutInflater.inflate(<your-static-view-layout>, parent, false)
                return ViewHolderStaticView(view)
            

            val view = layoutInflater.inflate(<your-item-list-layout>, parent, false)
            return ViewHolderItemList(view)
        

        inner class ViewHolderStaticView(itemView: View) : RecyclerView.ViewHolder(itemView) 
            fun bind() = with(itemView) 
                // Setup your static view layout
            
        

        inner class ViewHolderItemList(itemView: View) : RecyclerView.ViewHolder(itemView) 
            fun bind(item: Item) = with(itemView) 
                // Setup your list items
            
        

设置您的回收站视图调用:

    parent_recycler_view.layoutManager = LinearLayoutManager(this)
    parent_recycler_view.adapter = RecyclerViewAdapter()

要添加新元素,您需要调用:

    itemList.add(Item())
    parent_recycler_view.adapter.notifyDataSetChanged()

你应该可以通过调用滚动到回收器视图的底部:

    parent_recycler_view.smoothScrollToPosition(itemList.size)

【讨论】:

【参考方案2】:

我遇到过一个与这个非常相似的案例。虽然@Luca's answer 是最佳的,但是如果不可能有一个RecyclerView,就像我的情况一样,我找到的解决方案是requestFocus() 在孩子RecyclerView 的最后一项。

我在 child recyclerview 的项目中有一个 EditText,我所做的是:

inner class ChildRVViewHolderItemList(itemView: View) : RecyclerView.ViewHolder(itemView) 
    fun bind(item: Item) = with(itemView) 
        if (isLastItemToShow) 
          itemView.mEditText.requestFocus()
        
    

这样,只要满足isLastItemToShow 条件,位于我的子recyclerview 的最后一项内的EditText 就会获得焦点,并最终使RecyclerView 滚动到底部。

【讨论】:

以上是关于Android:RecyclerView里面的RecyclerView,滚动到底部的主要内容,如果未能解决你的问题,请参考以下文章

翻译Android RecyclerView CardView

Android RecyclerView 基本使用

android RecyclerView的Grid布局案例

Android Kotlin - 用于 RecyclerView 的 setOnTouchListener 和所有项目子视图/里面的所有内容

android 浅析RecyclerView回收复用机制及实战(仿探探效果)

Android TV端的(RecyclerView)水平滚动焦点错乱问题