Another simple implementation of Android RecycleView Item animation expansion details

Keywords: Android xml encoding Gradle

Not much to say, let's see the effect first.


Generally, many people on the Internet, RecycleView Item expand the effect of the idea is through the add and remove of item to achieve, but what problems will the effect of the graph appear?

  • Each item has rounded corners
  • Each item has spacing

If it is also achieved through add and remove, how to ensure that the distance between the contents of the drop-down is not there, and how to ensure that the corners will always move down. It's more troublesome, and it's not that there must be no way out. All in all, it's disgusting to deal with. However, it is not such a bad plan, after all, there is no omnipotent plan, only the appropriate one.

The solutions implemented by add and remove can be found in the following articles

Android -- RecyclerView (super simple) implements expandable lists

ExpandableRecyclerview

expandable-recycler-view

Okay, before we talk about the source code, let's talk about our ideas.

  • A peripheral control is a simple RecycleView
  • The parent view of item in recycleView is cardview, which supports rounded corners for convenience.
  • Click on the drop-down to make it clear that it's a simple visual and gone animation.

Here comes the source code:

Since recycleview and cardview are used, you must first integrate the following in gradle:

dependencies {
    //**** your other compile *****
    compile 'com.android.support:recyclerview-v7:25.3.1'
    compile 'com.android.support:cardview-v7:25.0.0'
}

Then integrate the layout of recycleview in activty

actvity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.touch.xu.expandedrecycleviewdemo.MainActivity"
    android:orientation="vertical">
    <TextView
        android:padding="10dp"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Expandable recycleView"/>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/id_recycleview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </android.support.v7.widget.RecyclerView>
</LinearLayout>

Then the layout of each item of recycleview is as follows:

item_normal.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    app:cardCornerRadius="5dp"
    app:cardElevation="5dp"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <LinearLayout
        android:orientation="vertical"
        android:background="@android:color/white"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:gravity="center"
            android:textColor="@android:color/black"
            android:padding="30dp"
            android:id="@+id/id_textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <RelativeLayout
            android:background="@android:color/darker_gray"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <RelativeLayout
                android:padding="10dp"
                android:clickable="true"
                android:id="@+id/id_top"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <TextView
                    android:layout_centerVertical="true"
                    android:id="@+id/id_tip"
                    android:text="You need to start testing...."
                    android:paddingLeft="10dp"
                    android:gravity="left"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>
                <ImageView
                    android:layout_centerVertical="true"
                    android:id="@+id/id_attention"
                    android:layout_alignParentRight="true"
                    android:src="@mipmap/attention"
                    android:layout_width="20dp"
                    android:layout_height="20dp"/>
            </RelativeLayout>
            <TextView
                android:id="@+id/id_expand_view"
                android:visibility="gone"
                android:paddingLeft="20dp"
                android:gravity="left|center_vertical"
                android:layout_below="@id/id_top"
                android:text="This is unfolding. view\n This is unfolding. view\n This is unfolding. view"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_40"/>
        </RelativeLayout>
    </LinearLayout>
</android.support.v7.widget.CardView>

I intercepted some fragments from the view holder where I changed item to write expansion and hiding logic.

if (mExpandableView.getVisibility() == View.VISIBLE) {
    animClose(mExpandableView);
} else {
    animOpen(mExpandableView);
}

private void animOpen(final View view){
    view.setVisibility(View.VISIBLE);
    view.setAlpha(0);
    if (mOpenValueAnimator == null) {
        mOpenValueAnimator = createDropAnim(view,0, mHiddenViewMeasuredHeight);
    }
    mOpenValueAnimator.start();
}

private void animClose(final View view){
    int origHeight = view.getHeight();
    view.setAlpha(1);
    if (mCloseValueAnimator == null) {
        mCloseValueAnimator = createDropAnim(view, origHeight, 0);
        mCloseValueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                view.setVisibility(View.GONE);
            }
        });
    }
    mCloseValueAnimator.start();
}

private ValueAnimator createDropAnim(final  View view,int start,int end) {
    final ValueAnimator va = ValueAnimator.ofInt(start, end);
    va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        int value = (int) animation.getAnimatedValue();//Setting height according to the change coefficient of time factor
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        layoutParams.height = value;

        float alpha = ((float)value) / mHiddenViewMeasuredHeight;
        view.setAlpha(alpha);

        view.setLayoutParams(layoutParams);//Setting Height
        }
    });
    return  va;
}

Core logic is so much, I upload the specific source code Github Up. Welcome to Starha.

Posted by Snewzzer on Mon, 10 Jun 2019 13:43:05 -0700