RecyclerView in Android has been the defacto for viewing lists in android. The solid performance and the ability to plugin any feature into a list without breaking a sweat made it the developer favorite. Ultimately replacing Listviews from being the standard way of displaying lists in android applications. What makes the RecyclerView the go-to library when thinking about lists?
We also need to create a nested sub-class extending the RecyclerView.ViewHolder which helps to create ViewHolders which populates data to the views present in the recyclerView. Once we wire up everything, our Custom adapter will look something similar to this.
How does a RecyclerView work?
Having a deeper understanding of the Custom RecyclerView example and the RecyclerViewAdapter will help a lot in writing efficient code. Let’s see what makes RecyclerView awesome. At the core, the view is known for it’s recycling ability of child views that help reduce memory usage (That’s where the name comes from). At first, RecyclerView initializes a set of child views to display a certain amount of contents in the list to fill the viewport of the screen. Once the user starts scrolling, the view which gets past the screen boundary is used to repopulate and reused at the other end, this is done by the Adapter.Custom RecyclerView Adapter
Before attaching a Custom Adapter to the RecyclerView, make sure you have included the RecyclerView view tags in the layout (xml) file.<RecyclerViewCreate a new XML layout file in res/layout/ with your desired layout design.
android:id="@+id/recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<?xml version="1.0" encoding="utf-8"?>Create a Java Class to hold the necessary information regarding the data objects.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="@+id/txt_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:padding="5dp"/>
<TextView
android:id="@+id/txt_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:padding="5dp"/>
</LinearLayout>
public class Contact {Now Let’s start working on the custom Adapter for the RecyclerView. Create a new Java Class extending the RecyclerView.Adapter and override the following methods from the parent class.
private String name;
private String number;
public Contact(String name, String number) {
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
We also need to create a nested sub-class extending the RecyclerView.ViewHolder which helps to create ViewHolders which populates data to the views present in the recyclerView. Once we wire up everything, our Custom adapter will look something similar to this.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ContactHolder> {You can either hardcode the values of the contact or asynchronously load the data into the list and pass it down to the adapter to do the job of displaying it in the RecyclerView.
// List to store all the contact details
private ArrayList<Contact> contactsList;
private Context mContext;
// Counstructor for the Class
public VideoListAdapter(ArrayList<Contact> contactsList, Context context) {
this.contactsList = contactsList;
this.mContext = context;
}
// This method creates views for the RecyclerView by inflating the layout
// Into the viewHolders which helps to display the items in the RecyclerView
@Override
public ContactHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
// Inflate the layout view you have created for the list rows here
View view = layoutInflater.inflate(R.layout.contact_list_item, parent, false);
return new ContactHolder(view);
}
@Override
public int getItemCount() {
return contactList == null? 0: contactList.size();
}
// This method is called when binding the data to the views being created in RecyclerView
@Override
public void onBindViewHolder(@NonNull ContactHolder holder, final int position) {
final Contact contact = contactList.get(position);
// Set the data to the views here
holder.setContactName(contact.getName());
holder.setContactNumber(contact.getNumber());
// You can set click listners to indvidual items in the viewholder here
// make sure you pass down the listner or make the Data members of the viewHolder public
}
// This is your ViewHolder class that helps to populate data to the view
public class ContactHolder extends RecyclerView.ViewHolder {
private TextView txtName;
private TextView txtNumber;
public ContactHolder(View itemView) {
super(itemView);
txtName = itemView.findViewById(R.id.txt_name);
txtNumber = itemView.findViewById(R.id.txt_number);
}
public void setContactName(String name) {
txtName.setText(name);
}
public void setContactNumber(String number) {
txtNumber.setText(number);
}
}
}
public class MainActivity extends AppCompatActivity {
private MyAdapter listAdapter;
private ArrayList<Contact> contactsList = new ArrayList<>();
private RecyclerView recycler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recycler = findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recycler.setLayoutManager(layoutManager);
listAdapter = new MyAdapter(contactsList, this);
recycler.setAdapter(listAdapter);
//Load the date from the network or other resources
//into the array list asynchronously
contactsList.add(new Contact("Daniel Shiffman", "778899009"));
contactsList.add(new Contact("Jhon Doe", "778899009"));
contactsList.add(new Contact("Jane Doe", "778899009"));
listAdapter.notifyDataSetChanged();
}
}
Custom Recycler Adapter for Multiple Views
public class Contact {Note that we are using a unique integer to note the type of view the object requires in the RecyclerView. This indicator can be used in the RecyclerView Adapter to use a specific layout with the ViewHolder. Here the Notable parts are the ViewType indicator variables in the data class (model class), the overding of <code>getItemViewType()</code> method and switching the layouts based on this on the onCreateViewHoder method.
//Add the type indicators here
public static final int TEXT_TYPE = 0;
public static final int IMAGE_TYPE = 0;
private int viewType;
private String name;
private String number;
public Contact(int viewType,String name, String number) {
this.viewType = viewType;
this.name = name;
this.number = number;
}
public int getViewType() {
return viewType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
public class MyAdapter extends RecyclerView.Adapter<RecylerView.ViewHolder> {
// List to store all the contact details
private ArrayList<Contact> contactsList;
private Context mContext;
// Counstructor for the Class
public VideoListAdapter(ArrayList<Contact> contactsList, Context context) {
this.contactsList = contactsList;
this.mContext = context;
}
// This method creates views for the RecyclerView by inflating the layout
// Into the viewHolders which helps to display the items in the RecyclerView
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
// Inflate the layout view you have created for the list rows here
// use the viewType to inflate specic Layouts for the ViewHolders
switch(viewType) {
case Contact.TEXT_TYPE:
// Inflate the first view type
View view = layoutInflater.inflate(R.layout.list_layout_1, parent, false);
return new ViewHolder1(view);
case Contact.TEXT_TYPE:
// inflate the second view type
View view = layoutInflater.inflate(R.layout.list_layout_2, parent, false);
return new ViewHolder2(view);
}
// always use a fallback ViewHolder
View view = layoutInflater.inflate(R.layout.default_list_layout, parent, false);
return new ViewHolder(view);
}
@Override
public int getItemCount() {
return contactList == null? 0: contactList.size();
}
@Override
public int getItemViewType(int position) {
int type = contactsList.get(position).getViewType();
return type;
}
// This method is called when binding the data to the views being created in RecyclerView
@Override
public void onBindViewHolder(@NonNull ContactHolder holder, final int position) {
final Contact contact = contactList.get(position);
// Set the data to the views here
holder.setContactName(contact.getName());
holder.setContactNumber(contact.getNumber());
// You can set click listners to indvidual items in the viewholder here
// make sure you pass down the listner or make the Data members of the viewHolder public
}
// This is your ViewHolder class that helps to populate data to the view
public class viewHolder1 extends RecyclerView.ViewHolder {
// Your First view holder
// Connect with the items in the layout here
}
public class viewHolder2 extends RecyclerView.ViewHolder {
// Your Second view holder
// Connect with the items in the layout here
}
}
No comments:
Post a Comment