【问题标题】:Blank space between elements with listAdapter/recyclerview.adapter when removing an item删除项目时带有 listAdapter/recyclerview.adapter 的元素之间的空格
【发布时间】: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


猜你喜欢
  • 1970-01-01
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
相关资源
最近更新 更多