簡體   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