代码之家  ›  专栏  ›  技术社区  ›  Bmuig

更改数据时,RecyclerView.ListAdapter崩溃

  •  0
  • Bmuig  · 技术社区  · 7 年前

    RecyclerView.ListAdapter 试试这个能不能用在生产上。

    我的计划是在加载列表项时显示一个占位符(骨架)项,然后在客户机收到数据后切换到普通的项目列表。我处理这件事的方式 适配器 是我给 (这样我就知道数据还没有加载)。

    第一部分工作得很好 启动并显示框架项,但一旦加载“真实”列表,应用程序就会崩溃。坠机的原因是 适配器 直接转到 不打电话 onCreateViewHolder()

    到目前为止,我还没有弄清楚它为什么会跳过 onCreateViewHolder() 第一个项目的一部分,直接进入绑定。我查了一下 ,但这两个项目(框架项目和“真实”项目)明显不同。 (这里有一个简短的旁注:出于某种原因,两个 扩散 函数永远不会触发。。我不确定这是否也是问题的一部分,或者这只是一个 安卓工作室 问题。)

    重要的主要类别:

    class VIPSimilarAdsAdapter(context: Context, presenterInterface: BaseVIPContract.MVPAdapterPresenter) : ListAdapter<Ad, AdViewHolderFactory.AdBaseViewHolder>(SimilarAdsDiffCallback()) {
    
        private val presenterInterface: WeakReference<BaseVIPContract.MVPAdapterPresenter> = WeakReference(presenterInterface)
        private var showLoadingInidicator = true
    
        override fun submitList(list: List<Ad>?) {
            showLoadingInidicator = list == null
            super.submitList(list)
        }
    
        override fun getItemCount(): Int {
            return when (showLoadingInidicator) {
                true -> 1
                else -> super.getItemCount()
            }
        }
    
        override fun onBindViewHolder(@NonNull holder: AdViewHolderFactory.AdBaseViewHolder, position: Int) {
            if (!showLoadingInidicator) {
                getItem(position)?.let { safeAd ->
                    CommonViewBinder.bindCommonFields(holder as AdViewHolderFactory.AdViewHolder, safeAd)
                    AdViewBinder.bindAdFields(holder, safeAd)
                    holder.itemView.setOnClickListener {
                        presenterInterface.get()?.onUserEventSimilarAdClicked(safeAd, position)
                    }
                }
            }
        }
    
        @NonNull
        override fun onCreateViewHolder(@NonNull parent: ViewGroup, viewType: Int): AdViewHolderFactory.AdBaseViewHolder {
            return (when (showLoadingInidicator) {
                true -> AdViewHolderFactory.SkeletonViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.grid_item_skeleton, parent, false), ITEM_VIEW_TYPE_SKELETON)
                else -> AdViewHolderFactory.AdViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.grid_item_ad_basic, parent, false))
            })
        }
    }
    

    DiffUtil回调

    class SimilarAdsDiffCallback : DiffUtil.ItemCallback<Ad>() {
        override fun areItemsTheSame(oldItem: Ad, newItem: Ad): Boolean {
            return oldItem == newItem
        }
    
        override fun areContentsTheSame(oldItem: Ad, newItem: Ad): Boolean {
            return oldItem.id == newItem.id
        }
    }
    

    这个 适配器 只是用

    adAdapterSimilarAds.submitList(null)
    

    adAdapterSimilarAds.submitList(list)
    

    一旦我们加载了数据。


    编辑: 这是坠机的痕迹

    java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{4e5bcfd position=6 id=-1, oldPos=0, pLpos:0 scrap [attachedScrap] tmpDetached no parent} androidx.recyclerview.widget.RecyclerView{3d89e2f VFED..... ......ID 0,1953-1080,2289 #7f090302 app:id/similar_ads_after_pos_1}, adapter:ebk.vip.similar_ads.VIPSimilarAdsAdapter@ac7dc3c, layout:androidx.recyclerview.widget.GridLayoutManager@e9b3dc5, context:ebk.vip.vip_core.VIPActivity@ecfbcc3
            at androidx.recyclerview.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5715)
            at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5898)
            at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
            at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
            at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
            at androidx.recyclerview.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:557)
            at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
            at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612)
            at androidx.recyclerview.widget.GridLayoutManager.onLayoutChildren(GridLayoutManager.java:171)
            at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3875)
            at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3330)
            at android.view.View.measure(View.java:19857)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
            at android.view.View.measure(View.java:19857)
            at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
            at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
            at android.view.View.measure(View.java:19857)
            at androidx.core.widget.NestedScrollView.measureChildWithMargins(NestedScrollView.java:1502)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
            at androidx.core.widget.NestedScrollView.onMeasure(NestedScrollView.java:556)
            at android.view.View.measure(View.java:19857)
            at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
            at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
            at android.view.View.measure(View.java:19857)
            at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
            at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
            at android.view.View.measure(View.java:19857)
            at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
            at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
            at android.view.View.measure(View.java:19857)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
            at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
            at android.view.View.measure(View.java:19857)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
            at android.view.View.measure(View.java:19857)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
            at android.view.View.measure(View.java:19857)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
    
    0 回复  |  直到 7 年前