(android)动态嵌套回收器视图项目中的随机更改问题

(android)动态嵌套回收器视图项目中的随机更改问题,android,android-recyclerview,Android,Android Recyclerview,嗨, 我正在制作一个动态的嵌套回收视图 外部回收视图(例行程序)由以下部分组成(A、B、C…)、添加按钮、 和delete按钮,内部回收视图(详细程序)由文本视图(设置、重量和计数)组成 当我添加外部项时,默认情况下它有一个内部RecyclerView项 我认为实施是成功的,但事实并非如此 这张照片是我事先做了一些东西的条件 这是一张在那里创建其他项目的图片 然而,在图中,当我添加G项时,您可以看到F项 而B项发生了变化 奇怪的是,G项有两个基本项。本来就是这样 第二张图片是后面添加的项目 如果

嗨, 我正在制作一个动态的
嵌套回收视图

外部回收视图(例行程序)
由以下部分组成(A、B、C…)、添加按钮、

和delete按钮,内部回收视图(详细程序)由文本视图(设置、重量和计数)组成

当我添加外部项时,默认情况下它有一个内部
RecyclerView

我认为实施是成功的,但事实并非如此

这张照片是我事先做了一些东西的条件

这是一张在那里创建其他项目的图片

然而,在图中,当我添加
G项时,您可以看到
F项

B项
发生了变化

奇怪的是,G项有两个基本项。本来就是这样

第二张图片是后面添加的项目

如果我添加了一个新的
外部回收视图
项目,整个系统将有一个新的变化

请再说一遍

我不知道为什么会发生这种变化。如果添加新项目,则需要

保留现有项目

请告诉我原因

这是代码

RoutineAdapter.java(外部循环视图适配器)

公共类RoutineAdapter扩展了RecyclerView.Adapter{
语境;
ArrayList routineItems=新的ArrayList();
公共RoutineDetailAdapter-detailAdapter;
OnRoutineItemClickListener侦听器;
公共无效设置OnRoutineClickListener(OnRoutineItemClickListener侦听器){
this.listener=listener;
}
公共无效附加项(RoutineModel项){
常规项目。添加(项目);
notifyDataSetChanged();
}
public void addDetailItem(RoutineDetailAdapter curDetailAdapter){
curDetailAdapter.addItem(新RoutineDetailModel());
}
public void deleteDetailItem(RoutineDetailAdapter curDetailAdapter){
curDetailAdapter.deleteItem();
}
@非空
@凌驾
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType){
context=parent.getContext();
LayoutFlater充气机=LayoutFlater.from(上下文);
视图项视图=充气机。充气(R.layout.routine\u项,父项,false);
ViewHolder=新的ViewHolder(项目视图);
detailAdapter=新RoutineDetailAdapter();
holder.setRoutineDetailRecyClerView();
支架。rv_详图。设置适配器(详图适配器);
addItem(新RoutineDetailModel());
报税表持有人;
}
@凌驾
public void onBindViewHolder(@NonNull ViewHolder,int位置){
RoutineModel curRoutineItem=routineItems.get(位置);
持有者。设置项目(当前项目);
}
@凌驾
public int getItemCount(){
返回routineItems.size();
}
公共类ViewHolder扩展了RecyclerView.ViewHolder{
RecyclerView rv_详图;
文本视图例程;
按钮地址集;
按钮删除集;
公共视图持有者(@NonNull View itemView){
超级(项目视图);
initViews();
addSet.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
RoutineDetailAdapter curDetailAdapter=(RoutineDetailAdapter)rv_detail.getAdapter();
OnAddBtnClick(curDetailAdapter);
}
});
deleteSet.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
RoutineDetailAdapter curDetailAdapter=(RoutineDetailAdapter)rv_detail.getAdapter();
OnDeleteBtnClick(curDetailAdapter);
}
});
}
私有void initViews(){
例程=itemView.findViewById(R.id.routine);
rv_detail=itemView.findviewbyd(R.id.detail_例程);
addSet=itemView.findviewbyd(R.id.add\u集);
deleteSet=itemView.findviewbyd(R.id.delete\u集);
}
私有void集合项(RoutineModel routineItem){
setText(routineItem.getRoutine());
}
public void setRoutineDetailRecyClerView(){
rv_detail.setLayoutManager(新的LinearLayoutManager(context,RecyclerView.VERTICAL,false));
}
}
RoutineItemClickListener上的公共接口{
在ADDBTNCLICK(RoutineDetailAdapter-detailAdapter)上公开作废;
公共无效OnDeleteBtnClick(RoutineDetailAdapter detailAdapter);
}
}
RoutineDetailAdapter.java(内部循环视图适配器)

公共类RoutineDetailAdapter扩展了RecyclerView.Adapter{
ArrayList items=新建ArrayList();
语境;
插入位置;
删除位置;
公共无效附加项(RoutineDetailModel项){
项目。添加(项目);
notifyItemInserted(插入位置);
}
公共无效删除项(){
试一试{
如果(items.size()>1){//至少保留一组
项目。移除(删除位置);
删除(删除位置);
deletePosition-=1;
}
}捕获(例外e){
//空的
}
}
公共阵列列表getItem(){
归还此物品;
}
@非空
@凌驾
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType){
context=parent.getContext();
LayoutInflater充气器=LayoutInflater.from(parent.getContext());
视图项视图=充气机。充气(R.layout.routine\u detail\u项目,父项,false);
返回新的ViewHolder(itemView);
}
@凌驾
public void onBindViewHolder(@NonNull ViewHolder,int位置){
RoutineDetailModelItem=items.get(位置);
H
public class RoutineAdapter extends RecyclerView.Adapter<RoutineAdapter.ViewHolder> {
    Context context;
    ArrayList<RoutineModel> routineItems = new ArrayList<>();
    public RoutineDetailAdapter detailAdapter;
    OnRoutineItemClickListener listener;

    public void setOnRoutineClickListener(OnRoutineItemClickListener listener) {
        this.listener = listener;
    }

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

    public void addDetailItem(RoutineDetailAdapter curDetailAdapter) {
        curDetailAdapter.addItem(new RoutineDetailModel());
    }
    public void deleteDetailItem(RoutineDetailAdapter curDetailAdapter) {
        curDetailAdapter.deleteItem();
    }

    @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.rv_detail.setAdapter(detailAdapter);
        detailAdapter.addItem(new RoutineDetailModel());

        return holder;
    }

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

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

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

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

            addSet.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    RoutineDetailAdapter curDetailAdapter = (RoutineDetailAdapter) rv_detail.getAdapter();
                    listener.OnAddBtnClick(curDetailAdapter);
                }
            });

            deleteSet.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    RoutineDetailAdapter curDetailAdapter = (RoutineDetailAdapter) rv_detail.getAdapter();
                    listener.OnDeleteBtnClick(curDetailAdapter);
                }
            });
        }

        private void initViews() {
            routine = itemView.findViewById(R.id.routine);
            rv_detail = itemView.findViewById(R.id.detail_routine);
            addSet = itemView.findViewById(R.id.add_set);
            deleteSet = itemView.findViewById(R.id.delete_set);
        }
        private void setItems(RoutineModel routineItem) {
            routine.setText(routineItem.getRoutine());
        }

        public void setRoutineDetailRecyClerView() {
            rv_detail.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false));
        }
    }

    public interface OnRoutineItemClickListener {
        public void OnAddBtnClick(RoutineDetailAdapter detailAdapter);
        public void OnDeleteBtnClick(RoutineDetailAdapter detailAdapter);
    }
}
public class RoutineDetailAdapter extends  RecyclerView.Adapter<RoutineDetailAdapter.ViewHolder>{
    ArrayList<RoutineDetailModel> items = new ArrayList<>();
    Context context;
    int insertPosition;
    int deletePosition;

    public void addItem(RoutineDetailModel item) {
        items.add(item);
        notifyItemInserted(insertPosition);
    }

    public void deleteItem() {
        try {
            if(items.size() > 1) { // Leave at least one set
                items.remove(deletePosition);
                notifyItemRemoved(deletePosition);
                deletePosition -= 1;
            }
        } catch (Exception e) {
            // empty
        }
    }

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

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        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, position);
        insertPosition = position + 1;
        deletePosition = position;
    }

    @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, int setCount) {
            set.setText(setCount + 1 + "set");
        }
    }
}
public class WriteRoutineActivity extends AppCompatActivity {
    Button add_routine_btn;
    TextView title;
    RecyclerView routine_rv;

    RoutineAdapter routineAdapter;
    LinearLayoutManager routineLayoutManger;
    ArrayList<String> titleData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_write_routine);

        initViews();
        setPageTitle(getIntent());
        setRoutineRecyclerview();

        routineAdapter = new RoutineAdapter();
        routine_rv.setAdapter(routineAdapter);

        add_routine_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                WorkoutListDialogFragment routineDialog = new WorkoutListDialogFragment();
                routineDialog.show(getSupportFragmentManager(), "RoutineListDialog");
            }
        });

        routineAdapter.setOnRoutineClickListener(new RoutineAdapter.OnRoutineItemClickListener() {
            @Override
            public void OnAddBtnClick(RoutineDetailAdapter curDetailAdapter) {
                routineAdapter.addDetailItem(curDetailAdapter);
            }

            @Override
            public void OnDeleteBtnClick(RoutineDetailAdapter curDetailAdapter) {
                routineAdapter.deleteDetailItem(curDetailAdapter);
            }
        });
    }

    private void initViews() {
        title = findViewById(R.id.body_part_detail_title);
        routine_rv = findViewById(R.id.routine_recyclerview);
        add_routine_btn = findViewById(R.id.add_routine);
    }

    private void setRoutineRecyclerview() {
        routineLayoutManger = new LinearLayoutManager(getApplicationContext(), RecyclerView.VERTICAL, false);
        routine_rv.setLayoutManager(routineLayoutManger);
        routine_rv.setHasFixedSize(true);
        RecyclerView.ItemDecoration divider = new DividerItemDecorator(ContextCompat.getDrawable(getApplicationContext(), R.drawable.divider));
        routine_rv.addItemDecoration(divider);
    }

    public void setPageTitle(Intent intent) {
        if(intent != null) {
            titleData = intent.getStringArrayListExtra("bodypart");
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                String new_title = String.join(" / ", titleData);
                title.setText(new_title);
            }
            else {
                StringBuilder new_title = new StringBuilder();
                for (int i = 0; i < titleData.size(); i++) {
                    if (i == titleData.size() - 1) {
                        new_title.append(titleData.get(i));
                        break;
                    }
                    new_title.append(titleData.get(i)).append(" / ");
                }
                title.setText(new_title);
            }
        }
    }

    public void addRoutine(String routine) {
        routineAdapter.addItem(new RoutineModel(routine));
        routine_rv.smoothScrollToPosition(routineAdapter.getItemCount() - 1);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".data.DailyRecordDetailActivity">
    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/Theme.AppBarOverlay"
        app:elevation="0dp">
        <androidx.appcompat.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <TextView
                    android:id="@+id/body_part_detail_title"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="PART"
                    android:textColor="@color/white"
                    android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
                    android:layout_centerHorizontal="true"/>
            </RelativeLayout>
        </androidx.appcompat.widget.Toolbar>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
        <Button
            android:id="@+id/add_routine"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="ROUTINE ADD"
            android:backgroundTint="@color/light_green"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/routine_recyclerview"
            app:layout_constraintRight_toRightOf="parent"/>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/routine_recyclerview"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:scrollbars="vertical"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/add_routine"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/white"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp">
    <LinearLayout
        android:id="@+id/linear_routine"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent">
        <TextView
            android:id="@+id/routine"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:paddingLeft="10dp"
            android:text="ROUTINE"
            android:textSize="16dp"
            android:textStyle="bold"
            android:layout_weight="2"/>
        <Button
            android:id="@+id/add_set"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="?android:selectableItemBackground"
            android:text="ADD"
            android:textColor="@color/black"
            android:gravity="center"
            android:layout_weight="1"/>
        <Button
            android:id="@+id/delete_set"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="?android:selectableItemBackground"
            android:text="DELETE"
            android:textColor="@color/black"
            android:layout_weight="1"/>
    </LinearLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/detail_routine"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toBottomOf="@+id/linear_routine"
        app:layout_constraintLeft_toLeftOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_marginLeft="5dp"
    android:padding="10dp"
    android:clipToPadding="false">
    <TextView
        android:id="@+id/set"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="SET"/>
    <TextView
        android:id="@+id/weight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="0 kg"/>
    <TextView
        android:id="@+id/reps"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="0"/>

</LinearLayout>
public class RoutineAdapter extends RecyclerView.Adapter<RoutineAdapter.ViewHolder> {
        Context context;
        ArrayList<RoutineModel> routineItems = new ArrayList<>();
        //public RoutineDetailAdapter detailAdapter; //TODO move it to local variable in method onCreateViewHolder
        OnRoutineItemClickListener listener;
@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);
        RoutineDetailAdapter detailAdapter = new RoutineDetailAdapter(); //TODO Create local variable
        detailAdapter.addItem(new RoutineDetailModel());
        holder.setRoutineDetailRecyClerView();
        holder.rv_detail.setAdapter(detailAdapter);

        return holder;
    }
public class MultipleViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private Context context;
    private List<Object> items; //List<Object or Generic class or abstarct base Model class parent of Routine and RoutineDetails>
    private OnItemClickListener listener; //TODO new interface

        ..............

}
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if(viewType == 1){
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.routine_item, parent, false);
            return new RoutineViewHolder (itemView);
        }/*else{*/
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.routine_detail_item, parent, false);
            return new RoutineDetailsViewHolder (itemView);
        //}
    }
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    Object object = items.get(position); //Object or Generic class or abstarct base Model class parent of Routine and RoutineDetails>
    if(object instanceof RoutineModel) {
        //create method
        updateRoutineViews((RoutineViewHolder) holder, (RoutineModel) object, position);
    }else if(object instanceof RoutineDetailsModel) {
        //create method
        updateRoutineDetailsViewHolder((RoutineDetailsViewHolder) holder, (RoutineDetailModel) object);
    }
}
@Override
    public int getItemViewType(int position) {
        Object object = items.get(position);
        if(object instanceof RoutineModel){
            return 1;
        }
        //else if instanceOf RoutineDetailModel return 0
        return 0; 
    }
List<Object> mixedList = new ArrayList<>();
for(RoutineModel rm: routineList){
    mixedList.add(rm);
    if(rm has routineDetailModels){ //pseudo code
        for(RoutineDetailModels rmdetilas: rm.getRoutineDetailModels()){
            mixedList.add(rmdetilas);
        }
    }
}
adpater.swapData(mixedList); //create your method to swap or set data to adapter
public interface OnItemClickListener{
    void onClick(View view, int position);
    void onLongClick(View view, int position);
}
adapter.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onClick(View view, int position) {
            Object item = (Object) adapter.getItem(position);
            if(item instanceof Routine) {
                if (view.getId() == R.id.delete_id) {
                    //TODO delete form list, notifyItemRemoved or generate all mixeddata again and swap
                } else if (view.getId() == R.id.whateveryouwant) {
                    //TODO doSomething()
                }

            }
        }

        @Override
        public void onLongClick(View view, int position) {

        }
    });
public class RoutineViewHolder extends RecyclerView.ViewHolder  {
    public RecyclerView rv_detail;
    public TextView routine;
    public Button addSet;
    public Button deleteSet;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        //initViews(); in constructor
        routine = itemView.findViewById(R.id.routine);
        rv_detail = itemView.findViewById(R.id.detail_routine);
        addSet = itemView.findViewById(R.id.add_set);
        deleteSet = itemView.findViewById(R.id.delete_set);
    } 
}
private void updateRoutineViews(RoutineViewHolder holder, RoutineModel routineItem, position){
    holder.routine.setText(routineItem.getRoutine());
    holder.rv_detail.setText(routineItem.getWhateverYouWant());

    holder.deleteSet.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onItemClickListener.onClick(v, position); //or holder.getAdapterPosition()
        }
    });
}
public class RoutineActivity extends AppCompatActivity {

    private MultipleViewAdapter adapter;
    private List<RoutineModel> routineList;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_routine);

        RecyclerView contentList = findViewById(R.id.list);
        contentList.setLayoutManager(new LinearLayoutManager(this));
        adapter = new MultipleViewAdapter(this, new ArrayList<>());
        contentList.setAdapter(adapter);
        adapter.setOnItemClickListener(new MultipleViewAdapter.OnItemClickListener() {
            @Override
            public void onClick(View view, int position) {
                Object item = (Object) adapter.getItem(position);
                if(item instanceof RoutineModel) {
                    RoutineModel routineModel = (RoutineModel) item;
                    if (view.getId() == R.id.add_set) {
                        int weight = randomInt(99);
                        Toast.makeText(RoutineActivity.this, "New item with weight: " + weight + " kg", Toast.LENGTH_SHORT).show();
                        routineModel.addDetails(new RoutineDetailsModel(routineModel.getDetailsSize() + 1, weight));
                        adapter.swapData(getMixedList()); // OR add item to adapter and notify item inserted
                        //TODO implement SnappingLinearLayoutManager and set list.smoothScroleto... routineModel
                    } else if (view.getId() == R.id.delete_set) {
                        //TODO doSomething()
                        boolean deleted = routineModel.removeDetails(routineModel.getDetailsSize() - 1); // -1 !!! to delete last item
                        Toast.makeText(RoutineActivity.this, deleted ? "Last item is deleted": "No more items", Toast.LENGTH_SHORT).show();
                        adapter.swapData(getMixedList()); // OR remove item from adapter and notify item removed
                        //TODO implement SnappingLinearLayoutManager and set list.smoothScroleto.... routineModel
                    }

                }else if(item instanceof RoutineDetailsModel) {
                    RoutineDetailsModel routineModel = (RoutineDetailsModel) item;
                    Toast.makeText(RoutineActivity.this, "Weight: " + routineModel.getWeight() + " kg", Toast.LENGTH_SHORT).show();

                //TODO EDITED 4 (copy/paste this) random new Weight
                routineModel.setWeight(randomInt(99));
                adapter.notifyItemChanged(position);
                Toast.makeText(RoutineActivity.this, "New Weight: " + routineModel.getWeight() + " kg", Toast.LENGTH_SHORT).show();

                }
            }

            @Override
            public void onLongClick(View view, int position) {

            }
        });

        initFakeData();
        adapter.swapData(getMixedList());
    }


    private List<Object> getMixedList() {
        List<Object> mixedList = new ArrayList<>();
        for(RoutineModel rm: routineList){
            mixedList.add(rm);
            if(rm.getRoutineDetailsModel() != null && rm.getRoutineDetailsModel().size() > 0){
                for(RoutineDetailsModel rmdetilas: rm.getRoutineDetailsModel()){
                    mixedList.add(rmdetilas);
                }
            }
        }
        return mixedList;
    }


    private void initFakeData() {
        routineList = new ArrayList<>();
        for(int i = 0; i < 5; i++){
            RoutineModel routineModel = new RoutineModel(String.valueOf(i + 1));
            for(int j = 0; j < 4; j++){
                routineModel.addDetails(new RoutineDetailsModel(j+1, randomInt(99)));
            }
            routineList.add(routineModel);
        }
    }

    private int randomInt(int max) {
        return (int) Math.floor(Math.random() * max);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>
public class MultipleViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private final Context context; // TODO only if you need conetxt
    private List<Object> items;
    private OnItemClickListener onItemClickListener;

    public MultipleViewAdapter(Context context, List<Object> items) {
        this.context = context;
        this.items = items;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if(viewType == 1){
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.routine_item, parent, false);
            return new RoutineViewHolder(itemView);
        }/*else{*/
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.routine_detail_item, parent, false);
        return new RoutineDetailsViewHolder(itemView);
        //}
    }


    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        Object object = items.get(position); //Object or Generic class or abstarct base Model class parent of Routine and RoutineDetails>
        if(object instanceof RoutineModel) {
            updateRoutineViews((RoutineViewHolder) holder, (RoutineModel) object, position);
        }else if(object instanceof RoutineDetailsModel) {
            updateRoutineDetailsViewHolder((RoutineDetailsViewHolder) holder, (RoutineDetailsModel) object, position);
        }
    }

    private void updateRoutineViews(RoutineViewHolder holder, RoutineModel routineItem, int position){
        holder.routine.setText("Routine " + routineItem.getRoutine());

        holder.addSet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(onItemClickListener != null) onItemClickListener.onClick(v, position);
            }
        });

        holder.deleteSet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(onItemClickListener != null) onItemClickListener.onClick(v, position);
            }
        });
    }

    private void updateRoutineDetailsViewHolder(RoutineDetailsViewHolder holder, RoutineDetailsModel routineDetailsModel, int position){
        holder.set.setText(routineDetailsModel.getSet() + " set");
        holder.weight.setText(routineDetailsModel.getWeight()  + " kg");
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(onItemClickListener != null) onItemClickListener.onClick(v, position);
            }
        });
    }


    @Override
    public int getItemViewType(int position) {
        Object object = items.get(position);
        if(object instanceof RoutineModel){
            return 1;
        }
        //else if instanceOf RoutineDetailModel return 0
        return 0;
    }

    @Override
    public int getItemCount() {
        if(items == null) return 0;
        return items.size();
    }

    public Object getItem(int position) {
        if(this.items == null || position < 0 || position >= this.items.size()) return null;
        return this.items.get(position);
    }

    public void swapData(List<Object> newItems) {
        if (newItems != null) {
            this.items = newItems;
            notifyDataSetChanged();
        }
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public interface OnItemClickListener{
        void onClick(View view, int position);
        void onLongClick(View view, int position);
    }


    public static class RoutineViewHolder extends RecyclerView.ViewHolder  {
        public TextView routine;
        public Button addSet;
        public Button deleteSet;

        public RoutineViewHolder(@NonNull View itemView) {
            super(itemView);
            //initViews(); in constructor
            routine = itemView.findViewById(R.id.routine);
            addSet = itemView.findViewById(R.id.add_set);
            deleteSet = itemView.findViewById(R.id.delete_set);
        }
    }

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



}
public class RoutineModel {

    private List<RoutineDetailsModel> routineDetailsList;
    private String routine;

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

    public List<RoutineDetailsModel> getRoutineDetailsModel() {
        return routineDetailsList;
    }

    public void setRoutineDetailsModel(List<RoutineDetailsModel> routineDetailsModel) {
        this.routineDetailsList = routineDetailsModel;
    }

    public void addDetails(RoutineDetailsModel item) {
        if(routineDetailsList == null) {
            routineDetailsList = new ArrayList<>();
        }
        this.routineDetailsList.add(item);
    }
    public boolean removeDetails(int index) {
        if(routineDetailsList == null || index >= routineDetailsList.size() || index < 0) return false;
        this.routineDetailsList.remove(index);
        return true;
    }

    public String getRoutine() {
        return routine;
    }

    public void setRoutine(String routine) {
        this.routine = routine;
    }

    public int getDetailsSize() {
        if(routineDetailsList == null) return 0;
        return routineDetailsList.size();
    }
}
public class RoutineDetailsModel {

    private int set;
    private int weight;

    public RoutineDetailsModel(int set, int weight) {
        this.set = set;
        this.weight = weight;
    }

    public int getSet() {
        return set;
    }

    public void setSet(int set) {
        this.set = set;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}