Expandable List using ListAdapter – Android

Tram Ho

Today I want to share with you an example of Expandable List using ListAdapter + Data Binding and multi-type in RecyclerView .

You can refer to my source code here !

I’m using Gradle 6.5 and Android Studio 4.1 .

This example will display a list of Sections, when we tap on a Section it will expand and display its Items.

Dependencies

First we will need some dependencies in the module’s build.gradle like so:

Section Model

We will have a Section model containing the following information:

You pay attention to the following 2 properties:

  • isExpandable : Defines isExpandable state. true if minimizing, false if expanding.
  • items : The list of items to display when the list expands.

Here I encourage to use data class to facilitate compare in DiffUtil later.

ViewHolder

Next, we will have 2 ViewHolder to display for the Section and its Item :

SectionViewHolder

I will create a layout item_section.xml containing a TextView to display the name of the Section and an AppCompatImageView to display the expand icon, which changes according to isExpandable in the Section model.

I have added a BindingAdapter is sectionExpandable to update icons expand when isExpandable change.

To display Section Item , I will build another ViewHodder :

SectionItemViewHolder

For Section Item, I only need a TextView to display the name of that Item.

ListAdapter

Now, we will handle ListAdapter to integrate with the above ViewHolder .

The reason I use ListAdapter is that it integrates DiffUtil to compare the differences of the submitted list. You can refer to here .

First, we will need to give it a DiffUtil.ItemCallback like this:

In the Adapter there will be 2 types, one for Section and one for Section Item.

To be able to display these 2 types in RecyclerView , the Adapter needs to define them through override getItemViewType(_: Int) : Int method.

Next, we will create ViewHolder generals corresponding to the defined ViewType and bind data for them.

MainViewModel

Now, I will use the ViewModel to process the data for the Section as well as update the Section list as there is action expanding.

MainViewModel class will look like this:

  • getSectionList() : Random a Section list
  • expand(_: Int) : Updates the status when a section expading.
  • refresh() : Refresh the Section list.

Finally we will apply all of them to RecyclerView in MainActivity .

MainActivity

activity_main.xml

In activity_main.xml layout, I only have a RecyclerView and SwipeRefreshLayout serving to refresh the Section list.

  • app:onRefreshListener="@{() -> viewModel.refresh()}" receives the refresh action from the user and calls the refresh() method.
  • app:refreshing="@{viewModel.isRefreshing()}" shows loading icon under isRefreshing() .
  • app:sectionList="@{viewModel.sectionListLiveData}" is a BindingAdapter I defined in MainActivity.Binding , to submit a new list when sectionListLiveData changed.

MainActivity

In the BindingAdapter sectionList , I will check isExpandable to either add or not add the section item.

When isExpandable is false , which means expanding, we will add Section Items. And vice versa, we only add Sections.

Apprehend

I have finished introducing an example of Expandable List. Maybe this is not the best way to handle this problem. But hope it helps a little bit for you.

If there are any problems or suggestions for the article, please comment below …

Thank you for reading here.

Thank you and Happy coding !!!

Source Code

Share the news now

Source : Viblo