Android recyclerview expand and collapse

Android recyclerview expand and collapse

Expandable RecyclerView

Custom RecyclerViewAdapters for expanding and collapsing groups with support for multiple view types

Let’s say you are a rock star 🎸 and you want to build an app to show a list of your favorite Genre s with a list of their top Artist s.

First, define your custom ExpandableGroup class:

Next up, let’s create the ChildViewHolder and GroupViewHolder . These are both wrappers around regular ol’ RecyclerView.ViewHolder s so implement any view inflation and binding methods you may need.

Now we are ready for the juicy part — let’s make our ExpandableRecyclerViewAdapter

By including your GroupViewHolder and ChildViewHolder in the definition of the class, you’ll see that the onCreateGroupViewHolder and onCreateChildViewHolder methods return the correct type 👍

Lastly you’ll need either an Activity or Fragment to host your adapter. Once you’ve got that up and running, all that’s left is to instantiate your fancy new GenreAdapter with a List

Saving And Restoring Expand / Collapse State

If you want to save the expand and collapse state of your adapter, you have to explicitly call through to the adapters onSaveInstanceState() and onRestoreInstanceState() in the calling Activity

Programmatic Expanding and Collapsing

The ExpandableRecyclerViewAdapter exposes methods to control the expanded and collapsed state.

First up we have the toggles, .toggleGroup(int) and .toggleGroup(ExpandableGroup) . These are handy for when you control the states explicitly.

We also expose explicit methods to control the expanding and collapsing of specific groups, .expandGroup() and .collapseGroup() . For example, to expand the first group immediately:

Adding Custom Expand / Collapse Animations

If you want to add a custom Drawable that animates based on a groups state, override the expand() and collapse() methods in your GroupViewHolder :

Listening to Expand/Collapse events

If you want register an ExpandCollapseListener outside of the adapter, you can simply call setOnGroupExpandCollapseListener on the ExpandableRecyclerViewAdapter

Multiple Child and Group Types

The MultiTypeExpandableRecyclerViewAdapter allows subclasses to implement multiple different view types for both children and groups.

Continuing with our genre example, let’s say you wanted to display regular artists differently from your favorite artists. Let’s start by making a new FavoriteArtistViewHolder

Just like the regular ArtistViewHolder , FavoriteArtistViewHolder must extends ChildViewHolder .

Next up, let’s create a subclass of MultiTypeExpandableRecyclerViewAdapter called MultiTypeGenreAdapter and let’s add two static int s representing our two artist view types:

Notice we started used values > 2. That’s because ExpandableListPosition.CHILD and ExpandableListPositon.GROUP are 1 and 2 respectively so they are already taken.

Since we only want a single view type for groups, we only need to override getChildViewType() . As getGroupViewType() will default to ExpandableListPosition.GROUP .

Since we provided custom view types for our children, we must also override isChild()

And now, just like in any other RecyclerView.Adapter in our onCreateChildViewHolder and our onBindChildViewHolder we can use the provided parameters to switch on the different view tyeps:

Expandable Check RecyclerView

An extension of expandablerecyclerview for checking single or multiple children within a group

The setup for the single and multi check versions is very similar to the expandablerecyclerview we walked through above. Here are a few of the notable differences.

Instead of ExpandableGroup you must use CheckedExpandableGroup . CheckedExpandableGroup is a subclass of ExpandableGroup that uses a SparseBooleanArray to hold onto which of it’s children are checked.

The expandablecheckrecyclerview library comes with two default implementations — SingleCheckExpandableGroup and MultiCheckExpandableGroup .

The CheckableChildRecyclerViewAdapter has a clearChoices() which un checks any currently checked children.

The CheckableChildViewHolder is a subclass of ChildViewHolder that has a Checkable widget. The Checkable interface is initially not set, so in order to see your children view states update, you must set a View that implements Checkable in your view holder.

Listening to Child Click Events

There is a custom callback for click events on children of a CheckedExpandableGroup which returns you the View of the row item that was clicked, the current checked state of the child, the containing CheckedExpandableGroup group and the index of the child that was clicked.

Читайте также:  Debugging using android device

To see the complete code for all the above examples along with unit tests for the adapters check out the sample app. The app has the following packages:

An example of basic ExpandableRecyclerViewAdapter

An example of a CheckableChildRecyclerViewAdapter using MultiCheckExpandableGroup

An example of a CheckableChildRecyclerViewAdapter using SingleCheckExpandableGroup

An example of a MultiTypeExpandableRecyclerViewAdapter using two different child view holders

Expandable RecyclerView is Copyright (c) 2016 thoughtbot, inc. It is free software, and may be redistributed under the terms specified in the LICENSE file.

Expandable RecyclerView is maintained by @mandybess

Expandable RecyclerView is maintained and funded by thoughtbot, inc. The names and logos for thoughtbot are trademarks of thoughtbot, inc.

We love open source software! See our other projects or hire us to help build your product.

About

Custom Android RecyclerViewAdapters that collapse and expand

Источник

RecyclerView развернуть / свернуть элементы

Я хочу развернуть / свернуть элементы моего recyclerView, чтобы показать больше информации. Я хочу добиться того же эффекта от SlideExpandableListView .

В основном в моем viewHolder у меня есть вид, который не виден, и я хочу сделать плавную анимацию развертывания / сворачивания, а не устанавливать видимость только VISIBLE / GONE. Мне нужно только расширить элемент за раз, и было бы здорово иметь некоторую отметку, чтобы показать, что элемент выбран.

Это тот же эффект, что и в новом списке недавних звонков Android. Параметры «ОБРАТНАЯ СВЯЗЬ» и «ДЕТАЛИ» отображаются только при выборе элемента.

Пожалуйста, не используйте какую-либо библиотеку для этого эффекта, вместо этого используйте рекомендуемый способ сделать это в соответствии с Google I / O. В методе onBindViewHolder вашего recyclerView сделайте это:

  • Где детали это мой вид, который будет отображаться на ощупь (детали звонка в вашем случае. По умолчанию Visibility.GONE).
  • mExpandedPosition — это переменная типа int, инициализированная -1

А для классных эффектов, которые вы хотели, используйте их в качестве атрибутов list_item:

и comment_selection — это:

Для этого просто нужны простые линии, не сложные

в вашем методе onBindViewHolder добавьте ниже код

mExpandedPosition — это глобальная переменная int, инициализированная -1

Для тех, кто хочет, чтобы только один предмет был расширен, а другие развалились. Использовать это

сначала объявите глобальную переменную с previousExpandedPosition = -1

Готово. Просто и скромно .. 🙂

Не сказать, что это лучший подход, но, похоже, он мне подходит.

Прежде всего, добавьте расширенную область в макет ячейки / элемента и сделайте компоновку вмещающей ячейки animateLayoutChanges = «true». Это обеспечит анимацию развертывания / свертывания:

Затем сделайте так, чтобы ваш класс адаптера RV реализовал View.OnClickListener, чтобы вы могли воздействовать на элемент, по которому щелкали. Добавьте поле int для хранения позиции одного расширенного представления и инициализируйте его отрицательным значением:

Наконец, реализуйте методы ViewHolder, onBindViewHolder () и переопределите метод onClick (). Вы развернете представление в onBindViewHolder, если его позиция равна «extendedPosition», и скроете его, если нет. Вы устанавливаете значение extendedPosition в слушателе onClick:

Это должно расширять только один элемент за один раз, используя системную анимацию по умолчанию для изменения макета. По крайней мере, это работает для меня. Надеюсь, поможет.

Существует очень простая в использовании библиотека с поддержкой gradle: https://github.com/cachapa/ExpandableLayout .

Прямо из библиотеки документов:

После того, как вы отмечаете свое расширяющиеся точки зрения, просто вызвать любого из этих методов на контейнере: expand() , collapse() или toggle()

Я знаю, что прошло много времени с тех пор, как был опубликован оригинальный вопрос. Но я думаю, что для таких, как я, небольшое объяснение ответа @ Heisenberg поможет.

Объявите две переменные в классе адаптера как

Затем в onBindViewHolder, следуя указаниям оригинального ответа.

И, наконец, чтобы получить объект recyclerView в переопределении адаптера

Надеюсь это поможет.

Нет необходимости использовать сторонние библиотеки. Небольшая настройка метода, продемонстрированного в Google I / O 2016 и Гейзенберге на эту тему, делает свое дело.

Поскольку notifyDataSetChanged() перерисовывает полный RecyclerView , notifyDataItemChanged() это лучший вариант (не лучший), потому что у нас есть позиция и ViewHolder в нашем распоряжении, и notifyDataItemChanged() только перерисовывает конкретный ViewHolder в данной позиции .

Но проблема в том, что преждевременное исчезновение ViewHolder щелчка и его появление не устраняется, даже если notifyDataItemChanged() используется.

Следующий код не прибегать к notifyDataSetChanged() или notifyDataItemChanged() и испытано на API 23 и работает как шарм при использовании на RecyclerView , где каждый ViewHolder имеет , CardView как это корневой элемент:

Читайте также:  Мои рисунки для android

prev_position глобальное целое число, инициализированное -1. details это полное представление, которое отображается в развернутом виде и скрыто при свертывании.

Как уже говорилось, корневой элемент ViewHolder — это атрибуты CardView with foreground и stateListAnimator определены точно так, как сказал Гейзенберг по этой теме.

ОБНОВЛЕНИЕ: Приведенная выше демонстрация свернет ранее развернутый элемент, если один из них развернут. Чтобы изменить это поведение и сохранить развернутый элемент таким, какой он есть, даже когда другой элемент развернут, вам потребуется следующий код.

ОБНОВЛЕНИЕ: при развертывании последних элементов в списке, он может не отображаться в полной видимости, потому что расширенная часть находится ниже экрана. Чтобы получить полный элемент на экране, используйте следующий код.

ВАЖНО: чтобы вышеприведенные демонстрации работали, в их коде необходимо сохранить экземпляр RecyclerView и его LayoutManager (последний для гибкости)

Источник

Expand a RecyclerView in Four Steps

Expand a RecyclerView in Four Steps

The Expandable RecyclerView library is a lightweight library that simplifies the inclusion of expandable dropdown rows in your RecyclerView. In it, you have two types of views. The parent view is the one visible by default, and it contains the children. The child view is the one that is expanded or collapsed, and will appear when a parent item is clicked.

In this post, we will implement the Expandable RecyclerView in the CriminalIntent application from our Android programming guide. We’ll be showing a more detailed view of each crime from the main list fragment.

Not familiar with RecyclerView? Bill Phillips has written two excellent blog posts on the subject.

Let’s Get it Working

Our completed demo will look like this:

Start by adding these two dependencies to your app’s build.gradle file:

All expanding and collapsing functionality is handled in the adapter, meaning that your RecyclerView is just a stock RecyclerView. All you’ll need to do to set up the Expandable RecyclerView in a layout is add a stock RecyclerView to your activity or fragment’s XML layout.

1. The ViewHolders

First, let’s create the XML layouts for our parent and child views. Our parent layout is going to include the title of the crime and a dropdown arrow to display an animation when the item is expanded or collapsed. We’ll call this layout list_item_crime_parent .

Now, onto the child layout. The child is going to contain a TextView that shows the date of the crime and a checkbox that we can click when the crime is solved. We’ll call this layout list_item_crime_child .

Now that we have both of our layouts ready, let’s set up each ViewHolder. We will create a class called CrimeParentViewHolder that extends ParentViewHolder and another class called CrimeChildViewHolder that extends ChildViewHolder .

Let’s start with CrimeParentViewHolder. Go ahead and create a public TextView and ImageButton variable for our two views, like so:

Now, onto our CrimeChildViewHolder. We’re again going to create two public variables for our views, but this time one will be a TextView and one will be a CheckBox:

Now let’s set up our parent and child objects.

2. Parents and Their Children

For our CriminalIntent example, the data that we want to display in our list items are fields of our Crime object. Since we have both a parent and a child layout, the best practice is to create a child object, separate from the parent, to hold the data that will be displayed in the child.

In this case, our parent object will be the Crime object itself. Let’s make our Crime object implement ParentObject . Implement the getter and setter methods with a list variable:

The expandable RecyclerView allows for multiple children or none, so the children need to be added as a list. You can either add the children directly in the getChildObjectList method we implemented by returning your List of children, or you can add them when we create the list of items by calling setChildObjectList with the list of respective children. I will be doing the latter in this demo.

Our child object will hold two values, a String for the date and a boolean for the solved flag:

We’ll populate each parent object with children in the final step. Now, let’s get the adapter working!

3. The Adapter

We’re going need to implement a custom adapter that extends ExpandableRecyclerAdapter. Inside our adapter, we will implement a few methods so we can populate the data in our ViewHolders.

Читайте также:  Оффлайн карты для андроид абхазия

First, let’s create a class and call it CrimeExpandableAdapter. Make it extend ExpandableRecyclerAdapter and give it our two ViewHolder type parameters in the order of

. Our header will look like this:

You’ll need to implement the four inherited methods, onCreateParentViewHolder , onBindParentViewHolder , onCreateChildViewHolder and onBindChildViewHolder . Go ahead and implement the default constructor that will take in a Context and a List of ParentObjects.

In our constructor, let’s get access to the LayoutInflater and call it mInflater. This will be used in our onCreateParentViewHolder and onCreateChildViewHolder to inflate the layouts we created earlier. In our constructor, add mInflater = LayoutInflater.from(context); . This will create a layout inflater for us.

Now, let’s create our views and add them to the custom ViewHolders we made earlier. In onCreateParentViewHolder , let’s replace the return null line with these two lines:

Let’s now do the same as we did in onCreateParentViewHolder , but adjust for our CrimeChildViewHolder. Again, replace return null with these two lines, but this time in onCreateChildViewHolder :

To finish off our adapter, let’s work on our onBindViewHolder methods, starting with onBindParentViewHolder . In onBindParentViewHolder , three variables are passed in: the viewholder we created in onCreateParentViewHolder , the position of the item and the parent object associated with that position. We’re going to need to cast the passed parent object to our parent object type (which, as you recall, is our Crime object). Let’s make our onBindParentViewHolder look like this:

Finally, we will set up our CrimeChildViewHolder. Recall that our CrimeChildViewHolder contains a TextView for a date and a CheckBox to indicate whether the crime is solved. Our onBindChildViewHolder will look like this:

Now our adapter is ready to roll. Let’s finish this all up!

4. Tying it all together

Let’s head back to our main fragment, where we are hosting the RecyclerView. Make sure you find the RecyclerView in your layout and set its layout manager to a new LinearLayoutManager .

I went ahead and created a simple method to generate each of our Crime objects and attach their children. You can add this method in your Fragment:

Another option is to create a new list of children directly in your Crime object and set that to be the childrenList. A third option would be to create a list of children in getChildObjectList and return that list.

Now we can add the following lines to our onCreateView method:

Note that the list you pass into your adapter must be of the type ParentObject.

The setCustomParentAnimationView allows for the arrow in the parent layout to rotate on expand/collapse and setParentClickableAnimationDefaultDuration gives it a default rotation time of 200 milliseconds. setParentAndIconExpandOnClick ensures that we can click both the parent and the arrow to expand the item. You can always remove these if you don’t want an animation or custom triggering view.

Finally, set the RecyclerView’s adapter to finish it up:

That’s it! You now should have a RecyclerView that expands and collapses and has a nice rotation animation to go along with it.

Want to improve it or see more?

The library is open source, so visit the project’s GitHub page to see all the source code, then send a pull request if there are new features you’d like to add.

*Ryan Brooks was an Android intern this summer. Apply now to join our team as an intern in Fall 2015.

Steve Sparks

Steve Sparks has been a Nerd since 2011 and an electronics geek since age five. His primary focus is on iOS, watchOS, and tvOS development. He plays guitar and makes strange and terrifying contraptions. He lives in Atlanta with his family.

Schedule a call today! Our team of nerds are ready to help

Splash Screens: The Final Right Way

The impending release of Android 12 brings with it a group of new APIs for Android developers to learn and play with. Being a good citizen.

Coming soon: Kotlin Programming: The Big Nerd Ranch Guide, Second Edition

Kotlin has been changing at a steady pace over the years, and more and more developers are choosing Kotlin as their language of choice.

Using StateFlow over LiveData for end-to-end operations

Observing data asynchronously is such a core skill for mobile developers that you may imagine Android has a long-established set of simple APIs in.

Источник

Оцените статью