Recyclerview 项目在再次获取数据时增加高度 Android Kotlin

Posted

技术标签:

【中文标题】Recyclerview 项目在再次获取数据时增加高度 Android Kotlin【英文标题】:Recyclerview item increase height when fetch data again Android Kotlin 【发布时间】:2021-12-24 05:48:11 【问题描述】:

我有 recyerlView。我从服务器加载数据。当它最初加载时,它的高度是正常的,但是当我通过项目单击进入下一个活动时。回来慢慢增加孩子的身高。我尝试对此进行调试,发现 onResume api 调用导致了问题。但是我在布局上做错了什么我不明白。

FirstLayout.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"
    android:layout_
    android:layout_>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/reyclerview"
        android:layout_
        android:layout_
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

FirstActivity.kt

class FirstActivity : BaseActivity() 

    lateinit var binding: FirstLayoutActivityLayoutBinding
    private val viewModel: FirstViewModel by inject()
    private var listAdapter: ListAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setupViewModel()
        binding = FirstLayoutActivityLayoutBinding.inflate(layoutInflater)
        setContentView(binding.root)
    

    private fun setupViewModel() 
        viewModel.livedata.observe(this,  list ->
            setupAdapter(list)
        )
    

    private fun setupAdapter(list: List<String>) 
        initializeAdapter(list)
        listAdapter?.updateItemsList(list)
        binding.recyclerView.apply 
            addItemDecoration(HeaderItemDecoration(context))
             val itemDecorator = DividerItemDecoration(context, DividerItemDecoration.VERTICAL)
        itemDecorator.setDrawable(ContextCompat.getDrawable(context, R.drawable.divider)!!)
        addItemDecoration(itemDecorator)
            adapter = listAdapter
        
    

    private fun initializeAdapter(list: List<String>) 
        listAdapter = ListAdapter(list.toMutableList())
    

    override fun onResume() 
        super.onResume()
        viewModel.fetchItem() // noraml retrofit call
    

HeaderItemDecoration 是从这个answer 使用的。

ListAdapter.kt

class ListAdapter(private val list: MutableList<String>) : RecyclerView.Adapter<Adapter.MyViewHolder>() 

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder 
        return MyViewHolder(
            ListLayoutBinding.inflate(
                LayoutInflater.from(parent.context),
                parent,
                false
            )
        )
    

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) 
        holder.bindItem(list[position])
    

    override fun getItemCount(): Int 
        return list.size
    

    inner class MyViewHolder(private val binding: ListLayoutBinding) : RecyclerView.ViewHolder(binding.root) 

        fun bindItem(s: String) 
            binding.cool.text = s
        
    

ListLayout.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"
    android:id="@+id/root"
    android:background="@color/red"
    android:layout_
    android:layout_>

    <TextView
        android:id="@+id/cool"
        android:layout_
        android:layout_
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

我正在将我的观点添加到我的Youtube Link。请看看是什么问题。谢谢

我没有添加任何逻辑来增加高度

【问题讨论】:

【参考方案1】:

看起来有多个ItemDecorations 的问题,每次获取新数据时都会设置它们。确切地说:多个DividerItemDecorations,它为项目添加了小填充(用于划分它们)。注意方法名称以add... 开头,所以每次你添加新的,旧的都留在那里,并且这个分隔符的每个实例都添加了一些填充。如果你会实施例如每次例如在后台拉到刷新或自动刷新10 秒后,每次刷新 GUI 方法调用 (setupAdapter) 都会增加一些空间而不会离开 Activity。目前您只在onResume 中获取数据一次,因此每个 move-activity-to-foreground 操作都会添加一个分隔符(当数据将被正确获取时)

将这部分代码移动到onCreate,以便仅设置一次分隔符,这是通过代码进行一些额外样式设置的合适位置

binding.recyclerView.apply 
        addItemDecoration(HeaderItemDecoration(context))
        val itemDecorator = DividerItemDecoration(context, DividerItemDecoration.VERTICAL)
        itemDecorator.setDrawable(ContextCompat.getDrawable(context, R.drawable.divider)!!)
        addItemDecoration(itemDecorator)

在您的 setupAdapter 方法中,仅将适配器设置为 RecyclerView,不要设置它的样式(多次)

private fun setupAdapter(list: List<String>) 
    initializeAdapter(list)
    listAdapter?.updateItemsList(list)
    binding.recyclerView.adapter = listAdapter

【讨论】:

很好的答案。谢谢一百万

以上是关于Recyclerview 项目在再次获取数据时增加高度 Android Kotlin的主要内容,如果未能解决你的问题,请参考以下文章

更改微调器项目数据时更新recyclerview单行数据

滚动 NestedScrollView 时如何获取 recyclerview 的当前项目位置?

Android RecyclerView上拉加载更多item点击事件(显示获取的数据)

第一次在 recyclerview 上显示获取数据,但第二次打开 recyclerview 不显示数据

在 RecyclerView 中滚动时不可见的项目变得可见

在Android recyclerVIew中单击项目时如何保存状态