首页 > 解决方案 > 刷新适配器时回收器视图项相互重叠

问题描述

我有一个嵌套的recyclerview,父recyclerview 有不同类型的内部水平滚动recyclerviews。如添加的图片

在此处输入图像描述

问题在于 Trending now 内部 recyclerview,这个 recyclerview 的项目有所有这些卡片很长很短,我正在根据告诉我要显示哪张卡片的响应更改 onBindView 中的可见性,

这工作得很好,但是每当我刷新我的主适配器时,现在趋势部分就会像这样扭曲

在此处输入图像描述

如果我再次刷新适配器,它会恢复到原来的形状,我无法在这里找到问题所在。

代码打击:

所以我的json响应是这样的,我有小部件列表,我们有不同类型的小部件来显示不同类型的内部recyclerview,即使这些小部件的高度宽度来自api响应,

"results": [
  {
    "id": 1,
    "widget_type_id": 1,
    "widget_type": "FixSizeCard",
    "widget_left_margin": 20,
    "widget_right_margin": 20,
    "card_items": [
      {
        "web_url": "",
        "screen_id": 39,
        "web_title": "",
        "card_image": "url here",
        "is_clickable": true,
        "card_sequence": 110
      },
      { },
      { }
    ]
    },
 {
    "id": 3,
    "widget_type_id": 3,
    "widget_type": "MIX CARD",
    "widget_left_margin": 20,
    "widget_right_margin": 20,
    "widget_sequence": 300,
    "heading": "Trending now",
    "mix_card_items": [
      {
        "items": [
          {
            "web_url": "",
            "location": "top",
            "position": "left",
            "card_type": "long",
            "screen_id": 10,
            "web_title": "Discover",
            "card_h_max": 832,
            "card_image": "url here",
            "card_w_max": 616,
            "is_clickable": true,
            "screen_w_percent": 0.4278,
            "width": 462,
            "height": 624
          }
        ],
        "card_sequence": 1
      },
      {
        "items": [
          {
            "web_url": "",
            "location": "top",
            "position": "left",
            "card_type": "short",
            "screen_id": 6,
            "web_title": "Traffic cop",
            "card_h_max": 380,
            "card_image": "",
            "card_w_max": 616,
            "is_clickable": true,
            "screen_w_percent": 0.4278,
            "width": 462,
            "height": 285
          },
          {
            "icon": "",
            "title": "Petrol",
            "web_url": "",
            "location": "bottom",
            "position": "left",
            "subtitle": "(Udham Singh Nagar)",
            "card_type": "fix",
            "screen_id": 19,
            "top_title": "₹97.76",
            "web_title": "",
            "card_h_max": 380,
            "card_w_max": 616,
            "is_clickable": true,
            "top_subtitle": "0.02",
            "screen_w_percent": 0.4278,
            "card_top_bg_color": "#36BA3C",
            "width": 462,
            "height": 285
          },
          {
            "icon": "",
            "title": "Diesel",
            "web_url": "",
            "location": "bottom",
            "position": "right",
            "subtitle": "(Udham Singh Nagar)",
            "card_type": "fix",
            "screen_id": 19,
            "top_title": "₹90.29",
            "web_title": "",
            "card_h_max": 380,
            "card_w_max": 616,
            "is_clickable": true,
            "top_subtitle": "0.02",
            "screen_w_percent": 0.4278,
            "card_top_bg_color": "#36BA3C",
            "width": 462,
            "height": 285
          }
        ]
      }
    ]
  },

其他小部件很简单,只有混合卡(Trending now)小部件有点棘手

在 Trending now 我得到卡片的类型,比如长、短、非常短,在此基础上我需要显示内容/卡片

主外部适配器,我只添加相关代码 cz 它很多:

 homePageAdapter = object : GenericAdapter<HomePageResponseItem, RvHomePageParentItemBinding>(requireContext()) {
            override fun getLayoutResId(viewType: Int?): Int = R.layout.rv_home_page_parent_item

            override fun onBindData(
                model: HomePageResponseItem,
                position: Int,
                dataBinding: RvHomePageParentItemBinding
            ) {

                dataBinding.widgetHomePage.initHomeWidget(model, this@HomePageFragment)
            }

initHomePageMehotd

 fun initHomeWidget(model: HomePageResponseItem, listener: OnHomePageItemClickListener) {
   

    when (model.widgetTypeId) {

        FIXCARDS -> {
            setUpAdapter(model.cardItems, R.layout.rv_homepage_image_only_item)
        }
       
        MIXCARD -> {
            setUpAdapter(model.mixCardItems, R.layout.rv_item_home_page_trending_now)
        }

setUpAdapter() 函数:

private fun setUpAdapter(cardItems: List<Any>?, rvHomepageImageOnlyItem: Int) {
    val adapter = object : GenericAdapter<Any, Any>(context) {
        override fun getLayoutResId(viewType: Int?): Int = rvHomepageImageOnlyItem

        override fun onBindData(model: Any, position: Int, dataBinding: Any) {
            when (homePageResponseItem?.widgetTypeId) {
                3 -> {
                    //mix
                    val binding = (dataBinding as RvItemHomePageTrendingNowBinding)
                    val data = (model as MixCardItem)
                    handleInnerCardsVisibility(binding, data)
                }

**handleInnerCardsVisibility() 函数在某些地方处理混合卡片小部件的可见性我正在检查位置,因为短卡片可以在顶部或底部 **

private fun handleInnerCardsVisibility(
    binding: RvItemHomePageTrendingNowBinding,
    data: MixCardItem
) {

    binding.apply {
        setCardsDimensions(this)
        //only long card
        if (data.items?.get(0)?.cardType.equals("long")) {
            imgTypeLong.apply {
                makeVisible()
                setImageFromUrl(data.items?.get(0)?.cardImageUrl)
                layoutParams = ConstraintLayout.LayoutParams(
                    data.items!![0].innerCardWidth!!,
                    data.items!![0].innerCardHeight!!
                )
               
            imgTypeShortTop.makeGone()
            imgTypeShortBottom.makeGone()
            layoutFixVeryShortTop.makeGone()
            layoutFixVeryShortBottom.makeGone()


        } else {
            //short very short and fix cards with position
            imgTypeLong.makeGone()

            data.items?.let { smallCards ->

                for (innerCardData in smallCards) {

                    when (innerCardData.cardType?.toLowerCase(Locale.ROOT)) {
                        "short" -> {
                            if (innerCardData.location.equals("top")) {
                                Timber.d("HomePageWidget Short Card Top")
                                imgTypeShortTop.apply {
                                    makeVisible()
                                    val params = layoutParams as ConstraintLayout.LayoutParams
                                    params.apply {
                                        width = innerCardData.innerCardWidth!!
                                        height = innerCardData.innerCardHeight!!
                                    }
                                    layoutParams = params
                                    setImageFromUrl(innerCardData.cardImageUrl)
                                    
                                }
                            } else {
                                Timber.d("HomePageWidget Short Card Bottom")
                                imgTypeShortBottom.apply {
                                    makeVisible()
                                    val params = layoutParams as ConstraintLayout.LayoutParams
                                    params.apply {
                                        width = innerCardData.innerCardWidth!!
                                        height = innerCardData.innerCardHeight!!
                                    }
                                    layoutParams = params
                                    setImageFromUrl(innerCardData.cardImageUrl)
                                    
                            }
                        }

                        "fix" -> {
                            if (innerCardData.location.equals("top")) {
                                Timber.d("HomePageWidget fix Card top")
                                imgTypeShortTop.makeGone()
                                layoutFixVeryShortTop.apply {
                                    makeVisible()
                                    val params = layoutParams as ConstraintLayout.LayoutParams
                                    params.apply {
                                        width = innerCardData.innerCardWidth!!
                                        height = innerCardData.innerCardHeight!!
                                    }
                                    layoutParams = params
                                    if (innerCardData.position.equals("left")) {
                                        this.imgLeftImageOnly.makeGone()
                                        val bg = this.containerLeftBg.background
                                        val drawable = DrawableCompat.wrap(bg)
                                        DrawableCompat.setTint(
                                            drawable,
                                            Color.parseColor(innerCardData.cardTopBgColor)
                                        )
                                        this.containerLeftBg.background = drawable

                                        tv_item_title_left.text = innerCardData.title
                                        tv_price_left.text = innerCardData.topTitle
                                        tv_location_left.text = innerCardData.subtitle
                                        tv_price_change_left.text = innerCardData.topSubtitle
                                        tv_arrow_left.setImageFromUrl(innerCardData.icon)
                                    } else {
                                        this.imgRightImageOnly.makeGone()
                                        tv_item_title_right.text = innerCardData.title
                                        tv_price_right.text = innerCardData.topTitle
                                        tv_location_right.text = innerCardData.subtitle
                                        tv_price_change_right.text = innerCardData.topSubtitle
                                        tv_arrow_right.setImageFromUrl(innerCardData.icon)
                                    }
                                   
                                }
                            } else {
                                Timber.d("HomePageWidget fix Card bottom")
                                layoutFixVeryShortBottom.apply {
                                    imgTypeShortBottom.makeGone()
                                    makeVisible()
                                    val params = layoutParams as ConstraintLayout.LayoutParams
                                    params.apply {
                                        width = innerCardData.innerCardWidth!!
                                        height = innerCardData.innerCardHeight!!
                                    }
                                    layoutParams = params
                                    if (innerCardData.position.equals("left")) {
                                        this.imgLeftImageOnly.makeGone()
                                        val bg = this.containerLeftBg.background
                                        val drawable = DrawableCompat.wrap(bg)
                                        try {
                                            DrawableCompat.setTint(
                                                drawable,
                                                Color.parseColor(innerCardData.cardTopBgColor)
                                            )
                                        } catch (e: Exception) {
                                            DrawableCompat.setTint(
                                                drawable,
                                                Color.parseColor("#699FFD")
                                            )
                                            Timber.e("Home page error wrong color")
                                        }
                                        this.containerLeftBg.background = drawable

                                        tv_item_title_left.text = innerCardData.title
                                        tv_price_left.text = innerCardData.topTitle
                                        tv_location_left.text = innerCardData.subtitle
                                        tv_price_change_left.text = innerCardData.topSubtitle
                                        tv_arrow_left.setImageFromUrl(innerCardData.icon)
                                    } else {
                                        this.imgRightImageOnly.makeGone()
                                        val bg = this.containerRightBg.background
                                        val drawable = DrawableCompat.wrap(bg)
                                        try {
                                            DrawableCompat.setTint(
                                                drawable,
                                                Color.parseColor(innerCardData.cardTopBgColor)
                                            )
                                            this.containerRightBg.background = drawable
                                        } catch (e: Exception) {
                                            DrawableCompat.setTint(
                                                drawable,
                                                Color.parseColor("#699FFD")
                                            )
                                            Timber.e("Home page error wrong color")
                                        }


                                        tv_item_title_right.text = innerCardData.title
                                        tv_price_right.text = innerCardData.topTitle
                                        tv_location_right.text = innerCardData.subtitle
                                        tv_price_change_right.text = innerCardData.topSubtitle
                                        tv_arrow_right.setImageFromUrl(innerCardData.icon)
                                    }
                                    
                                }
                            }
                        }

                      
    }
}

设置维度方法()

 private fun setCardsDimensions(binding: Any) {
    when (binding) {
        is RvItemHomePageTrendingNowBinding -> {
            binding.apply {
                container.layoutParams = ConstraintLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT,
                    homePageResponseItem?.cardHeight!!
                )
                homePageResponseItem?.cardSpaceMargin?.let {
                    container.margin(left = it / 2, right = it / 2)
                }
            }
        }
  }

现在流行/混合类型卡片 xml 布局

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/container"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/img_type_long"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        app:srcCompat="@drawable/ic_placeholder"
        android:visibility="gone"
        tools:visibility="visible"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_height="208dp"
        tools:layout_width="150dp" />


    <androidx.appcompat.widget.AppCompatImageView

        android:visibility="visible"
        android:id="@+id/img_type_short_top"
        tools:layout_width="158dp"
        tools:layout_height="95dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        app:srcCompat="@drawable/ic_placeholder"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:background="@color/colorTextBlack" />

    <androidx.appcompat.widget.AppCompatImageView

        android:id="@+id/img_type_short_bottom"
        android:layout_width="158dp"
        android:layout_height="95dp"
        android:scaleType="fitXY"
        app:srcCompat="@drawable/ic_placeholder"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        tools:background="@color/colorTextBlack"
        tools:layout_height="95dp"
        tools:layout_width="158dp" />

    <include
        tools:visibility="visible"
        android:visibility="gone"
        android:id="@+id/layout_fix_very_short_bottom"
        layout="@layout/rv_item_home_page_fix_veryshort"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <include
        tools:visibility="gone"
        android:visibility="gone"
        android:id="@+id/layout_fix_very_short_top"
        layout="@layout/rv_item_home_page_fix_veryshort"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

标签: androidandroid-layoutandroid-fragmentsandroid-recyclerview

解决方案


推荐阅读