【问题标题】:Update Parent Adapter in Nested Adapters?在嵌套适配器中更新父适配器?
【发布时间】:2021-02-17 23:52:13
【问题描述】:

我有两个 RecyclerViews 的嵌套适配器,如下所示:
父适配器:

public class ParentAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public static ArrayList<ParentItem> parentItemList;

    private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();

    private com.example.todotestapp.ChildAdapter childAdapter;

    public ParentAdapter(ArrayList<ParentItem> parentItemList) {
        this.parentItemList = parentItemList;
    }

    public class ParentViewHolder extends RecyclerView.ViewHolder {

        private RecyclerView childRecyclerView;
        public ParentViewHolder(final View parentView) {
            super(parentView);

            childRecyclerView = parentView.findViewById(R.id.child_recyclerview);
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        View parentView = inflater.inflate(R.layout.parent_layout, parent, false);
        return new ParentViewHolder(parentView);
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {

        final ParentItem someParentItem = parentItemList.get(position);

        ArrayList<ChildItem> childItemList = someParentItem.getChildItemList();
        RecyclerView childRecyclerView = ((ParentViewHolder) holder).childRecyclerView;
        LinearLayoutManager layoutManager = new LinearLayoutManager(childRecyclerView.getContext());
        layoutManager.setInitialPrefetchItemCount(childItemList.size());
        childAdapter = new com.example.todotestapp.ChildAdapter(childItemList);
        childRecyclerView.setLayoutManager(layoutManager);
        childRecyclerView.setAdapter(childAdapter);
        childRecyclerView.setRecycledViewPool(viewPool);

    }

    @Override
    public int getItemCount() {return parentItemList.size(); }
}

子适配器:

public class ChildAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private ArrayList<ChildItem> childItemList;

    public ChildAdapter(ArrayList<ChildItem> childItemList) {
        this.childItemList = childItemList;
    }

    public class ChildViewHolder extends RecyclerView.ViewHolder {
        CheckBox childCheckBox;

        public ChildViewHolder(final View childView) {
            super(childView);

            childCheckBox = childView.findViewById(R.id.child_checkbox);
            childCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    ChildItem checkedChildItem = childItemList.get(getAdapterPosition());

                    ParentItem parentItemOfCheckedChildItem = checkedChildItem.getParentItem();
                    int parentAdapterPos = ParentAdapter.parentItemList.indexOf(parentItemOfCheckedChildItem);
                    int mainPos = MainActivity.mainParentItemList.indexOf(parentItemOfCheckedChildItem);
                    ArrayList<ChildItem> aChildItemList = parentItemOfCheckedChildItem.getChildItemList();
                    aChildItemList.remove(checkedChildItem);
                    childItemList.remove(checkedChildItem);
                    parentItemOfCheckedChildItem.setChildItemList(aChildItemList);
                    ParentAdapter.parentItemList.set(parentAdapterPos, parentItemOfCheckedChildItem);
                    MainActivity.mainParentItemList.set(mainPos, parentItemOfCheckedChildItem);

                    MainActivity.mainChildItemList.remove(checkedChildItem);
                    checkedChildItem.setIsChecked(true);
                    MainActivity.mainChildItemList.add(checkedChildItem);

                    ParentItem checkedParentItem = ParentAdapter.parentItemList.get(ParentAdapter.parentItemList.size() - 1);
                    checkedParentItem.addToChildItemList(checkedChildItem);
                    ParentAdapter.parentItemList.set(ParentAdapter.parentItemList.size() - 1, checkedParentItem);

                    notifyDataSetChanged();
                }
            });
        }
    }
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        View childView = inflater.inflate(R.layout.child_layout, parent, false);
        return new ChildViewHolder(childView);
    }
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        final ChildItem aChildItem = childItemList.get(position);
    }

    @Override
    public int getItemCount() {return childItemList.size();}
}

我知道 ChildAdapter 非常混乱,但我在处理数据时遇到了麻烦。我想从当前的 ParentItem 中删除 checkedChildItem,将其添加到新的 ParentItem,然后刷新数据。我当前的代码执行前两个步骤(从原始 ParentItem 的 childItemList 中删除 ChildItem 并将其添加到新的 ParentItem 中),但仅在活动刷新后显示数据。
我已经尝试在“updateDataAfterChecked”方法中将数据传递给 ParentAdapter,但我仍然无法更新它,因为 ChildItemViewHolder 是静态上下文并且 notifyDataSetChanged() 不是,所以我似乎无法找到一种方法更新 ParentAdapter 而不转到其他活动并再次返回。有什么建议吗?
- - - - - - - - - - - - - - - - - - 编辑 - - - - - - - ---------------------------
我能够通过将 LiveData 用于 ParentItemList 来访问 .notifyDataSetChanged(),但是在刷新页面之前,ChildItem 仍然不会出现在第二个 ParentItem 中(如果我调用 finish() 然后调用 startActivity(getIntent()),一切按预期工作,除非这会导致我不喜欢的不和谐效果)。有什么建议可以帮助解决这个问题吗?谢谢。
- - - - - - - - - - - - - - - - - - 编辑 - - - - - - - ---------------------------
我的目标是类似于 Google Tasks 应用程序 (android) 所做的事情——如果您检查一个项目,它会从其日期中删除并实时添加到“已完成”;我不知道这些信息是否对答案有帮助,但我认为值得一提。

【问题讨论】:

    标签: java android android-recyclerview nestedrecyclerview


    【解决方案1】:

    您应该使用 Sectioned-RecyclerView 而不是 RecyclerView。

    参考以下代码: https://github.com/IntruderShanky/Sectioned-RecyclerView

    希望以上链接对您有所帮助。

    【讨论】:

    • 不要粗鲁,但该适配器最后一次更新是在四年前...如果您查看源代码...这不是最有效的实现(notifyDataSetChanged 创建一个新列表,对其进行转换并然后传递通知只是为了命名一件事,所有这些都发生在主线程上)。
    • 我同意你的评论;我更多的是寻找一种方法来在我现有的代码中实现一些东西。必须实现一个全新的库并(基本上)重新创建应用程序并不一定是理想的。
    【解决方案2】:

    使用 ViewModels 和 MutableLiveData 解决了这个问题。
    在 MainActivity 中:

    public class MainActivity extends AppCompatActivity implements LifecycleOwner {
        public static ChildViewModel childViewModel;
        public static ArrayList<ChildItem> childAdapterData;
        private ParentAdapter parentAdapter;
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ...
            setViewModel();
            // Populate childAdapterData in setAdapter()
            setAdapter();
            setRecyclerView();
            updateViewModel();
        }
        ...
        public static void updateViewModel() {
            childViewModel.getChildItemLiveData().setValue(childAdapterData);
        }
    
        public void setViewModel() {
            childViewModel = new ViewModelProvider(this).get(ChildViewModel.class);
            final Observer<ArrayList<ChildItem>> observer = new Observer<ArrayList<ChildItem>>() {
                @Override
                public void onChanged(ArrayList<ChildItem> childItems) {
                    // Do things
                    // Don't have to do notifyDataSetChanged--also notifyItemRangeChanged(), etc.
                    parentAdapter.notifyDataSetChanged();
                }
            };
            childViewModel.getChildItemLiveData().setValue(childAdapterData);
            childViewModel.getChildItemLiveData().observe(this, observer);
        }
    }
    
    


    在 ChildAdapter 中:

    public class ChildAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
        private ArrayList<ChildItem> childItemList;
    
        public ChildAdapter(ArrayList<ChildItem> childItemList) {
            this.childItemList = childItemList;
        }
    
        public class ChildViewHolder extends RecyclerView.ViewHolder {
            CheckBox childCheckBox;
    
            public ChildViewHolder(final View childView) {
                super(childView);
    
                childCheckBox = childView.findViewById(R.id.child_checkbox);
                childCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        ChildItem checkedChildItem = childItemList.get(getAdapterPosition());
                        // Remove from ParentItem A
                        ...
                        // Add to ParentItem B
                        ...
                        MainActivity.childAdapterData.set(parentItemAPosition, parentItemA);
                        MainActivity.childAdapterData.set(parentItemBPosition, parentItemB);
                        MainActivity.updateViewModel();
                    }
                });
            }
        }
    ...
    
    }
    


    最后是 ViewModel

    public class ChildViewModel extends ViewModel {
        public MutableLiveData<ArrayList<ChildItem>> childItemLiveData;
    
        public MutableLiveData<ArrayList<ChildItem>> getChildItemLiveData() {
            if(childItemLiveData == null) {
                childItemLiveData = new MutableLiveData<>();
            }
            return childItemLiveData;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多