'How to flow Data from One RecyclerView to Another RecyclerView when an item in first RecyclerView is clicked?

Hi, I faced an issue here.. I was creating a chatbot in which user can type a text to send it and also can select a text out of the recommended texts

enter image description here

so I created two RecycleViews

enter image description here

My goal is - when the user selects one of the recommended text, then that text should appear in the Chatting RecycleView

enter image description here

here is my main Activity Class

public class Charts extends AppCompatActivity {

    private static final String USER_KEY = "user";
    private static final String BOT_KEY = "bot";

    RecyclerView chart_recycle,auto_texts;
    EditText message_text;
    ImageView send_btn,mic_button;
    ImageView setting_button;

    ChartsAdapter chartsAdapter;
    RecyclerView.LayoutManager linearLayout;
    ArrayList<ChartModeClass> modeClassesArrayList = new ArrayList<>();

    AutoAdapter autoAdapter;
    RecyclerView.LayoutManager horizontal;
    List<Texts> list = new ArrayList();


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

        message_text = findViewById(R.id.message_text);
        send_btn = findViewById(R.id.send_btn);
        mic_button = findViewById(R.id.mic_btn);
        setting_button = findViewById(R.id.setting_button);

        chart_recycle = findViewById(R.id.chart_recycle);
        chart_recycle.setHasFixedSize(true);

        auto_texts = findViewById(R.id.auto_texts);
        auto_texts.setHasFixedSize(true);

        linearLayout = new LinearLayoutManager(getApplicationContext(), RecyclerView.VERTICAL, false);
        chart_recycle.setLayoutManager(linearLayout);

        //Auto text
        horizontal = new LinearLayoutManager(getApplicationContext(),RecyclerView.HORIZONTAL, false);
        auto_texts.setLayoutManager(horizontal);

        chartsAdapter = new ChartsAdapter(modeClassesArrayList, Charts.this);
        chart_recycle.setAdapter(chartsAdapter);

        //Auto texts
        autoAdapter = new AutoAdapter(getApplicationContext(),list);
        auto_texts.setAdapter(autoAdapter);
        addInputs();

        BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(Charts.this);
        mic_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                bottomSheetDialog.setContentView(R.layout.record);
                bottomSheetDialog.show();
            }
        });

        message_text.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                if (charSequence.toString().trim().length()==0){
                    mic_button.setVisibility(View.VISIBLE);
                    send_btn.setVisibility(View.GONE);
                }else {
                    send_btn.setVisibility(View.VISIBLE);
                    mic_button.setVisibility(View.GONE);
                }
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
               if (charSequence.toString().trim().isEmpty()){
//                   Toast.makeText(getApplicationContext(),"Enter text",Toast.LENGTH_LONG).show();
                   mic_button.setVisibility(View.VISIBLE);
                   send_btn.setVisibility(View.GONE);
               }else {
                   send_btn.setVisibility(View.VISIBLE);
                   mic_button.setVisibility(View.GONE);
               }
            }

            @Override
            public void afterTextChanged(Editable editable) {

                if (editable.toString().length()==0){
                    mic_button.setVisibility(View.VISIBLE);
                    send_btn.setVisibility(View.GONE);
                }
            }
        });


        send_btn.setOnClickListener(view -> {
            if (message_text.getText().toString().isEmpty()) {
                Toast.makeText(Charts.this, "Please enter text..", Toast.LENGTH_SHORT).show();
            }

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                returnResponse(message_text.getText().toString());
            }
            message_text.setText("");
        });

    }



    @SuppressLint("NotifyDataSetChanged")
    private void returnResponse(String message) {

        modeClassesArrayList.add(new ChartModeClass(message, USER_KEY));
        chartsAdapter.notifyDataSetChanged();
        chart_recycle.scrollToPosition(modeClassesArrayList.size()-1);

        String url = "http://xxxxxxxxxxxxxxxx"+message;
        String BASE_URL = "https://xxxxxxxxx";
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
        Call<MessageModeClass> call = retrofitApi.getMessage(url);

        call.enqueue(new Callback<MessageModeClass>() {
            @Override
            public void onResponse(@NonNull Call<MessageModeClass> call, @NonNull Response<MessageModeClass> response) {
                if (response.isSuccessful()) {
                    MessageModeClass messageModeClass = response.body();
                    if (messageModeClass != null) {
                        modeClassesArrayList.add(new ChartModeClass(messageModeClass.getCnt(), BOT_KEY));
                    }
                    chartsAdapter.notifyDataSetChanged();
                    chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);

                } else {
                    Toast.makeText(Charts.this, "response is null", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(@NonNull Call<MessageModeClass> call, @NonNull Throwable t) {
                modeClassesArrayList.add(new ChartModeClass("No response check your network connection!", BOT_KEY));
                chartsAdapter.notifyDataSetChanged();
                chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
            }
        });

    }



    @SuppressLint("NotifyDataSetChanged")
    @Override
    protected void onStart() {
        super.onStart();

        String lang = getIntent().getExtras().getString("lang");
        if (lang.equals("english")){

            modeClassesArrayList.add(new ChartModeClass("Hey welcome back am fema bot", BOT_KEY));
            chartsAdapter.notifyDataSetChanged();
            chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);

        }else if (lang.equals("swahili")){
            modeClassesArrayList.add(new ChartModeClass("Habari karibu miminni bot niliyetengenezw", BOT_KEY));
            chartsAdapter.notifyDataSetChanged();
            chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
        }else {
            modeClassesArrayList.add(new ChartModeClass("Hey welcome back am fema bot", BOT_KEY));
            chartsAdapter.notifyDataSetChanged();
            chart_recycle.scrollToPosition(modeClassesArrayList.size() - 1);
        }

    }


    private void addInputs() {
        Texts text1 = new Texts("gender?");
        Texts text2 = new Texts("gender equality");
        Texts text3 = new Texts("what is good about females");
        Texts text4 = new Texts("un goals");
        Texts text5 = new Texts("about men");

        list.addAll(Arrays.asList(new Texts[]{text1,text2,text3,text4,text5}));
    }
}

here is my Adapter class class codes

public class AutoAdapter extends RecyclerView.Adapter<AutoAdapter.ViewHolderClass> {
    Context context;
    List<Texts> list;


    public AutoAdapter(Context context, List<Texts> list) {
        this.context = context;
        this.list = list;
    }


    @NonNull
    @Override
    public ViewHolderClass onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_list,parent,false);
        ViewHolderClass viewHolderClass = new ViewHolderClass(view);

        return viewHolderClass;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolderClass holder, @SuppressLint("RecyclerView") int position) {
        holder.input_text.setText(list.get(position).getText());

        holder.input_text.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               // my stack
            }
        });
    }


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

    public class ViewHolderClass extends RecyclerView.ViewHolder {

        TextView input_text;

        public ViewHolderClass(@NonNull View itemView) {
            super(itemView);
            input_text = itemView.findViewById(R.id.input_text);
        }
    }

}


Solution 1:[1]

You can add a list of your recommendations in another RecyclerView Then in the ViewHolder of each item of the RecyclerView add Callback to listen on click events when a user clicks one of the item like the following


public class ViewHolderClass extends RecyclerView.ViewHolder {

    private TextView input_text;
    private final Callback callback; // custom callback

    public ViewHolderClass(@NonNull View itemView, Callback callback) {
        super(itemView);
        this.callback = callback;
        input_text = itemView.findViewById(R.id.input_text);

        // now add onClickListener of the itemView to fire custom callback
        itemView.setOnClickListener(view -> {
           this.callback.onItemClick(getAdapterPosition());
        });
    }

    // this is my custom callback for return click event
    public interface Callback {
       void onItemClick(int position);
    }
}

Now inside your adapter add the callback from viewholder


public class AutoAdapter extends RecyclerView.Adapter<AutoAdapter.ViewHolderClass> {
    private Context context;
    private List<Texts> list;
    private AutoAdapterCallback callback;


    public AutoAdapter(Context context, List<Texts> list) {
        this.context = context;
        this.list = list;
    }
    
    public setCallback(AutoAdapterCallback callback) {
        this.callback = callback;
    }

    @NonNull
    @Override
    public ViewHolderClass onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_list,parent,false);
        ViewHolderClass viewHolderClass = new ViewHolderClass(view, new ViewHolderClass.Callback() {
        @Override
        public void onItemClick(int position) {
            // forward callback to adapter callback
            if (callback != null) {
               // get actual item from its position
               final Texts texts = getItemByPosition(position);
               // send to adapter callback
               callback.onItemClick(texts);
            }
        });

        return viewHolderClass;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolderClass holder, @SuppressLint("RecyclerView") int position) {
        holder.input_text.setText(list.get(position).getText());

        // I haven't used this inteady I added callback on viewholder side
        // holder.input_text.setOnClickListener(new View.OnClickListener() {
        //     @Override
        //     public void onClick(View view) {
        //        // my stack
        //     }
        // });
    }


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

    // return Texts object by given position
    public Texts getItemByPosition(int position) {
        return this.list.get(position);
    }
    
    // add adapter callback to be called by viewholder
    public interface AdapterCallback {
        void onItemClick(Texts texts);
    }
}

After that, now on your Activity you can easily listen on any item when a user clicks and get its corresponding Texts object from list as following:


//code ...

// here 

//Auto texts
autoAdapter = new AutoAdapter(getApplicationContext(),list);

//set callback to listen for click events
autoAdapter.setCallback(new AutoAdapter.AutoAdapterCallback() {
     @Override
     public void onItemClick(Texts texts) {
        // you can get your clicked item here
        // now you can put texts object to another RecyclerView :)
     }
});

auto_texts.setAdapter(autoAdapter);

//code ...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mussa Charles