In my application i am using recyclerview to display all contact list. I want two section in recyclerview.
Like one section is my application contact list and second
Take a look at my library on Github, can be used to easily create sections: RecyclerAdapter & Easy Section
mRecylerView.setLayoutManager(...);
/*create Adapter*/
RecyclerAdapter<Customer> baseAdapter = new RecyclerAdapter<>(...);
/*create sectioned adapter. the Adapter type can be RecyclerView.Adapter*/
SectionedAdapter<String, RecyclerAdapter> adapter = new SectionedAdapter<>(SectionViewHolder.class, baseAdapter);
/*add your sections*/
sectionAdapter.addSection(0/*position*/, "Title Section 1");
/*attach Adapter to RecyclerView*/
mRecylerView.setAdapter(sectionAdapter);
Hope it helps.
If you already have a RecyclerView
, an easy way to implement the sections is using Gabriele Mariotti's SimpleSectionedRecyclerViewAdapter.
I paste you his example:
//Your RecyclerView
mRecyclerView = (RecyclerView) findViewById(R.id.list);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.addItemDecoration(new DividerItemDecoration(this,LinearLayoutManager.VERTICAL));
//Your RecyclerView.Adapter
mAdapter = new SimpleAdapter(this,sCheeseStrings);
//This is the code to provide a sectioned list
List<SimpleSectionedRecyclerViewAdapter.Section> sections =
new ArrayList<SimpleSectionedRecyclerViewAdapter.Section>();
//Sections
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(0,"Section 1"));
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(5,"Section 2"));
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(12,"Section 3"));
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(14,"Section 4"));
sections.add(new SimpleSectionedRecyclerViewAdapter.Section(20,"Section 5"));
//Add your adapter to the sectionAdapter
SimpleSectionedRecyclerViewAdapter.Section[] dummy = new SimpleSectionedRecyclerViewAdapter.Section[sections.size()];
SimpleSectionedRecyclerViewAdapter mSectionedAdapter = new
SimpleSectionedRecyclerViewAdapter(this,R.layout.section,R.id.section_text,mAdapter);
mSectionedAdapter.setSections(sections.toArray(dummy));
//Apply this adapter to the RecyclerView
mRecyclerView.setAdapter(mSectionedAdapter);
Let me try to propose a native solution.
You must have a list of Contacts with a flag of isFavourite like
private class Contacts{
private String name;
private String phoneNumber;
private boolean isFavourite;
}
sort that array on the basis of isFavourite and contactName like this
pass that list to your ContactRecyclerAdapter. and Use two different layouts for Header and Items like this
In your adapter getItemViewType Layout like this ....
@Override
public int getItemViewType(int position) {
if (mCountriesModelList.get(position).isSection) {
return SECTION_VIEW;
} else {
return CONTENT_VIEW;
}
}
https://github.com/sayanmanna/LetterSectionedRecyclerView
If you are looking for a solution that doesn't need to use hardcoded header/row indexes, you can use the library SectionedRecyclerViewAdapter.
First create a Section class to group your items:
class MySection extends StatelessSection {
String title;
List<String> list;
public MySection(String title, List<String> list) {
// call constructor with layout resources for this Section header, footer and items
super(R.layout.section_header, R.layout.section_item);
this.title = title;
this.list = list;
}
@Override
public int getContentItemsTotal() {
return list.size(); // number of items of this section
}
@Override
public RecyclerView.ViewHolder getItemViewHolder(View view) {
// return a custom instance of ViewHolder for the items of this section
return new MyItemViewHolder(view);
}
@Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) {
MyItemViewHolder itemHolder = (MyItemViewHolder) holder;
// bind your view here
itemHolder.tvItem.setText(list.get(position));
}
@Override
public RecyclerView.ViewHolder getHeaderViewHolder(View view) {
return new SimpleHeaderViewHolder(view);
}
@Override
public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) {
MyHeaderViewHolder headerHolder = (MyHeaderViewHolder) holder;
// bind your header view here
headerHolder.tvItem.setText(title);
}
public void addRow(String item) {
this.list.add(item);
}
}
Then you set up the RecyclerView with your Sections:
// Create an instance of SectionedRecyclerViewAdapter
SectionedRecyclerViewAdapter sectionAdapter = new SectionedRecyclerViewAdapter();
// Create your sections with the list of data
MySection favoritesSection = new MySection("Favorites", favoritesList);
MySection contactsSection = new MySection("Add Favorites", contactsList);
// Add your Sections to the adapter
sectionAdapter.addSection(favoritesSection);
sectionAdapter.addSection(contactsSection);
// Set up your RecyclerView with the SectionedRecyclerViewAdapter
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(sectionAdapter);
You can also add new rows to your sections without having to recalculate indexes:
favoritesSection.addRow("new item");
sectionAdapter.notifyDataSetChanged();
Alternative to using any third party library or using custom logic to add header to RecyclerView
, there is a much simpler solution using Android SDK. You can simply use ExpandableListView
. You might be thinking that it makes the list collapsible, but there is a very simple thing which you can do to avoid the same. In the adapter class for ExpandableListView
, in the getGroupView
method, simply add the following line:
(parent as ExpandableListView).expandGroup(groupPosition)
The method would look something like this:
override fun getGroupView(groupPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup?): View {
var view = convertView
if (convertView == null) {
val layoutInflater = context
.getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater
view = layoutInflater.inflate(R.layout.group_view, null)
}
/*
Code to populate your data
*/
// The following code will expand the group whenever the group view is inflated
(parent as ExpandableListView).expandGroup(groupPosition)
return view
}
This works simply due to the way how ExpandableListView
adapter works. Whenever you try to collapse a group header, it calls the getGroupView
method(so that you can inflate a different view for expanded/collapsed state). But you are expanding the group in that method, hence the view never actually collapses, effectively giving you a sectioned list appearance.
Expect for the one line mentioned above, all other part of the same is exactly as you would do with a normal ExpandableListView
, hence there is no additional bit of customisation you need to do.