In this tutorial I am explaining how to implement multiple layout in a single RecyclerView
Add ‘com.android.support:recyclerview‘ in Gradle dependencies and sync it (Check this tutorial for Recycler View example https://wiki.workassis.com/android-recyclerview-example/)
MainActivity
package samples.bm.com.myapplication; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.widget.Toast; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; public class MainActivity extends AppCompatActivity implements MyMediatorInterface { private MyAdapter mAdapter; private ArrayList<ItemInterface> mUsersAndSectionList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); ArrayList<UserModel> usersList = new ArrayList<>(); try { usersList.add(new UserModel("Jos", "123546567", sdf.parse("2016-1-1"))); usersList.add(new UserModel("Kiran", "456546456", sdf.parse("2016-1-1"))); usersList.add(new UserModel("Manu", "5678", sdf.parse("2016-3-31"))); usersList.add(new UserModel("Roy", "67443453", sdf.parse("2016-1-31"))); usersList.add(new UserModel("Musthu", "456353", sdf.parse("2016-1-31"))); usersList.add(new UserModel("Jaffer", "4644", sdf.parse("2016-1-31"))); } catch (ParseException e) { e.printStackTrace(); } mUsersAndSectionList = new ArrayList<>(); getSectionalList(usersList); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv_my_recycler_view); recyclerView.setHasFixedSize(true); final GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2); gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { if (MyAdapter.SECTION_VIEW == mAdapter.getItemViewType(position)) { return 2; } return 1; } }); recyclerView.setLayoutManager(gridLayoutManager); mAdapter = new MyAdapter(mUsersAndSectionList, this); recyclerView.setAdapter(mAdapter); } private void getSectionalList(ArrayList<UserModel> usersList) { Collections.sort(usersList, new Comparator<UserModel>() { @Override public int compare(UserModel user1, UserModel user2) { return user1.jDate.compareTo(user2.jDate) > 0 ? 1 : 0; } }); String lastHeader = ""; int size = usersList.size(); for (int i = 0; i < size; i++) { UserModel user = usersList.get(i); String header = getSimpleDate(user.jDate); if (!TextUtils.equals(lastHeader, header)) { lastHeader = header; mUsersAndSectionList.add(new GroupTitleModel(header)); } mUsersAndSectionList.add(user); } } public static String getSimpleDate(Date date) { SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy"); String stringdate = format.format(date); return stringdate; } @Override public void userItemClick(int pos) { Toast.makeText(MainActivity.this, "Clicked User : " + ((UserModel) mUsersAndSectionList.get(pos)).name, Toast.LENGTH_SHORT).show(); } }
MyMediatorInterface
package samples.bm.com.myapplication; public interface MyMediatorInterface { void userItemClick(int pos); }
MyAdapter
package samples.bm.com.myapplication; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import java.lang.ref.WeakReference; import java.util.ArrayList; public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public static final int SECTION_VIEW = 0; public static final int CONTENT_VIEW = 1; ArrayList<ItemInterface> mUsersAndSectionList; WeakReference<Context> mContextWeakReference; public MyAdapter(ArrayList<ItemInterface> usersAndSectionList, Context context) { this.mUsersAndSectionList = usersAndSectionList; this.mContextWeakReference = new WeakReference<Context>(context); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { Context context = mContextWeakReference.get(); if (viewType == SECTION_VIEW) { return new SectionViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item_group_title, parent, false)); } return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_user_item, parent, false), context); } @Override public int getItemViewType(int position) { if (mUsersAndSectionList.get(position).isSection()) { return SECTION_VIEW; } else { return CONTENT_VIEW; } } @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { Context context = mContextWeakReference.get(); if (context == null) { return; } if (SECTION_VIEW == getItemViewType(position)) { SectionViewHolder sectionViewHolder = (SectionViewHolder) holder; GroupTitleModel sectionItem = ((GroupTitleModel) mUsersAndSectionList.get(position)); sectionViewHolder.title.setText(sectionItem.title); return; } MyViewHolder myViewHolder = (MyViewHolder) holder; UserModel currentUser = ((UserModel) mUsersAndSectionList.get(position)); myViewHolder.TvName.setText(currentUser.name); myViewHolder.TvPhone.setText(currentUser.phone); } @Override public int getItemCount() { return mUsersAndSectionList.size(); } //holder public static class MyViewHolder extends RecyclerView.ViewHolder { public TextView TvName, TvPhone; public LinearLayout ll; public MyViewHolder(View itemView, final Context context) { super(itemView); TvName = (TextView) itemView.findViewById(R.id.tv_name); TvPhone = (TextView) itemView.findViewById(R.id.tv_phone); ll = (LinearLayout) itemView.findViewById(R.id.ll_layout); ll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ((MainActivity) context).userItemClick(getAdapterPosition()); } }); } } public class SectionViewHolder extends RecyclerView.ViewHolder { TextView title; public SectionViewHolder(View itemView) { super(itemView); title = (TextView) itemView.findViewById(R.id.tv_group_title); } } }
GroupTitleModel
package samples.bm.com.myapplication; public class GroupTitleModel implements ItemInterface { public String title; public GroupTitleModel(String title) { this.title = title; } @Override public boolean isSection() { return true; } }
UserModel
package samples.bm.com.myapplication; import java.util.Date; public class UserModel implements ItemInterface{ public String name; public String phone; public Date jDate; public UserModel(String name, String phone, Date jDate) { this.name = name; this.phone = phone; this.jDate = jDate; } @Override public boolean isSection() { return false; } }
ItemInterface
package samples.bm.com.myapplication; public interface ItemInterface { boolean isSection(); }
Layouts
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="samples.bm.com.myapplication.MainActivity" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> <android.support.v7.widget.RecyclerView android:id="@+id/rv_my_recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:clipToPadding="false"/> </LinearLayout>
row_item_group_title.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#f9aaaa" android:padding="5dp"> <TextView android:id="@+id/tv_group_title" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
row_user_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ll_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:layout_gravity="center" android:layout_width="100dp" android:layout_height="100dp" android:src="@mipmap/ic_launcher"/> <TextView android:id="@+id/tv_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="center" android:text="name"/> <TextView android:id="@+id/tv_phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="center" android:text="23423424242"/> </LinearLayout>
Output