Android 嵌套回收视图';s notifyDataSetChanged()不工作

Android 嵌套回收视图';s notifyDataSetChanged()不工作,android,android-recyclerview,Android,Android Recyclerview,我正在实现一个嵌套回收器视图 单击按钮时,会为每个项目动态添加嵌套回收器视图 我已经实现了这个功能。但当您单击按钮添加项目时 只有通过嵌套的recyclerview的setAdapter()才能更新项目 不是notifyDataSetChanged() 为什么会这样?为什么不更新为notifyDataSetChanged() 至少据我所知,setAdapter()应该只调用一次 如果多次调用setAdapter(),这有关系吗 我想要的是由notifyDataSetChanged()更新,而不是

我正在实现一个
嵌套回收器视图

单击按钮时,会为每个项目动态添加嵌套回收器视图

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

只有通过嵌套的recyclerview的setAdapter()才能更新项目

不是
notifyDataSetChanged()

为什么会这样?为什么不更新为
notifyDataSetChanged()

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

如果多次调用
setAdapter()
,这有关系吗

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

但该项由
setAdapter()
更新

为什么?

RoutineModel.java

public class RoutineModel {
    String routine;
    public ArrayList<RoutineDetailModel> arrayListDetail;

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

    public String getRoutine() {
        return routine;
    }
}
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");
        }
    }
}
RoutineDetailAdapter.java

public class RoutineModel {
    String routine;
    public ArrayList<RoutineDetailModel> arrayListDetail;

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

    public String getRoutine() {
        return routine;
    }
}
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");
        }
    }
}

RecyclerView
s通过回收少量的
ViewHolder
对象,并更新它们以显示不同项目的数据来工作。这发生在
onBindViewHolder
中,您正在设置它以显示与
holder.setItems(curRoutineItem)
调用的数据,对吗

但每次绑定视图持有者时,您都要执行以下操作:

  • 获取当前位置的
    RoutineModel
  • 清除其
    arrayListDetail
    并添加单个新的``RoutineDetailModel```
  • 创建一个新的
    RoutineDetailAdapter
    ,它只包含单个
    RoutineDetailModel
    ,并在
    ViewHolder
    RecyclerView
    上设置该适配器,替换已有的适配器
  • 添加一个单击侦听器,将另一个
    RoutineDetailModel
    添加到
    RoutineModel
    和适配器(下一次调用
    onBindViewHolder
    时将清除并重新创建这两个侦听器)
所以我不知道您的问题具体在哪里,但实际上您并没有将此状态与添加的项一起存储—每当调用
onBindViewHolder
时,只要一个项滚动到视图中,它就会被擦除

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

但是如果你的意思是你滚动列表,你的项目就会消失,是的,这是会发生的,因为每次项目滚动回视图时你都会删除它们。这些东西看起来像是数据初始化:

curRoutineItem.arrayListDetail = new ArrayList<>();
curRoutineItem.arrayListDetail.add(new RoutineDetailModel());
RecyclerView
初始化,在
onViewHolderCreated
中,每个RecyclerView可能会发生一次。然后在
onBindViewHolder
中,您可以调用
getAdapter
并设置要显示的项目


这可能有助于解决您的问题,我不确定您到底看到了什么,因为我希望它会感觉非常糟糕!

Hello Ybb。我想您尝试使用
附加项(ArrayList项)通知DataSetChanged()
?是的,因为我认为每次添加项目时都应该更新
回收器视图
。这有错吗?您有一些
视图持有者
,足以填充列表的可见部分-系统通过调用
onCreateViewHolder
来创建它们。每个
视图持有者
都有自己的
回收视图
>,并且每个都有自己的
适配器
。您可以在所有设置完成后在
onCreateViewHolder
中设置该适配器。
onBindViewHolder
在您希望使用系统提供的
ViewHolder
在列表项中显示数据时被调用。因此,要在其
RecyclerView
中显示数据,您可以需要获取其适配器并设置项目,然后执行
notifyDataSetChanged()
(您正在执行的操作)我不知道这是否能解决您的具体问题,但可以将每个适配器看作是插入
RecyclerView
以使其显示内容的东西,并且在创建
RecyclerView
时,只要设置
ViewHolder
就可以创建并设置一个适配器。然后,您可以使用当前数据对其进行更新,就像u设置
someTextView.text=无论什么
。但请记住,您在
onBindViewHolder
中不断重置
ArrayList
s(您所持有的实际数据),因此您的项目在滚动出屏幕时将不断重置(从技术上讲,当它们滚动回视图时)哦,很抱歉,很难在注释中解释!您的
ViewHolder
有一个
RecyclerView
,它是从布局中膨胀出来的-您只是在安装过程中为它创建了一个适配器(在
onCreateViewHolder
中)。您每次都需要创建一个新的,因为每个
ViewHolder
都有自己的
RecyclerView
,它需要自己的
适配器。如果您在每个
RecyclerView
上设置相同的适配器实例,它们将显示相同的内容。如果现在不看到您的代码是什么样子,就很难给出建议,每个
ViewHolder
只是一个用于显示项目数据的布局。XML中有一个
RecyclerView
,因此当您为
ViewHolder
膨胀该布局时,这是一个视图(在
initViews()
中指定为
routine\u detail
。因此每个
RecyclerView
都需要一个适配器(或者它不会做任何事情)。一旦你设置了它,你应该
onBindViewHolder
中获取它。然后你可以用
arrayListDetail
为当前项目(从
位置
)执行
setItems
。我不能
curRoutineItem.arrayListDetail = new ArrayList<>();
curRoutineItem.arrayListDetail.add(new RoutineDetailModel());
RoutineDetailAdapter detailAdapter = new RoutineDetailAdapter();
holder.routine_detail.setAdapter(detailAdapter);