Home > Back-end >  Recyclerview item increase height when fetch data again Android Kotlin
Recyclerview item increase height when fetch data again Android Kotlin

Time:11-12

I have recyerlView. I loaded data from the server. When it initially loads it height is normal, but when I go to the next activity through item click. And come back it slowly increasing the height of the child. I tried to debug this and found that onResume api call causing the issue. But What I am doing wrong in layout I don't get it.

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_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@ id/reyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        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 is used from this enter image description here

CodePudding user response:

looks like a problem with multiple ItemDecorations, which are set every time new data is fetched. to be exact: multiple DividerItemDecorations, which adds small padding to the items (for dividing them). note methods name starts with add..., so every time you are adding new, old stays there and every instance of this divider is adding some padding. if you would implement e.g. pull-to-refresh or auto-refresh in background every e.g. 10 secs then every refresh GUI method call (setupAdapter) would add some space without leaving Activity. currently you are fetching data only once, in onResume, so every move-activity-to-foreground action will add one divider (when data will be fetched properly)

move this part of code to onCreate for setting dividers only once, thats proper place for some additional styling by code

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

and inside your setupAdapter method set only adapter to RecyclerView, don't style it (multiple times)

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