如何在RecyclerView中仅刷新列表的一部分

时间:2019-06-15 10:38:54

标签: android android-layout android-recyclerview

我有一个复杂的RecyclerView,我正在使用5 ViewHolders的适配器。我创建了类似于“联系人列表”的自定义部分。但是在我的recyclerView中,一个区域中的项目可以重置其他区域中的所有内容。但是我不知道该怎么做。

我现在正在做的是擦除整个适配器列表并再次添加项,但这不是有效的方法。 Section 1中的项目还包含CheckBox,如果选中,则可以清除Section 2Section 3中的所有数据。

OnCheckedChangeListener内设置

CheckBox并从itemList[pos]状态设置onBindViewHolder状态(在绑定开始时检查部分内部的默认选中项目)。如果选中,则将刷新整个列表并调用notifyDataSetChanged之所以这样做,是因为不同部分中的所有其他项目都是基于第一部分中的选中项。

这是由于concurrent modification exception而导致崩溃的原因。每次在onBindViewHolder内将这些项目之一再次绑定时,都会触发检查更改侦听器并刷新整个列表。如果连续两次或更多次调用,它将使我的应用程序崩溃。 同样,如果用户将上下滚动并且Section1项目开始重新出现和消失,它将在一行中多次调用onBindViewHolder =>多次调用notifyDataSetChanged()=>异常。

Android RecyclerView确实缺乏对版块的本地支持。仅在开始时像subArrays一样设置节,然后调用adapter.updateSection(1)这样的做法真的很酷。

如果我可以为每个部分分别创建RecyclerView,这也更好,但是整个RecyclerView必须是可滚动的。在RecyclerViews中添加4个NestedScrollView将终止回收机制。

用于刷新项目的代码预览:

val selectedVariantFirstSectionJSONObject = getSelectedVariantInJSON(selectedVariantID)
        ingredientsItemList.apply {
            clear()
            add(IngredientHeaderItemNonIconified(getString(R.string.food_ingredients_variant_label)))
            addAll(foodVariantsArray)
            add(IngredientSectionSeparator())
            add(IngredientHeaderItemNonIconified(getString(R.string.food_ingredients_required_ingredients_label)))
            add(RequiredIngredient(getVariantRequiredIngredients(selectedVariantJSONObject.getJSONArray(getString(R.string.food_variant_required_ingredients)))))
            add(IngredientSectionSeparator())
            add(IngredientHeaderItemIconified(getString(R.string.food_ingredients_remove_ingredients_label), TYPE_INGREDIENT_REM))
            addAll(removableIngredients)
            add(IngredientSectionSeparator())
            add(IngredientHeaderItemIconified(getString(R.string.food_ingredients_add_ingredients_label), TYPE_INGREDIENT_OPT))
            addAll(optionalIngredients)
        }

adapter.notifyDataSetChanged()

便于理解的图像(有点复杂):

enter image description here

2 个答案:

答案 0 :(得分:1)

您可以简单地致电RvAdapter.notifyItemRangeChanged(start,count); 如果您有

,那么对于子适配器也是一样

答案 1 :(得分:0)

如果您有修改过的物品位置,只需传递这些位置, 在具有修改数据位置的列表循环中运行以下方法。

 public void updateItem(Data Data, int position) {
        mDataList.add(position, data);
        notifyItemChanged(position);
    }