Improve performance of recycler views and prevent flickering on state change.

This commit is contained in:
Antoine POPINEAU 2020-07-11 18:15:40 +02:00
parent 7d95618ff5
commit 308e7d7567
No known key found for this signature in database
GPG Key ID: A78AC64694F84063
5 changed files with 20 additions and 6 deletions

View File

@ -20,6 +20,8 @@ class AlbumsAdapter(val context: Context?, private val listener: OnAlbumClickLis
fun onClick(view: View?, album: Album) fun onClick(view: View?, album: Album)
} }
override fun getItemId(position: Int): Long = data[position].id.toLong()
override fun getItemCount() = data.size override fun getItemCount() = data.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

View File

@ -19,6 +19,8 @@ class AlbumsGridAdapter(val context: Context?, private val listener: OnAlbumClic
fun onClick(view: View?, album: Album) fun onClick(view: View?, album: Album)
} }
override fun getItemId(position: Int): Long = data[position].id.toLong()
override fun getItemCount() = data.size override fun getItemCount() = data.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

View File

@ -57,9 +57,13 @@ class RadiosAdapter(val context: Context?, val scope: CoroutineScope, private va
} }
} }
override fun getItemCount() = instanceRadios.size + data.size + 2 override fun getItemId(position: Int) = when (getItemViewType(position)) {
RowType.InstanceRadio.ordinal -> (-position - 1).toLong()
RowType.Header.ordinal -> Long.MIN_VALUE
else -> getRadioAt(position).id.toLong()
}
override fun getItemId(position: Int) = data[position].id.toLong() override fun getItemCount() = instanceRadios.size + data.size + 2
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int): Int {
return when { return when {

View File

@ -25,11 +25,9 @@ class TracksAdapter(private val context: Context?, private val favoriteListener:
var currentTrack: Track? = null var currentTrack: Track? = null
override fun getItemCount() = data.size override fun getItemId(position: Int): Long = data[position].id.toLong()
override fun getItemId(position: Int): Long { override fun getItemCount() = data.size
return data[position].id.toLong()
}
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) { override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView) super.onAttachedToRecyclerView(recyclerView)

View File

@ -8,6 +8,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
import com.github.apognu.otter.repositories.HttpUpstream import com.github.apognu.otter.repositories.HttpUpstream
import com.github.apognu.otter.repositories.Repository import com.github.apognu.otter.repositories.Repository
import com.github.apognu.otter.utils.* import com.github.apognu.otter.utils.*
@ -22,6 +23,12 @@ import kotlinx.coroutines.withContext
abstract class OtterAdapter<D, VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>() { abstract class OtterAdapter<D, VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>() {
var data: MutableList<D> = mutableListOf() var data: MutableList<D> = mutableListOf()
init {
super.setHasStableIds(true)
}
abstract override fun getItemId(position: Int): Long
} }
abstract class OtterFragment<D : Any, A : OtterAdapter<D, *>> : Fragment() { abstract class OtterFragment<D : Any, A : OtterAdapter<D, *>> : Fragment() {
@ -46,6 +53,7 @@ abstract class OtterFragment<D : Any, A : OtterAdapter<D, *>> : Fragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
recycler.layoutManager = layoutManager recycler.layoutManager = layoutManager
(recycler.itemAnimator as? SimpleItemAnimator)?.supportsChangeAnimations = false
recycler.adapter = adapter recycler.adapter = adapter
(repository.upstream as? HttpUpstream<*, *>)?.let { upstream -> (repository.upstream as? HttpUpstream<*, *>)?.let { upstream ->