RV - recycler view
I have an RV inside an alertdialog. Adapter for the RV extends ListAdapter with DiffUtil.ItemCallback. List for the adapter is being updated every 500ms using countdowntimer (checking whether the list item is downloaded or not).
The problem is, the list is updated and submitted to the adapter with the new data and but the list item view is not updating based on new data provided as shown below. I'm using data/view binding for updating the list item view.
The RV sometimes updates the item view when being scrolled.
PS: The RV is a child of NestedScrollView
This is how it is working right now
Adapter code
class AlarmSongsAdapter(
private val onItemClicked: (AlarmSongItem) -> Unit,
private val startDownloading: (String) -> Unit,
private val insertDownloadEntityInDB: (DownloadEntity) -> Unit
) : ListAdapter<AlarmSongItem, AlarmSongsAdapter.AlarmSongsViewHolder>(DiffUtilCallback) {
object DiffUtilCallback : DiffUtil.ItemCallback<AlarmSongItem>() {
override fun areItemsTheSame(oldItem: AlarmSongItem, newItem: AlarmSongItem): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: AlarmSongItem, newItem: AlarmSongItem): Boolean {
return oldItem == newItem
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlarmSongsViewHolder {
return AlarmSongsViewHolder(AlarmsSongListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false), onItemClicked, startDownloading, insertDownloadEntityInDB)
}
override fun onBindViewHolder(holder: AlarmSongsViewHolder, position: Int) {
holder.bind(getItem(position))
}
class AlarmSongsViewHolder(
private val binding: AlarmsSongListItemBinding,
private val onItemClicked: (AlarmSongItem) -> Unit,
private val startDownloading: (String) -> Unit,
private val insertDownloadEntityInDB: (DownloadEntity) -> Unit
) : RecyclerView.ViewHolder(binding.root) {
fun bind(alarmSongItem: AlarmSongItem) {
binding.alarmSongItem = alarmSongItem
binding.executePendingBindings()
}
init {
binding.downloadButton.setOnClickListener {
val alarmSongItem = binding.alarmSongItem!!
when(alarmSongItem.downloadState){
Download.STATE_STOPPED -> {
startDownloading(alarmSongItem.audioFile)
val storageInfo = StorageUtils.currentStorageTypeAndPath(binding.root.context)
insertDownloadEntityInDB(alarmSongItem.toDownloadEntity(storageInfo))
}
else -> {}
}
}
binding.root.setOnClickListener {
onItemClicked(binding.alarmSongItem!!)
}
}
}
}
List item view code
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="alarmSongItem"
type="com.baja.app.domain.models.AlarmSongItem" />
</data>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:cardElevation="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<androidx.cardview.widget.CardView
android:id="@+id/song_item_thumbnail_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardBackgroundColor="@android:color/transparent"
app:cardCornerRadius="6dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/song_item_thumbnail"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerVertical="true"
android:scaleType="centerCrop"
app:srcCompat="@drawable/bg_default_light"
tools:ignore="ContentDescription"
app:thumbnailFromUri="@{alarmSongItem.thumbnail}" />
</androidx.cardview.widget.CardView>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="60dp"
android:id="@+id/download_progress_container"
android:layout_alignParentRight="true"
android:layout_centerVertical="true">
<ImageView
android:id="@+id/download_bg"
android:layout_width="32dp"
android:layout_height="32dp"
android:scaleType="centerCrop"
app:srcCompat="?bg_default_circular"
tools:ignore="ContentDescription"
android:layout_centerInParent="true" />
<com.google.android.material.button.MaterialButton
android:id="@+id/download_button"
style="@style/AppTheme.OutlinedButton.Icon"
android:layout_width="32dp"
android:layout_height="32dp"
app:cornerRadius="32dp"
app:icon="@drawable/ic_download"
app:iconTint="@android:color/white"
changeIcon="@{alarmSongItem.downloadState}"
android:layout_centerInParent="true" />
<com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/download_progress_bar"
style="@style/Widget.MaterialComponents.ProgressIndicator.Circular.Indeterminate"
android:layout_width="33dp"
android:layout_height="33dp"
app:circularRadius="17dp"
app:indicatorColor="?attr/progressIndicatorColor"
app:indicatorWidth="1dp"
showProgressBar="@{alarmSongItem.downloadState}"
android:layout_centerInParent="true"
android:visibility="gone" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginStart="20dp"
android:layout_toEndOf="@id/song_item_thumbnail_container"
android:orientation="vertical"
android:weightSum="2"
android:layout_toStartOf="@id/download_progress_container"
android:layout_marginEnd="8dp">
<TextView
android:id="@+id/song_item_name"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="bottom"
android:maxLines="1"
android:textSize="16sp"
android:textStyle="bold"
tools:text="Sa re ga ma pa"
android:text="@{alarmSongItem.title}" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="@+id/song_item_artist"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="4dp"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxWidth="150dp"
android:maxLines="1"
android:textSize="14sp"
tools:text="Sidharth Arun"
android:text="@{alarmSongItem.artist}" />
<View
android:layout_width="5dp"
android:layout_height="5dp"
android:layout_gravity="center_vertical"
android:background="@drawable/dot" />
<TextView
android:id="@+id/song_item_duration"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="4dp"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
tools:text="10:12"
app:formatDuration="@{alarmSongItem.duration}" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
Binding Adapter functions
@BindingAdapter("thumbnailFromUri")
fun thumbnailFromUri(view: ImageView, uri: String) {
Glide.with(view).load(uri).placeholder(R.drawable.bg_default_light).error(R.drawable.bg_default_light).into(view)
}
@BindingAdapter("changeIcon")
fun changeIconBasedOnDownloadState(view: MaterialButton, state: Int) {
when (state) {
Download.STATE_COMPLETED -> view.setIconResource(R.drawable.ic_check)
else -> view.setIconResource(R.drawable.ic_download)
}
}
@BindingAdapter("showProgressBar")
fun showProgressbarBasedOnState(view: ProgressIndicator, state: Int) {
when (state) {
Download.STATE_QUEUED,
Download.STATE_RESTARTING,
Download.STATE_DOWNLOADING -> view.visibility = View.VISIBLE
else -> view.visibility = View.GONE
}
}
from RecyclerView list item view not updating (using DiffUtil.ItemCallback)
No comments:
Post a Comment