https://acadgild.com/blog/expandable-recyclerview-in-android-with-examples
Expandable RecyclerView
Expandable RecyclerView is one of the most important feature in Android which can be easily created for our application using Big Nerd Ranch’s Expandable RecyclerView Library
It contains two views one is parent view and other is child view. Parent is visible by default but the child view has to be expanded and collapsed. It will expand when we click on parent view.
This feature is quite similar to the ExpandableListView in Android. Since it is an old one, it does not perform well according to our requirement.
It contains two views one is parent view and other is child view. Parent is visible by default but the child view has to be expanded and collapsed. It will expand when we click on parent view.
This feature is quite similar to the ExpandableListView in Android. Since it is an old one, it does not perform well according to our requirement.
Expandable RecyclerView View Holders
We have to create two view holders to hold the view of parent and child
- ParentViewHolder
- ChildViewHolder.
So, by using these we shall create it in our application to make it better.
build.gradle:
Add this dependency in your build.gradle file.
dependencies { compile 'com.android.support:recyclerview-v7:23.2.1' }
After adding the library, we have to add some Java classes with the help of this library like Adapter, Model, and View holders.
Expandable RecyclerView Example with Code:
Now, it’s time to do it programmatically. So here in this example we will show Movie category as a parent and movies according to the category are a child.
Create an Application Expandable RecyclerView ExampleAndroid.
Create an Application Expandable RecyclerView ExampleAndroid.
Requirements:
MainActivity.java, MovieCategory.java, MovieCategoryAdapter.java, MovieCategoryViewHolder.java, Movies.java, MoviesViewHolder.java, activity_main.xml, movie_category_view.xml, movies_view.xml.
After adding a library and some Java classes let’s do it one by one in our project.
After adding a library and some Java classes let’s do it one by one in our project.
MovieCategory.java:
Create this parent class, implements ParentListItem and override its method
Add the code here
public class MovieCategory implements ParentListItem { private List<Movies> mMovies; @Override public List<?> getChildItemList() { return mMovies; }
Here, it returns the list of movies.
Movies.java:
Create this child class it is used to show the data in each child of a parent.
Add the code here
public class Movies { private String mName; public Movies(String name) { mName = name; } public String getName() { return mName; } }
movie_category_view.xml:
Create this XML file for creating the view of movie category.
Add the code inside LinearLayout.
Add the code inside LinearLayout.
<TextView android:id="@+id/tv_movie_category" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="@dimen/standard_text_size" android:textStyle="bold"/> <ImageView android:id="@+id/iv_arrow_expand" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/selector_arrow_down"/>
It shows a text view with an arrow icon.
MovieCategoryViewHolder.java:
Create this class and extend it with ParentViewHolder. It is a class which binds the view. Here we take the reference of MovieCategory view and set the properties when it is expanded and collapsed.
Add the code here
mMovieTextView = (TextView) itemView.findViewById(R.id.tv_movie_category); mArrowExpandImageView = (ImageView) itemView.findViewById(R.id.iv_arrow_expand);
Add the code in bind(…) method
mMovieTextView.setText(movieCategory.getName());
Now, set the properties for expand and collapse of arrow image and its rotation accordingly by implementing two methods setExpanded() and onExpansionToggled().
Add the code here:
@Override public void setExpanded(boolean expanded) { super.setExpanded(expanded); if (expanded) { mArrowExpandImageView.setRotation(ROTATED_POSITION); } else { mArrowExpandImageView.setRotation(INITIAL_POSITION); } } @Override public void onExpansionToggled(boolean expanded) { super.onExpansionToggled(expanded); RotateAnimation rotateAnimation; if (expanded) { // rotate clockwise rotateAnimation = new RotateAnimation(ROTATED_POSITION, INITIAL_POSITION, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); } else { // rotate counterclockwise rotateAnimation = new RotateAnimation(-1 * ROTATED_POSITION, INITIAL_POSITION, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); } rotateAnimation.setDuration(200); rotateAnimation.setFillAfter(true); mArrowExpandImageView.startAnimation(rotateAnimation); }
movies_view.xml:
Create this XML file. It shows the view of child items.
Add the code inside LinearLayout.
Add the code inside LinearLayout.
<TextView android:id="@+id/tv_movies" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="@dimen/standard_text_size"/>
Here, it shows the name of movies with respect to the parent.
MoviesViewHolder.java:
Create this class and extend it with ChildHolder. Here, we take the reference of the child view.
Add the code here
mMoviesTextView = (TextView) itemView.findViewById(R.id.tv_movies);
Add the code in bind(..) method:
public void bind(Movies movies) { mMoviesTextView.setText(movies.getName()); }
MovieCategoryAdapter.java:
Create this custom Adapter class which extends ExpandableRecyclerAdapter. Here, it has two different sets of onCreateViewHolder and onBindViewHolder. One of which is for parent and the other for the child.
Add the codes here
@Override public MovieCategoryViewHolder onCreateParentViewHolder(ViewGroup parentViewGroup) { View movieCategoryView = mInflator.inflate(R.layout.movie_category_view, parentViewGroup, false); return new MovieCategoryViewHolder(movieCategoryView); } @Override public MoviesViewHolder onCreateChildViewHolder(ViewGroup childViewGroup) { View moviesView = mInflator.inflate(R.layout.movies_view, childViewGroup, false); return new MoviesViewHolder(moviesView); } @Override public void onBindParentViewHolder(MovieCategoryViewHolder, int position, ParentListItem parentListItem) { MovieCategory = (MovieCategory) parentListItem; movieCategoryViewHolder.bind(movieCategory); } @Override public void onBindChildViewHolder(MoviesViewHolder, int position, Object childListItem) { Movies movies = (Movies) childListItem; moviesViewHolder.bind(movies); }
activity_main.xml:
Create this XML file for RecyclerView.
Add the code inside LinearLayout.
Add the code inside LinearLayout.
<android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="match_parent"/>
MainActivity.java:
It is in our Main Activity that we pass the data, set the adapter and take the reference of Recycler View.
Add the code here
Initialize:
private MovieCategoryAdapter mAdapter; private RecyclerView recyclerView; Add the code in onCreate(..){}: Movies movie_one = new Movies("The Shawshank Redemption"); Movies movie_two = new Movies("The Godfather"); Movies movie_three = new Movies("The Dark Knight"); Movies movie_four = new Movies("Schindler's List "); MovieCategory molvie_category_one = new MovieCategory("Drama", Arrays.asList(movie_one, movie_two, movie_three, movie_four));
Like this, we can add more movie categories.
final List<MovieCategory> movieCategories = Arrays.asList(molvie_category_one, molvie_category_two, molvie_category_three,molvie_category_four); recyclerView = (RecyclerView) findViewById(R.id.recyclerview); mAdapter = new MovieCategoryAdapter(this, movieCategories); recyclerView.setAdapter(mAdapter); recyclerView.setLayoutManager(new LinearLayoutManager(this));
We can also set the properties of expanding and collapse it by setExpandCollapseListener(..).
Add the code when our list item Expanded and collapsed:
mAdapter.setExpandCollapseListener(new ExpandableRecyclerAdapter.ExpandCollapseListener() { @Override public void onListItemExpanded(int position) { MovieCategory expandedMovieCategory = movieCategories.get(position); String toastMsg = getResources().getString(R.string.expanded, expandedMovieCategory.getName()); Toast.makeText(MainActivity.this, toastMsg, Toast.LENGTH_SHORT) .show(); } @Override public void onListItemCollapsed(int position) { MovieCategory collapsedMovieCategory = movieCategories.get(position); String toastMsg = getResources().getString(R.string.collapsed, collapsedMovieCategory.getName()); Toast.makeText(MainActivity.this, toastMsg, Toast.LENGTH_SHORT) .show(); } });
Now, set the adapter and layout manager in our recycler view.
recyclerView.setAdapter(mAdapter); recyclerView.setLayoutManager(new LinearLayoutManager(this));
Here, we can do like this.
Save and Restore the state of Expand / Collapsed:
We can save the expanded and collapsed state of items in our Recycler View during our device configuration changes. Other things and also we can store the state of same.
To save Expanded / Collapsed state we can call ExpandableRecyclerAdapter.onSaveInstanceState(Bundle savedInstanceState).
To save Expanded / Collapsed state we can call ExpandableRecyclerAdapter.onSaveInstanceState(Bundle savedInstanceState).
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mAdapter.onSaveInstanceState(outState); }
Like this, we can save the state.
To restore expanded / collapsed state we can call ExpandableRecyclerAdapter.onRestoreInstanceState(Bundle savedInstanceState).
To restore expanded / collapsed state we can call ExpandableRecyclerAdapter.onRestoreInstanceState(Bundle savedInstanceState).
@Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mAdapter.onRestoreInstanceState(savedInstanceState); }
Like this, we can restore the state.
Output:
Download Code: Github
Conclusion:
This was an interesting example of how to create Expandable RecyclerView by using Big Nerd Ranch’s library in our application. This feature is mainly used in many applications. We can customize it according to the requirement. It is the same as ExapandableListView but has some new features added. An interesting functionality of Android, it is frequently used by the developers.
Comments
Post a Comment