簡體   English   中英

ViewPager 列表刷新無法正常工作

[英]ViewPager list refresh is not working properly

我有自定義ViewPagerPagerAdapter ,它們在instantiateItem中加載項目。 如果我第一次使用設置的項目列表初始化它,它工作正常。

但是當我在列表上調用刷新並且我想用新的(完全不同的)列表填充適配器時,在調用viewPager.adapter?.notifyDataSetChanged()之后,PagerAdapter 停止正常工作並且這些項目是沒有內容的空白頁面,我可以刷過它們在 UI 中。

PageScreen不是Fragment 它只是ViewGroup容器,它正在膨脹布局並從特定項目中設置值。 它類似於RecyclerView中的ViewHolder + Binder

當我添加新列表並調用notifyDataSetChanged()時,也只調用一次instatiateItem() () 。 開始時它被稱為 3 個項目,即第一個列表中的PageScreen項目的數量。

//init
val pages = mutableListOf<PageScreen>()
pages.add(PageScreen(activity, app, itemJs1, onClick = {onItemClicked(itemJs1.id)}))
pages.add(PageScreen(activity, app, itemJs2, onClick = {onItemClicked(itemJs2.id)}))
pages.add(PageScreen(activity, app, itemJs3, onClick = {onItemClicked(itemJs3.id)}))

swipePager.adapter = CustomPagerAdapter(pages).also { it.notifyDataSetChanged() }

...

//on refresh after API call
pages.clear()

contentList.forEach{item-> pages.add(PageScreen(activity, app, item, onClick = {onItemClicked(item.id)}))}

(swipePager.adapter as? CustomPagerAdapter)?.notifyDataSetChanged()

也試過這個(同樣的結果):

//on refresh after API call

val newPages = mutableListOf<PageScreen>()

contentList.forEach{item-> newPages.add(PageScreen(activity, app, item, onClick = {onItemClicked(item.id)}))}

swipePager.adapter = CustomPagerAdapter(newPages).also { it.notifyDataSetChanged() }

適配器:

class CustomPagerAdapter(private var pageList: MutableList<PageScreen>) : PagerAdapter() {
    override fun isViewFromObject(view: View, `object`: Any): Boolean {
        return view == `object`
    }

    override fun getCount(): Int {
        return pageList.size
    }

    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
        container.removeView(`object` as View)
    }

    override fun instantiateItem(container: ViewGroup, position: Int): View {
        val layout = pageList[position].getScreen(container)
        container.addView(layout)
        return layout
    }
}

我還嘗試通過從 ViewPager contentView 中刪除它們並為每個項目調用instantiateItem()來正確刷新項目(我希望這是由 PagerAdapter 和 ViewPager 在我調用notifyDataSetChanged()時在內部完成的)。 但是結果和上面一樣。 現在每一頁都是空白的。 下面的 Function 添加到CustomPagerAdapter

fun refreshItems(vp: ViewPager, data: MutableList<PageScreen>){
        pageList.apply {
            forEachIndexed{pos, item->
                item.screenView?.let { sv->
                    destroyItem(vp, pos, sv)
                }
            }
            clear()
            addAll(data)
            forEachIndexed { pos, _ -> instantiateItem(vp, pos) }
        }
        notifyDataSetChanged()
    }

更新:我設法通過將 ViewPager 高度設置為固定值而不是WRAP_CONTENT來“解決”這個問題,但這不是解決方案。 我想要具有動態高度的 ViewPager,因為它的一些子項可以有不同的高度 + 設置 static 在 Android 中不是好方法。 一些帶有方形顯示屏的手機可能會裁剪頁面。

發生的事情是當我替換所有項目時,那些“空白”頁面是具有 0px 高度和 0px 寬度的項目,原因不明。

如果我將 ViewPager 高度替換為 dp 值,它“有效”。 但是當我替換那些視圖時,第一項總是空白。 但是當我滾動到第三個並返回到第一個時,項目出於某種原因在那里。

我也沒有得到那個高度的問題。 我在 ViewPager 中有 function ,它根據列表中最高的孩子設置其高度。 如果列表是 static,它可以工作,但是當我刷新它時它現在不起作用。

重新創建整個ViewPagerAdapter是解決此問題的方法。

我在onPageSelected()中調用了 API 並記得 position 返回到監聽器 function。

然后我像這樣重新創建了整個適配器:

swipePager.apply {
   adapter = null
   adapter = CustomPagerAdapter(newPages)
   adapter?.notifyDataSetChanged()
   invalidate()
}

刷新后,我滾動到記住 position ,如下所示:

setCurrentItem(position, true)

此解決方案不會留下空白頁,但我必須為我的ViewPager設置 static 高度,這可能是mdpi屏幕上的問題,有時無法從XML布局正確重繪特定的dp值。 有這個問題的手機是Sony Xperia E5 ,它有xhdpi屏幕,我的ViewPager的一部分是從底部裁剪的。

這必須使用單獨的dimens.xml手動調整mdpixhdpi

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM