There is an adapter that I use for several recyclerView in different fragments.

In each of the lists, I click on the elements, by clicking on which, it transfers me to activations.

 final Context context = ((View)personViewHolder.personPhoto.getParent()).getContext(); ((View)personViewHolder.personPhoto.getParent()).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent; switch (position) { case 0: intent = new Intent(context, MainActivity.class); break; case 1: intent = new Intent(context, SecondActivity.class); break; default: intent = new Intent(context, ThirdActivity.class); break; } context.startActivity(intent); } }); 

All is good, but because I use this adapter for several fragments, this option is not very suitable for me, because always clicking on the 1st item in the list takes me to the MainActivity for all fragments.

Once again, the problem : I can not for each list in different fragments implement the transition to specific activities / fragments.

Additionally, I found an option , but I don’t know how to cut it, and in general that it fits, maybe someone will suggest an idea, since with adapters I’m still on β€œYou”.

Full adapter code:

 public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder> { public static class PersonViewHolder extends RecyclerView.ViewHolder { TextView personName; TextView personAge; ImageView personPhoto; PersonViewHolder(View itemView) { super(itemView); personName = (TextView)itemView.findViewById(R.id.person_name); personAge = (TextView)itemView.findViewById(R.id.person_age); personPhoto = (ImageView)itemView.findViewById(R.id.person_photo); } } List<Person> persons; public RVAdapter(List<Person> persons){ this.persons = persons; } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); } @Override public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, viewGroup, false); PersonViewHolder pvh = new PersonViewHolder(v); return pvh; } @Override public void onBindViewHolder(PersonViewHolder personViewHolder, final int position) { personViewHolder.personName.setText(persons.get(position).name); personViewHolder.personAge.setText(persons.get(position).description); personViewHolder.personPhoto.setImageResource(persons.get(position).photoId); final Context context = ((View)personViewHolder.personPhoto.getParent()).getContext(); ((View)personViewHolder.personPhoto.getParent()).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent; switch (position) { case 0: intent = new Intent(context, MainActivity.class); break; case 1: intent = new Intent(context, TestActivity.class); break; default: intent = new Intent(context, TestActivity.class); break; } context.startActivity(intent); } }); } @Override public int getItemCount() { return persons.size(); } 

The code of one of my fragments (they only differ in the method initializeAdapter )

 public class SecondFragment extends Fragment { List<Person> persons; RecyclerView recyclerView; RecyclerView.LayoutManager layoutManager; public SecondFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_main, container, false); recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); layoutManager = new LinearLayoutManager(getContext()); recyclerView.setLayoutManager(layoutManager); recyclerView.setHasFixedSize(true); initializeData(); initializeAdapter(); return view; } private void initializeData() { persons = new ArrayList<>(); persons.add(new Person("test", "test", R.drawable.profile)); persons.add(new Person("test", "test", R.drawable.profile)); persons.add(new Person("test", "test", R.drawable.profile)); persons.add(new Person("test", "test", R.drawable.profile)); persons.add(new Person("test", "test", R.drawable.profile)); persons.add(new Person("test", "test", R.drawable.profile)); } private void initializeAdapter() { RVAdapter adapter = new RVAdapter(persons); recyclerView.setAdapter(adapter); } 

    3 answers 3

    This can be done in different ways.

    • You can change the behavior when pressed, depending on any value. This value can be set immediately in the adapter's constructor.

       public static class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder> { ... final int someFlag; .... public RVAdapter(List<Person> persons, int someFlag){ this.persons = persons; this.someFlag = someFlag; } } 

      And in the onClick method , consider this value.

      Just set this value when creating the adapter.

       adapter = new RVAdapter(persons, flag); 
    • You can also define actions in each separate fragment when you click on the elements of the list. For this you can use interfaces.

       public interface OnRVItemClickListener{ void onRVItemClick(int position); } 

      The adapter should then look like this:

       public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder> { ... final OnRVItemClickListener listener; ... public RVAdapter(List<Person> persons, OnRVItemClickListener listener){ this.persons = persons; this.listener = listener; } } ... 

      In the onClick method, we call the onRVItemClick (int position) method of this interface instance:

       @Override onClick(View v){ listener.onRVItemClick(position); } 

      And when creating an adapter in each fragment, you explicitly specify what to do when you click:

       private void initializeAdapter() { RVAdapter adapter = new RVAdapter(persons, new RVItemClickListener(){ @Override onRVItemClick(int position){ Intent intent; switch(position){ case 0: intent = .... break; case 1: intent = .... break; ..... } getActivity().startActivity(intent); } }); recyclerView.setAdapter(adapter); } 

    You can still do something else. This is the first thing that came to mind. And I think the simplest. But probably not the most elegant solution (especially the first method).

    • Thanks for the reaction, but you can have a little more specifics, because I can't transfer your idea to my application. The interface OnRVItemClickListener we declare in the fragment? Yes, and with a full adapter code, a lot of conflicts arise. - Morozov
    • @Vadim Morozov, Fixed the code. This is all inattention. - Inal Tuaev
    • when trying to add intent = new Intent (context, MainActivity.class); in the fragment, in the initializeAdapter method highlights the red context. Do not tell me how to correct? - Morozov
    • You need the context of the activity in which the fragment is located. You can get it: context = getActivity (); - Inal Tuaev
    • I declare him right in this method, after which he proposes to declare it final and the whole method breaks right away - Morozov

    RecyclerView implies not only initialization of the adapter, but also ViewHolder classes, you can use them and determine which activations should open depending on the class representing the visual, for example, this implementation:

      /** * Π’Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ Π½ΡƒΠΆΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ Π²ΠΈΠ·ΡƒΠ°Π»ΠΊΠΈ * * @param position - позиция элСмСнта * @return int - Ρ‚ΠΈΠΏ Π²ΠΈΠ·ΡƒΠ°Π»ΠΊΠΈ */ @Override public int getItemViewType(int position) { //Π² Π΄Π°Π½Π½ΠΎΠΌ случаС элСмСнты списка ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ классом, ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ ΠΈ ΠΏΠΎ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠ°ΠΊ Π²Π°ΠΌ ΡƒΠ΄ΠΎΠ±Π½Π΅Π΅ Object item = mItems.get(position); if (item instanceof Message) { return 0; } else if (item instanceof TalkItems.TalkDate) { return 1; } return -1; } /** * Π’Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ Π½ΡƒΠΆΠ½ΡƒΡŽ Π²ΠΈΠ·ΡƒΠ°Π»ΠΊΡƒ ΠΏΠΎ Π΅Ρ‘ Ρ‚ΠΈΠΏΡƒ * * @param parent - Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠ°Ρ Π²ΠΈΠ·ΡƒΠ°Π»ΠΊΠ° * @param viewType - Ρ‚ΠΈΠΏ Π²ΠΈΠ·ΡƒΠ°Π»ΠΊΠΈ * @return ViewHolder|null Π²ΠΈΠ·ΡƒΠ°Π»ΠΊΠ° */ @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(TalkActivity.this); switch (viewType) { case 0: return new MessageView( inflater.inflate(R.layout.talk_message_my, parent, false) ); case 1: return new DateView( inflater.inflate(R.layout.talk_date, parent, false) ); default: if (BuildConfig.DEBUG) { throw new AssertionError("НСизвСстный Ρ‚ΠΈΠΏ Π²ΠΈΠ·ΡƒΠ°Π»ΠΊΠΈ"); } return null; } } private class MessageView extends RecyclerView.ViewHolder { MessageView(View itemView) { super(itemView); final Context context = getApplicationContext(); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { context.startActivity(new Intent(context, MainActivity.class)); } }); } } private class DateView extends RecyclerView.ViewHolder { DateView(View itemView) { super(itemView); final Context context = getApplicationContext(); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { context.startActivity(new Intent(context, ThirdActivity.class)); } }); } } 

    If your list items have the same visual, but different β€œcontent,” you can use the following method:

     /** * Π’ Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΎΠ΄ΠΈΠ½ класс MessageView, Π½ΠΎΠ²Ρ‹ΠΉ класс Π½ΠΈΠΆΠ΅ * Π—Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰Π΅ΠΉ элСмСнта * * @param holder - пустая Π²ΠΈΠ·ΡƒΠ°Π»ΠΊΠ° * @param position - позиция элСмСнта */ @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder == null) { return; } Object item = mItems.get(position); final Context context = getApplicationContext(); MessageView mesHolder = (MessageView) holder; if (item instanceof Message) { mesHolder.view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { context.startActivity(new Intent(context, MainActivity.class)); } }); } else if (item instanceof DateItem) { mesHolder.view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { context.startActivity(new Intent(context, ThirdActivity.class)); } }); } } private class MessageView extends RecyclerView.ViewHolder { public View view; MessageView(View itemView) { super(itemView); view = itemView; } } 
    • Thank you, but I don’t really understand how to use DateView and MessageView correctly, what are they like? My lists in fragments? - Morozov
    • @VadimMorozov is not, it is the "holders" for the elements of the list, so you can for each of the types of elements register the behavior you need when you click on the element. However, if you have the same visual for them, then you can do without different "holders" and put the logic into the onBindViewHolder method (I will update it in the answer) - Nikita Leshchev
    • yes, the same. Thank you waiting. - Morozov
    • one
      @VadimMorozov here, updated. In this case, the difference in behavior comes from the type of the object, if the objects you have are of the same class, you can determine the behavior by the presence / absence of any parameters of the object or else how. - Nikita Leshchev

    1) Implement in each list list links storage. For example, public ArrayList<Intent> listMenu; , for example, in this adapter (I made it just as a BaseAdapter to make it faster)

     //это ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ public class TestAdapter extends BaseAdapter{ public ArrayList<Intent> listMenu; public Intent getMenuItem(int position, Context context) { if (position > (listMenu.size() - 1)) return new Intent(context, MainActivity.class); else return listMenu.get(position); } @Override public int getCount() { return 0; } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { return null; } } 

    2) When creating a list adapter, write down the links for this list immediately.

    3) Implement the method for retrieving the content element.

     //это ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ public Intent getMenuItem(int position, Context context) { if (position > (listMenu.size() - 1)) return new Intent(context, MainActivity.class); else return listMenu.get(position); } 

    4) When working with recyclerView, get the list object you need.

     //это ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ public void onClick(View view) { int itemPosition = mRecyclerView.getChildLayoutPosition(view); Intent intent = mRecyclerView.getAdapter().getMenuItem(context, itemPosition); context.startActivity(intent); } 

    Hope this helps you. Good luck!

    • If I understand you correctly, you propose to create a list of links for each adapter, but my idea is to use one adapter for several lists. - Morozov