首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌套回收视图的notifyDataSetChanged()不起作用

嵌套回收视图的notifyDataSetChanged()不起作用
EN

Stack Overflow用户
提问于 2021-01-17 18:11:16
回答 1查看 717关注 0票数 0

我正在实现一个Nested Recycler View

单击按钮时,将为每个项目动态添加nested recycler视图。

我已经实现了这个功能。但当您单击按钮添加项目时,

项目更新只有通过nested recyclerview's setAdapter()才有可能,

不是notifyDataSetChanged()

为什么会发生这种情况?为什么它没有用notifyDataSetChanged()更新

至少据我所知,setAdapter()只应该被调用一次。

如果多次调用setAdapter()是否重要?

我想要的是由notifyDataSetChanged()更新,而不是setAdapter()

但是项目是由setAdapter()更新的。

为什么?

RoutineModel.java

代码语言:javascript
复制
public class RoutineModel {
    String routine;
    public ArrayList<RoutineDetailModel> arrayListDetail;

    public RoutineModel(String routine) {
        this.routine = routine;
    }

    public String getRoutine() {
        return routine;
    }
}

RoutineAdapter.java (嵌套回收视图的适配器)

代码语言:javascript
复制
public class RoutineAdapter extends RecyclerView.Adapter<RoutineAdapter.ViewHolder> {
    ArrayList<RoutineModel> routineItems = new ArrayList<>();
    Context context;

    public void addItem(RoutineModel item) {
        routineItems.add(item);
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        View itemView =  inflater.inflate(R.layout.routine_item, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        RoutineModel curRoutineItem = routineItems.get(position);
        holder.setItems(curRoutineItem);

        // Set Routine Detail (Nested RecyclerView)
        holder.setRoutineDetailRecyClerView();
        RoutineDetailAdapter detailAdapter = new RoutineDetailAdapter();
        curRoutineItem.arrayListDetail = new ArrayList<>();
        curRoutineItem.arrayListDetail.add(new RoutineDetailModel());

        holder.routine_detail.setAdapter(detailAdapter);
        detailAdapter.addItems(curRoutineItem.arrayListDetail);

        // add NestedRecyclerView's item (Dynamically)
        holder.addSet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                curRoutineItem.arrayListDetail.add(new RoutineDetailModel());
                detailAdapter.addItems(curRoutineItem.arrayListDetail);
                holder.routine_detail.setAdapter(detailAdapter); // HERE!!!!!
            }
        });
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder  {
        TextView routine;
        Button addSet;
        RecyclerView routine_detail;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            initViews();
        }

        private void initViews() {
            routine = itemView.findViewById(R.id.routine);
            routine_detail = itemView.findViewById(R.id.detail_routine);
            addSet = itemView.findViewById(R.id.add_set);

        }
        private void setItems(RoutineModel routineItem) {
            routine.setText(routineItem.getRoutine());
        }
        public void setRoutineDetailRecyClerView() {
            routine_detail.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false));
            routine_detail.setHasFixedSize(true);
        }
    }
}

RoutineDetailModel.java (嵌套回收视图模型)

代码语言:javascript
复制
public class RoutineDetailModel {
    String set;
    String weight;
    String reps;
}

RoutineDetailAdapter.java

代码语言:javascript
复制
public class RoutineDetailAdapter extends  RecyclerView.Adapter<RoutineDetailAdapter.ViewHolder>{
    ArrayList<RoutineDetailModel> items = new ArrayList<>();

    public void addItems(ArrayList<RoutineDetailModel> items) {
        this.items = items;
        notifyDataSetChanged();
    }

    public ArrayList<RoutineDetailModel> getItem() {
        return this.items;
    }


    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View itemView = inflater.inflate(R.layout.routine_detail_item, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        RoutineDetailModel item = items.get(position);
        holder.setItem(item);
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView set;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            set = itemView.findViewById(R.id.set);
        }

        private void setItem(RoutineDetailModel item) {
            set.setText("TEST");
        }
    }
}

++++++++++++++++++++++++++++++++++

OnCreateViewHolder

代码语言:javascript
复制
@NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);
        View itemView =  inflater.inflate(R.layout.routine_item, parent, false);
        ViewHolder holder = new ViewHolder(itemView);
        detailAdapter = new RoutineDetailAdapter();
        holder.setRoutineDetailRecyClerView();
        holder.routine_detail.setAdapter(detailAdapter);

        return holder;
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-17 19:26:58

RecyclerView的工作方式是回收几个ViewHolder对象,并更新它们以显示不同项的数据。这种情况发生在onBindViewHolder中,您在这里设置它以使用holder.setItems(curRoutineItem)调用显示数据,对吗?

但是,每次绑定视图持有者时,您都会这样做:

获取当前position

  • clearing的RoutineModel -- its arrayListDetail,并添加一个新的RoutineDetailAdapter --一个只包含单个RoutineDetailModel的新RoutineDetailAdapter,并在ViewHolderRecyclerView上设置它,替换已经存在的

H 119添加一个单击侦听器,将另一个RoutineDetailModel添加到RoutineModel,并且适配器(这两个适配器都将在下一次被称为d22/code>调用)H 223

因此,我不知道具体问题在哪里,但是您实际上并没有用添加的项来存储这个状态--每次调用onBindViewHolder时,每当一个项滚动到视图中时,它都会被擦除。

如果您说单击该按钮而RecyclerView中没有发生任何事情而不再次调用setAdapter,那么我不知道为什么会发生这种情况--此时,detailAdapter在回收器视图中引用适配器,而您正在添加另一个项目(从技术上讲,用相同的列表替换它的项目,其中一个列表加上另一个列表)。

但是如果你的意思是你滚动列表,你的物品就消失了,是的,这是会发生的,因为你每次滚动到视图中时都会删除它们。这看起来像是数据初始化:

代码语言:javascript
复制
curRoutineItem.arrayListDetail = new ArrayList<>();
curRoutineItem.arrayListDetail.add(new RoutineDetailModel());

而且绝对不应该发生在onBindViewHolder。这些东西:

代码语言:javascript
复制
RoutineDetailAdapter detailAdapter = new RoutineDetailAdapter();
holder.routine_detail.setAdapter(detailAdapter);

RecyclerView初始化,并且可能会在onViewHolderCreated每个回收视图中发生一次。然后,在onBindViewHolder中,只需调用getAdapter并设置要显示的项。

这可能会对你的问题有所帮助,我不知道你到底看到了什么,因为我希望它能让你感觉到它是多么的破碎!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65764269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档