繁体   English   中英

删除 Android ViewPager2 中的项目

[英]Delete Item in Android ViewPager2

我正在将我的代码从使用androidx.viewpager更新为androidx.viewpager2 我正在翻阅数量不确定的片段,这些片段显示从数据库中检索到的数据记录。 加载视图寻呼机并通过我的数据进行分页效果很好,但我在删除项目和更新寻呼机适配器时遇到了一些麻烦。 我想通过在我的适配器上调用removeItem()方法(参见下面的代码)来删除任何给定 position 的项目。 那应该从我的数据库以及我的片段中删除该项目,然后更新视图。

结果是从数据库中删除了正确的项目。 但它不会从我的视图寻呼机中删除预期的片段,而是从下一页中删除。 当前页面仍然可见。 我将 position 偏移了正负 1 但没有成功 - 相反:在这些情况下,我的删除例程按最初预期执行。 我也尝试过类似的考虑,例如这里给出的。

我想实现以下行为:

  1. 删除任何项目时,应删除该页面并显示列表中的下一个项目。
  2. 当删除列表中的最后一个/最右边的项目时,应该删除该页面并显示前一个(现在是最后一个)页面。
  3. 当删除最后一个剩余项目(一个都没有)时,活动应该完成。

我的适配器代码:

internal class ShapePagerAdapter(private val activity: AppCompatActivity) : FragmentStateAdapter(activity) {
    private val dbManager: DatabaseManager
    private var shapeIds: MutableList<String>? = null

    init {
        dbManager = DatabaseManager(activity)
        try {
            shapeIds = dbManager.getShapeIds()
        } catch (e: DatabaseAccessException) {
            // ...
        }
    }

    override fun getItemCount(): Int {
        return if (null != shapeIds) shapeIds!!.size else 0
    }

    override fun createFragment(position: Int): Fragment {
        return ShapeFragment.newInstance(shapeIds!![position])
    }

    fun removeItem(activity: AppCompatActivity, position: Int) {
        try {
            // Remove from Database.
            dbManager.deleteShape(shapeIds!![position])
            // Remove from View Pager.
            shapeIds!!.removeAt(position)
            notifyItemRemoved(position)
            notifyItemRangeChanged(position , itemCount)
            // Close if nothing to show anymore.
            if (itemCount == 0) {
                activity.finish()
            }
        } catch (e: DatabaseAccessException) {
            // ...
        }
    }
}

FragmentStateAdapter的进一步研究表明,在这种情况下必须重写它的两个方法:

containsItem(long itemId)getItemId(int position)

默认实现适用于不添加、移动、删除项目的 collections。

通过搜索,我找到了类似问题的答案,为我指明了正确的方向。 它不会产生我的问题中给出的确切行为,这就是为什么我要发布一个稍微改编的版本。

关键是这两种方法是在项目序列可能发生变化的情况下实施的。 为了实现这一点,我维护了一个 map 的项目和项目 ID,并在序列发生变化时进行更新,在本例中是删除的项目。

internal class ShapePagerAdapter(private val activity: AppCompatActivity) : FragmentStateAdapter(activity) {
    private val dbManager: DatabaseManager
    private lateinit var shapeIds: MutableList<String>
    private lateinit var itemIds: List<Long>

    init {
        dbManager = DatabaseManager(activity)
        try {
            shapeIds = dbManager.getShapeIds()
            updateItemIds()
        } catch (e: DatabaseAccessException) {
            // ...
        }
    }

    override fun getItemCount(): Int = shapeIds.size

    override fun createFragment(position: Int): Fragment = ShapeFragment.newInstance(shapeIds[position])

    fun removeItem(activity: AppCompatActivity, position: Int) {
        try {
            dbManager.deleteShape(shapeIds[position])
            shapeIds.removeAt(position)
            notifyItemRemoved(position)
            notifyItemRangeChanged(position , itemCount)
            updateItemIds()
            if (itemCount == 0) activity.finish()
        } catch (e: DatabaseAccessException) {
            // ...
        }
    }

    private fun updateItemIds() {
        itemIds = shapeIds.map { it.hashCode().toLong() }
    }

    override fun getItemId(position: Int): Long = shapeIds[position].hashCode().toLong()

    override fun containsItem(itemId: Long): Boolean = itemIds.contains(itemId)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM