Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collapsing CardView inside RecyclerView when animating

Tags:

What I'm trying to do

I have a CardView with a supporting text on the bottom that is GONE by default. I want to make this section of the card visible only when the user clicks the "action arrow", as shown on the image below:

Expand Arrow

I know I can achieve that by simply setting that View visibility to VISIBLE, but I also want to animate the expand and the collapse events.

The problem and what I've tried so far

To do that I've used the android:animateLayoutChanges="true" property on my CardView xml, and it works just fine when it's expanding. But once I click on the arrow again to collapse the supporting text, the card below overlaps the card I've clicked during the animation. How can I avoid this overlapping?

EDIT: I know it may be possible to do something like the solution on this question, but it seems overly complicated since the android:animateLayoutChanges option exists. I wonder if it's possible to solve my issue using that XML property, to keep it simple.

My animation code is as follows:

Java code

protected void expandCard() {     if (isExpanded) {         ibt_show_more.animate().rotation(0).start();         isExpanded = false;         tv_support.setVisibility(View.GONE);     }     else {         ibt_show_more.animate().rotation(180).start();         isExpanded = true;         tv_support.setVisibility(View.VISIBLE);     } } 

XML code

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:card_view="http://schemas.android.com/apk/res-auto"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:layout_margin="@dimen/spacing_small"     card_view:cardCornerRadius="2dp"     android:id="@+id/os_list_item_cv">      <RelativeLayout         android:id="@+id/os_list_item_rl_root"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:animateLayoutChanges="true">          <!-- Here goes the header, the image, the action buttons and so on -->         <!-- Omitted on purpose -->         <!-- ... -->          <!-- This is the support TextView -->         <TextView             android:id="@+id/tv_support"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_below="@+id/os_list_item_rl_actions"             android:text="@string/bacon_ipsum"             android:paddingBottom="24dp"             android:paddingEnd="16dp"             android:paddingRight="16dp"             android:paddingLeft="16dp"             android:paddingStart="16dp"             android:visibility="gone"/>      </RelativeLayout>  </android.support.v7.widget.CardView> 

GIF for completeness (With wrong collapse behavior)

enter image description here

like image 722
Mauker Avatar asked Feb 01 '17 15:02

Mauker


People also ask

What is difference between CardView and RecyclerView?

The RecyclerView is a more advanced and more flexible version of the ListView. This new component is a big step because the ListView is one of the most used UI widgets. The CardView widget, on the other hand, is a new component that does not “upgrade” an existing component.


1 Answers

Right before you change the visibility, add this line of code:

TransitionManager.beginDelayedTransition(the rootView containing the cardView, new AutoTransition());  

You should get a smooth animation. Also remove "animateLayoutChanges=true" from your xml before this.

As for why this works, calling TransitionManager.beginDelayedTransition() makes the TransitionManger capture current values in the parent ViewGroup and render the animations in the next animation frame. The Transition passed in this case is an AutoTransition, which takes care of all the fading, moving, and resizing in the parent ViewGroup.

See Transitions and TransitionManager

Also take care to use Transitions from the support library where appropriate, or perform the neccessary API level checks.

like image 54
Tunji_D Avatar answered Sep 22 '22 07:09

Tunji_D