解决了
RV - 回收站视图
我在警报对话框中有一个 RV。RV 适配器使用 DiffUtil.ItemCallback 扩展 ListAdapter。适配器列表每 500 毫秒使用倒数计时器更新一次(检查列表项是否已下载)。
问题是,列表已更新并使用新数据提交给适配器,但列表项视图并未根据提供的新数据进行更新,如下所示。我正在使用数据/视图绑定来更新列表项视图。
RV 有时会在滚动时更新项目视图。
PS:RV 是 NestedScrollView 的孩子
适配器代码
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!!)
}
}
}
}
列表项查看代码
<?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>
绑定适配器函数
@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
}
}