Today I would like to talk about using different row layouts using RecyclerView.

Multiple row layouts using RecyclerView screen

Firstly need to add some dependencies to build.gradle file for using cardView and RecyclerView. For it need to update dependency section in this file:

compile 'com.android.support:cardview-v7:23.2.0'
compile 'com.android.support:recyclerview-v7:23.2.0'

Right now we can start working with RecyclerView. In this short tutorial I’ll create list with Cities and Events. Contain different object in the same list not better idea, but for simple tutorial I hope it’s OK:)

If you want to use different types of row layouts you must to implement next method in adapter:
[java]
@Override
public int getItemViewType(int position) {

}
[/java]

Firstly we can create two different layouts for our recycler view.

item_city
[xml]



[/xml]

item_event
[xml]



[/xml]

Next step is creating a model and dummy data for the application. Firstly need to create the model class which called CityEvent.
[java]
public class CityEvent {
public static final int CITY_TYPE = 0;
public static final int EVENT_TYPE = 1;

private String mName;
private String mDescription;
private int mType;

public CityEvent(String name, String description, int type) {
this.mName = name;
this.mDescription = description;
this.mType = type;
}

public String getName() {
return mName;
}

public void setName(String name) {
this.mName = name;
}

public String getDescription() {
return mDescription;
}

public void setDescription(String description) {
this.mDescription = description;
}

public int getType() {
return mType;
}

public void setType(int type) {
this.mType = type;
}
}
[/java]

After it I created DummyData class.
[java]
public final class DummyData {

public static List getData() {
List list = new ArrayList<>();
list.add(new CityEvent(“London”, null, CityEvent.CITY_TYPE));
list.add(new CityEvent(“Droidcon”, “Droidcon in London”, CityEvent.EVENT_TYPE));
list.add(new CityEvent(“Some event”, “Some event in London”, CityEvent.EVENT_TYPE));
list.add(new CityEvent(“Amsterdam”, null, CityEvent.CITY_TYPE));
list.add(new CityEvent(“Droidcon”, “Droidcon in Amsterdam”, CityEvent.EVENT_TYPE));
list.add(new CityEvent(“Berlin”, null, CityEvent.CITY_TYPE));
list.add(new CityEvent(“Droidcon”, “Droidcon in Berlin”, CityEvent.EVENT_TYPE));
return list;
}
}
[/java]

After it we can implement adapter for recycler view. This class called DifferentRowAdapter.
[java]
public class DifferentRowAdapter extends RecyclerView.Adapter {

private List mList;

public DifferentRowAdapter(List list) {
this.mList = list;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;

switch (viewType) {
case CITY_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_city, parent, false);
return new CityViewHolder(view);
case EVENT_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_event, parent, false);
return new EventViewHolder(view);
}
return null;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
CityEvent object = mList.get(position);
if (object != null) {
switch (object.getType()) {
case CITY_TYPE:
((CityViewHolder) holder).mTitle.setText(object.getName());
break;
case EVENT_TYPE:
((EventViewHolder) holder).mTitle.setText(object.getName());
((EventViewHolder) holder).mDescription.setText(object.getDescription());
break;
}
}
}

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

@Override
public int getItemViewType(int position) {
if (mList != null) {
CityEvent object = mList.get(position);
if (object != null) {
return object.getType();
}
}
return 0;
}

public static class CityViewHolder extends RecyclerView.ViewHolder {
private TextView mTitle;

public CityViewHolder(View itemView) {
super(itemView);
mTitle = (TextView) itemView.findViewById(R.id.titleTextView);
}
}

public static class EventViewHolder extends RecyclerView.ViewHolder {
private TextView mTitle;
private TextView mDescription;

public EventViewHolder(View itemView) {
super(itemView);
mTitle = (TextView) itemView.findViewById(R.id.titleTextView);
mDescription = (TextView) itemView.findViewById(R.id.descriptionTextView);
}
}
}
[/java]

The last step is updating MainActivity.
[java]
public class MainActivity extends AppCompatActivity {

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

@Override
protected void onStart() {
super.onStart();

DifferentRowAdapter adapter = new DifferentRowAdapter(DummyData.getData());

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, OrientationHelper.VERTICAL, false);
RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setAdapter(adapter);
}
}
[/java]

Full source code you can find on Github.

Thank you for you time. I hope it was helpful for you.
Have a nice day.

30 CommentsClose Comments

30 Comments

  • kinsleykajiva
    Posted June 26, 2016 at 2:45 pm 0Likes

    hi,guys this has just been a great tutorial…you have no idea how simple and easy you have made it for me to make sectioned recyclerview now i get the whole concept.

    THANK YOU!!!!!

  • kylexy
    Posted September 4, 2016 at 10:47 pm 0Likes

    thanks alot for tutorial but how do we implement on click with it thanks in advance

    • Posted November 13, 2016 at 7:59 am 0Likes

      You can to add this code to required ViewHolder class:
      itemView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {

      }
      });

      Or you can pass listener object to adapter. And handle listener event from activity, fragment, etc

      • Manish Singh
        Posted December 13, 2017 at 6:15 am 0Likes

        Thanks for tutorial.
        Could you highlight some info
        regarding item click event.

        eg :
        Today
        item list sorted according to above date
        2 Dec 2017
        item list sorted according to above date
        ……n

        so my problem is I want to pass itemList from selected header i.e. (date) to another fragment . but there is always index bound exception occurs.

        i’ve used hashmap for grouping data according to dates.

        • Posted January 16, 2018 at 7:01 pm 0Likes

          I don’t know exactly, because I need more information. Maybe you have problem with last item(s) in your HashMap, because you have header in addition to items

  • Daniel
    Posted October 21, 2016 at 6:37 pm 0Likes

    Hi!, excellent tutorial!!, quick question, how can we add click events to this tutorial?

    • Posted November 13, 2016 at 7:59 am 0Likes

      You can to add this code to required ViewHolder class:
      itemView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {

      }
      });
      Or you can pass listener object to adapter. And handle listener event from activity, fragment, etc

  • Hitesh
    Posted December 26, 2016 at 6:45 am 0Likes

    Nice Tutorial Simply Perfect

  • Akii
    Posted January 14, 2017 at 8:30 am 0Likes

    Lovely post buddy. I am searching for this from long time. I don’t want to use dependancy that make project complicated. Its excellent and clear tutorial.

  • Gojira
    Posted January 20, 2017 at 7:53 pm 0Likes

    Thank you so much!!

  • Gojira
    Posted January 25, 2017 at 3:45 am 0Likes

    Can you help me with this?
    Your code worked fine. But i wanna bring Firebase data right now, and put into this arrayList. How can i do that? here is the 3 retrievings (it’s working):

    databaseReference1.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {

    for (DataSnapshot dados : dataSnapshot.getChildren()) {
    Reuniao reuniao = dados.getValueReuniao.class);

    // The values i want to put into the arrayList

    idFinalReuniao = reuniao.getIdDataHoraReuniao();
    clienteReuniao = reuniao.getCliente();
    objetivoReuniao = reuniao.getObjetivo();
    horaReuniao = reuniao.getHora();
    dataReuniao = reuniao.getData();
    localReuniao = reuniao.getLocal();
    extrasReuniao = reuniao.getExtras();

    @Override
    public void onCancelled(DatabaseError databaseError) {
    }
    });

    _____________________________________________________________

    databaseReference2.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {

    for (DataSnapshot dados : dataSnapshot.getChildren()) {
    Processo processo = dados.getValue(Processo.class);

    // The values i want to put into the arrayList
    idFinalProcesso = processo.getIdDataHoraProcesso();
    numeroProcesso = processo.getNumero();
    clienteProcesso = processo.getCliente();
    naturezaProcesso = processo.getNatureza();
    dataProcesso = processo.getData();
    extrasProcesso = processo.getExtras();

    //onCancelled
    ______________________________________________________________

    databaseReference3.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {

    for (DataSnapshot dados : dataSnapshot.getChildren()) {
    Audiencia audiencia= dados.getValue(Audiencia.class);

    // The values i want to put into the arrayList
    idFinalAudiencia = audiencia.getIdDataHoraAudiencia();
    processoAudiencia = audiencia.getProcesso();
    clienteAudiencia = audiencia.getCliente();
    naturezaAudiencia = audiencia.getNatureza();
    dataAudiencia = audiencia.getData();
    horaAudiencia = audiencia.getHora();
    extrasAudiencia = audiencia.getExtras();

    //onCancelled

    _______________________________________________________________

    Like you did the CityEvent class, i did one with the data that you see above on the retrieving. Here it is:

    public class DadosFeed {

    public static final int REUNIAO_TYPE = 0;
    public static final int AUDIENCIA_TYPE = 1;
    public static final int PROCESSO_TYPE = 2;
    private int type;

    //private String usuario_id;

    private String idAtividade;
    private String cliente;
    private String objetivo;
    private String hora;
    private String data;
    private String local;
    private String extras;
    private String processo;
    private String natureza;

    public DadosFeed( String idAtividade, String cliente, String objetivo, String hora,
    String data, String local, String extras, String processo, String natureza, int type){
    this.idAtividade = idAtividade;
    this.cliente = cliente;
    this.objetivo = objetivo;
    this.hora = hora;
    this.data = data;
    this.local = local;
    this.extras = extras;
    this.processo = processo;
    this.natureza = natureza;
    this.type = type;

    }

    What can i do to put this data into an arrayList? Please, i really need the answer.
    Thank you!

  • Shreyas
    Posted March 23, 2017 at 4:06 pm 0Likes

    This is Wonderful…. Thank you 🙂

  • CJ
    Posted April 2, 2017 at 1:52 pm 0Likes

    Thank you so much for this.

    But I have a question. Because of the ability to create dynamic amounts of “headers”, I noticed that they take up positions.

    I’m implementing an “onItemClick” feature, similar to listviews, but I’m finding out that each header in the view takes a position.

    How can I create an argument to remove header positions?

    Thank you again!

    • Posted April 16, 2017 at 9:36 am 0Likes

      It will be really complicated, but you can send a Map or List with type of each item, as example

      • garima
        Posted May 31, 2017 at 1:39 am 0Likes

        here you are adding data statically in the list now i want to add data in list dynamically (i m retrieving data from database).I have list of array which contains row item but i m unable to use it in DummyData .so ,how it can be possible to use array in it

        • Posted June 14, 2017 at 5:56 pm 0Likes

          Try to use Map. You can use Map

  • Nikos
    Posted May 8, 2017 at 10:35 am 0Likes

    Thank you very much for the tutorial. But i have a question. Although, everything seems to work perfect with debugging only the first two items appear. The only difference in my code is that i call the adapter from a fragment.Is this the possible problem?

    • Posted June 14, 2017 at 5:51 pm 0Likes

      Try to check the getItemCount() method or a constructor.

  • jhon
    Posted July 17, 2017 at 1:57 pm 0Likes

    tnx.

    I have a problem.I used a layoutAdapter with 3 items in one row.
    I managed to fill them by using some tricks like 3*position 3*position+1 and …
    But in order to implement recycler touch listener , on every 3 items in a row i click
    i get a same position. Please Help.

    • Posted November 23, 2017 at 8:12 pm 0Likes

      I think you can also provide row position in your callback

  • Safan
    Posted July 28, 2017 at 11:17 am 0Likes

    Hi, great tutorial! just wanted to ask how do I create dividers in listview under each section?

    • Posted November 23, 2017 at 8:11 pm 0Likes

      Do you mean recyclerView?

  • Khalil
    Posted October 20, 2017 at 7:17 pm 0Likes

    Thanks a lot mate. Have been looking for it. Tried many examples but yours is so much good and easy. Thanks once again.

  • Mendhie Emmanuel
    Posted February 7, 2018 at 8:07 am 0Likes

    Thanks for this tutorial. Really helpful.
    But assuming you’re getting the data from Firebase, how will you implement it?

    Let’s say the database looks like this:

    Events: {
    “London”:{
    “Event 1”:{
    “name”: “Droid”,
    “description”: “Droid party in London”},
    “Event 2”:{
    “name”: “Firebase”,
    “description”: “Firebase lecture in London}
    },

    “Amsterdam”:{
    “Event 1”:{
    “name”: “ios”,
    “description”: “ios party with Tim Cook”},
    “Event 2”:{
    “name”: “Firebase”,
    “description”: “Firebase lecture in Amsterdam}
    }
    }

    How do you implement the Event database using Even location as header?

    • Posted July 30, 2018 at 8:00 pm 0Likes

      Hello, thank you for your comment.
      In the case of the database for an event, I can propose the model class which can be used for the Room library, or you can create a database using the idea of this class.

      data class Location(
      val city: String
      )

      data class Event(
      val name: String,
      val description: String,
      val eventLocation: Location
      )

      It’s the simplest solution. However, you can use another structure of the database.

  • Robocop
    Posted March 17, 2018 at 10:27 am 0Likes

    Hi, I was wondering is there a way to make an even deeper sectionedView? For example, when I click on DroidCon for the view to expand even more containing subitems for DroidCon? Can you do a tutorial for that please! =)

    • Posted July 30, 2018 at 8:06 pm 0Likes

      Hi, thank you for the comment.

      Creating a more in-depth expanded list is possible. However, it can be complicated for the end user, because it requires a long way from the category to the description (Category – Event – Description).

      I’ll re-think this example and create a tutorial for this in future.

  • Johana Marcela López Parra
    Posted April 3, 2018 at 4:38 pm 0Likes

    Thank you so much 🙂

  • blackblood
    Posted August 30, 2018 at 8:30 am 0Likes

    Thank you

  • Alex Nordeen
    Posted November 12, 2019 at 4:55 am 0Likes

    Hi,

    Sorry to intrude your mailbox.

    I saw you linked to http://junit.org/junit4/ from https://alexzh.com/2016/03/24/android-testing-unit-testing/

    I would like to bring to your attention a resource I recently created – Guru99. https://www.guru99.com/junit-tutorial.html The content is up to date and very in-depth.

    Thought you might like this one.

    Thanks!
    Alex

Leave a comment

Newsletter Subscribe

Get the Latest Posts & Articles in Your Email

We Promise Not to Send Spam:)