简体   繁体   中英

How can I implement a RecyclerView inside another RecyclerView's item

I should implement a RecyclerView , its item contains a TextView and another inner horizontal RecyclerView .

I started it considering that the inner RecyclerView likes any other View . The issue happened when I tried to pass the context to the LinearLayoutManager() and the RecyclerView.setAdapter() .

The issue is: I cannot pass the context , because I'm trying to pass it inside the first RecyclerView adapter

I cannot pass the context and don't know if this way is the optimal or if it will work at the end.

Here's my code:


public class TheFirstAdapter extends RecyclerView.Adapter<TheFirstAdapter.TheFirstViewHolder> {

    private Context context;
    private List<FirstItemModel> firstItemModelList;
    private List<SecondItemModel> secondItemModelList;
    SecondItemModel secondItemModel;
    TheSecondAdapter theSecondAdapter;

    public TheFirstAdapter(Context context, List<FirstItemModel> firstItemModel) {
        this.context = context;
        this.firstItemModelList = firstItemModelList;
    }

    @NonNull
    @Override
    public TheFirstViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.add_routine_list_item, parent,
                false);
        return new TheFirstAdapter.TheFirstViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull TheFirstViewHolder holder, int position) {

//there is an error in this line:
////java.lang.NullPointerException: Attempt to invoke interface method 'boolean java.util.List.add(java.lang.Object)' on a null object reference

//////the solution: secondItemModelList= new ArrayList<>(); 
            for (int i = 1; i < 5; i++) {
            secondItemModel = new AddRoutineRoutines("Morning", "#9697D6");
            secondItemModelList.add(secondItemModel);
        }

        FirstItemModel firstItemModel = firstItemModelList.get(position);
        holder.textView.setText(addRoutineItemModel.getFirstItemText());
        holder.theSecondRecyclerView.setLayoutManager(new LinearLayoutManager(context));
        TheSecondAdapter theSecondAdapter = new TheSecondAdapter(context, secondItemModelList);
        holder.theSecondRecyclerView.setAdapter();
    }

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

    class TheFirstViewHolder extends RecyclerView.ViewHolder {

        TextView textView;
        RecyclerView theSecondRecyclerView;

        public TheFirstViewHolder(@NonNull View itemView) {

            super(itemView);
            textView = itemView.findViewById(R.id.first_item_text);
            theSecondRecyclerView = itemView.findViewById(R.id.the_second_recycler_view);
        }
    }
}

Edit1: I passed the context but still there a problem I showed above.

Edit2: The problem was I didn't initialized the secondItemModelList .

*After discussions this code works:*


public class TheFirstAdapter extends RecyclerView.Adapter<TheFirstAdapter.TheFirstViewHolder> {

    private Context context;
    private List<FirstItemModel> firstItemModelList;
    private List<SecondItemModel> secondItemModelList;
    SecondItemModel secondItemModel;

    public TheFirstAdapter(Context context, List<FirstItemModel> firstItemModel) {
        this.context = context;
        this.firstItemModelList = firstItemModelList;
    }

    @NonNull
    @Override
    public TheFirstViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.add_routine_list_item, parent,
                false);
        return new TheFirstAdapter.TheFirstViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull TheFirstViewHolder holder, int position) {

        FirstItemModel firstItemModel = firstItemModelList.get(position);
        holder.textView.setText(addRoutineItemModel.getFirstItemText());
        holder.updateView(secondItemModelList);
    }

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

    class TheFirstViewHolder extends RecyclerView.ViewHolder {

        TextView textView;
        RecyclerView theSecondRecyclerView;

        public TheFirstViewHolder(@NonNull View itemView) {

            super(itemView);
            textView = itemView.findViewById(R.id.first_item_text);
            theSecondRecyclerView = itemView.findViewById(R.id.the_second_recycler_view);
        }

        public updateView(List<SecondItemModel> secondItemModelList) {
            secondItemModelList = new ArrayList<>();

            for (int i = 1; i < 5; i++) {
                secondItemModel = new SecondItemModel("Morning", "#9697D6");
                secondItemModelList.add(secondItemModel);
            }

            TheSecondAdapter theSecondAdapter = new TheSecondAdapter(context, secondItemModelList);
            LinearLayoutManager layoutManager
                    = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
            theSecondRecyclerView.setLayoutManager(layoutManager);
            theSecondRecyclerView.setAdapter(theSecondAdapter);
        }
    }
}

What is the context which you send to arg of constructor LinearLayoutManager ? If I understand your issue. You are using context from parent. Please use itemView.context .

Update:

Your code is very bad.

  1. Do not create adapter in the bindView method.
  2. Do not set/remove data in the bindView method.
  3. BindView only use for bind data for view. Only that.

ViewHolder should be like this:

class TheFirstViewHolder extends RecyclerView.ViewHolder {

        TextView textView;
        RecyclerView theSecondRecyclerView;
        TheFirstAdapter adapter;

        public TheFirstViewHolder(@NonNull View itemView) {

            super(itemView);
            textView = itemView.findViewById(R.id.first_item_text);
            theSecondRecyclerView = itemView.findViewById(R.id.the_second_recycler_view);
        }

        public void updateView(....) {
           //create new adapter if need.
           //set data for adapter if need
           ...
        }
    }

onBindViewHolder should be like this: holder.updateView(...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM