kotlin Android FlexboxLayoutManager正在重新创建项目

yrefmtwq  于 2023-02-19  发布在  Kotlin
关注(0)|答案(3)|浏览(236)

我正在使用FlexboxLayoutManager来显示动态宽度的Recycler View项目。我面临的问题是,当项目的背景发生变化时,它会重新动画/重新绘制所有不太吸引人/不需要的后续项目。

下面的屏幕截图展示了这个用例。当一行中有两个或更多不同宽度的项目时,选择/取消选择视图将重新创建下一个邻居。
我的代码为这个:

val managerVal = FlexboxLayoutManager(context, FlexDirection.ROW)
// I have used these properties as well with other combinations showing here for reference
//            managerVal.alignItems = AlignItems.FLEX_START
//            managerVal.justifyContent = JustifyContent.CENTER
            itemView.rvFilterOptions.layoutManager = managerVal
val filterOptionAdapter = FilterOptionAdapter(
                context,
                record.values
            )
itemView.rvFilterOptions.adapter = filterOptionAdapter

我还尝试过更改Adapter中的值

val lp = itemView.llFilterValue.getLayoutParams()
            if (lp is FlexboxLayoutManager.LayoutParams) {
               lp.flexGrow = 1.0f
               flexboxLp.flexShrink = 1f
               lp.alignSelf = AlignItems.FLEX_START

            }

更改适配器中项的背景的代码。

if (record.isSelected) {
                itemView.tvFilterValue.setTextColor(
                    AppCompatResources.getColorStateList(
                        context,
                        R.color.textWhite
                    )
                )
                itemView.ivFilterCheck.show()
                itemView.llFilterValue.background =
                    AppCompatResources.getDrawable(
                        context,
                        R.drawable.bg_dark_rectangle_circle_edge
                    )
            } else {
                itemView.tvFilterValue.setTextColor(
                    AppCompatResources.getColorStateList(
                        context,
                        R.color.textNormal
                    )
                )
                itemView.ivFilterCheck.invisible()
                itemView.llFilterValue.background =
                    AppCompatResources.getDrawable(
                        context,
                        R.drawable.bg_gray_rectangle_circle_edge
                    )
            }

显示行为的gif:

谢谢你抽出时间。

vcirk6k6

vcirk6k61#

所以修复程序最终保存在我的XML文件中。

*原因:*当您使用具有flex-directionwrap的flexbox时,您允许flexbox库处理视图大小。由于我的用例位于嵌套的回收器视图中,我的回收器视图项目之一使用match_parent属性,这导致在运行时在视图中调整冲突(这在库级别造成混乱)。
解决方案是简单地将wrap_content与flexbox一起使用,让库决定视图测量。

ctehm74n

ctehm74n2#

我遇到了同样的问题,我想是因为我在onBindViewHolder函数中通过DataBinding设置xml布局文件中的变量,导致布局文件中的TextView被重新创建,这似乎导致布局管理器重新计算视图是否应该换行,即使文本没有改变。
所以我想在不调用普通bind函数的情况下更新视图,我通过使用notifyItemChanged和一个有效负载来解决这个问题,每当我想将一个项目标记为选中时,例如:

notifyItemChanged(position: Int, payload: Any?)

因为你要发送一个有效载荷,你需要覆盖

onBindViewHolder(holder: MyViewHolder, position: Int, payloads: MutableList<Any>)

需要注意的是,此函数是RecyclerView始终调用的函数,因此如果您没有有效载荷,则需要调用超级函数或常规onBindViewHolder,例如:

override fun onBindViewHolder(holder: MyViewHolder, position: Int, payloads: MutableList<Any>) {
    if (payloads.isEmpty()) return super.onBindViewHolder(holder, position, payloads)
    // I know that I called notifyItemChanged with a Boolean as payload to set the selected state.
    holder.updateSelectedState(payloads.firstOrNull() as? Boolean ?: false)
}

然后在updateSelectedState中,我只是更新背景或imageview,而不是项目(或者,可能是任何可能扰乱布局宽度的内容)。

9udxz4iz

9udxz4iz3#

我也遇到过类似的问题。通过在我的回收器视图中添加setHasFixedSize(true)来修复它。

相关问题