【发布时间】:2022-06-10 22:52:12
【问题描述】:
我有一个ListAdapter 和我的recyclerView,每个元素都可以全屏显示自己的详细信息。
在详细信息屏幕中,我有一个删除选项。这会更新我的DB 中的一个表,我正在使用Flow 检索信息,并将该流转换为viewModel 中的livedata。
当recyclerview 尝试更新列表时,已删除的项目不会显示(如预期的那样),但它也会在元素之间留下空白。我不知道如何删除那个空白。
我可以拖放带有右上角图标的项目,重新排列后,适配器重新计算每个viewholder的大小/位置,空白消失。
此外,加载相同的 fragment 可以解决此问题。
最后,我尝试在this 回答之后从ListAdapter 移动到RecyclerView.Adapter,但空白仍然存在。
欢迎提出任何建议。
这里有一些代码sn-ps:
override fun onCreateView(){
.....
_binding = FragmentBaseTrackedBinding.inflate(layoutInflater, container, false)
.apply {
lifecycleOwner = viewLifecycleOwner
list.adapter = trackedItemAdapter
.....
trackedViewModel.listResults.observe(viewLifecycleOwner) { trackedItems ->
trackedItemAdapter?.submitList(trackedItems)
}
class TrackedViewModel(....){
val listResults = trackedItemsRepository.getItems()
.asLiveData(Dispatchers.Default + viewModelScope.coroutineContext)
}
class TrackedItemsRepository(....){
fun getItems(): Flow<List<TrackedInfo>> {
return trackedItemsDao.getItemsDao().map{ it ->
TrackedInfo(.....)
}
}
@Dao
interface TrackedItemsDao {
@Query("SELECT ........")
fun getItemsDao(): Flow<List<TrackedItemsDao>>
class ItemDiffCallback : DiffUtil.ItemCallback<BaseTrackedInfo>() {
override fun areItemsTheSame(oldItem: BaseTrackedInfo, newItem: BaseTrackedInfo): Boolean =
oldItem.keyName == newItem.keyName
override fun areContentsTheSame(oldItem: BaseTrackedInfo, newItem: BaseTrackedInfo): Boolean =
oldItem == newItem
}
适配器代码
class TrackedItemAdapter @AssistedInject constructor(
@Assisted("onItemSelected") private val onItemSelected: (keyName: String) -> Unit,
) : ListAdapter<BaseTrackedInfo, BaseTrackedItemViewHolder>(ItemDiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackItemViewHolder =
TrackItemViewHolder(
ItemTrackedBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
), .....
)
}
override fun onBindViewHolder(holder: BaseTrackedItemViewHolder, position: Int) {
val item = getItem(position)
if (item != null) {
holder.bind(item)
holder.dragIcon.setOnTouchListener { _, _ ->
itemTouchHelper.startDrag(holder)
return@setOnTouchListener true
}
}
}
viewholders 代码
class TrackCharacterItemViewHolder(
private val binding: ItemCharacterTrackedBinding,
onItemSelected: (keyName: String) -> Unit
) : BaseTrackedItemViewHolder(binding.root) {
override var dragIcon: ImageView = binding.dragIcon
init {
binding.setClickListener {
with(binding) {
item?.let {
onItemSelected.invoke(it.keyName)
}
root.hideKeyboard()
}
}
}
override fun bind(itemTracked: BaseTrackedInfo) {
binding.apply {
item = itemTracked as TrackedInfo
executePendingBindings()
}
}
xml
<?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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/searchList"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/item_character_tracked" />
<include
android:id="@+id/loadingError"
layout="@layout/loading_error"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
【问题讨论】:
-
你能发布回收站视图适配器的代码和项目的 XML 布局吗?
标签: android kotlin android-recyclerview listadapter