# RecyclerView item animation & self-contained MotionScene

This is going to be the result after we finish with the `RecyclerView`item animations and the self-contained `MotionScene`s.

But for now let's focus in putting everything into place. By the end of this step you'll have created the screen below. Simple as it is right now, it's the base for us to work with.&#x20;

![](https://720760333-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LMI4Smg5kqkZcFtc7nH%2F-LNucYcNXAGGr9lEJw4Z%2F-LNudkOtapyT2UirUIfj%2Fimage.png?alt=media\&token=fb9851e2-55a7-4559-9869-f38efa850409)

In a `RecyclerView` we can customize the way it appears as a `ViewGroup` (enter animation), or animate the differences in its children (add/ remove item). Together we're going to see the second one.

As mentioned in the beginning of this workshop, there are 2 ways you can specify an animation; either from the code or from the XML and the `RecyclerView` animations are not any different than this. In this workshop we're going to create them through XML.&#x20;

Let's start by adding some logic to our `DetailActivity` to prepare for adding our new animations.&#x20;

{% code title="ic\_remove.xml" %}

```
<vector android:height="24dp"
    android:tint="#333333"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0"
    android:width="24dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <path
        android:fillColor="#FF000000"
        android:pathData="M19,13H5v-2h14v2z" />
</vector>
```

{% endcode %}

{% code title="ic\_add.xml" %}

```
<vector android:height="24dp"
    android:tint="#333333"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0"
    android:width="24dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <path
        android:fillColor="#FF000000"
        android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
</vector>
```

{% endcode %}

{% code title="button\_background.xml" %}

```
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimaryDark">
    <item android:id="@android:id/mask">
        <shape android:shape="oval">
            <solid android:color="@color/colorPrimaryDark" />
            <corners android:radius="40dp" />
        </shape>
    </item>
</ripple>
```

{% endcode %}

{% code title="activity\_detail.xml" %}

```
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
    tools:context=".DetailActivity" ...>

    <!-- CircleImageView avatar --> 
    <!-- TextView name --> 

    <ImageButton
        android:id="@+id/bt_increase"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:background="?selectableItemBackgroundBorderless"
        android:foreground="@drawable/button_background"
        android:padding="28dp"
        android:src="@drawable/ic_add"
        app:layout_constraintBottom_toTopOf="@+id/guideline_horizontalHalf"
        app:layout_constraintEnd_toStartOf="@+id/guideline_vertical25"
        app:layout_constraintStart_toStartOf="@+id/guideline_vertical25"
        app:layout_constraintTop_toTopOf="@+id/guideline_horizontalHalf"
        tools:ignore="ContentDescription" />

    <TextView
        android:id="@+id/tv_counter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Body2"
        android:textSize="20sp"
        app:layout_constraintBottom_toTopOf="@+id/guideline_horizontalHalf"
        app:layout_constraintEnd_toStartOf="@+id/guideline_verticalHalf"
        app:layout_constraintStart_toStartOf="@+id/guideline_verticalHalf"
        app:layout_constraintTop_toTopOf="@+id/guideline_horizontalHalf" />

    <ImageButton
        android:id="@+id/bt_decrease"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:background="?selectableItemBackgroundBorderless"
        android:foreground="@drawable/button_background"
        android:padding="28dp"
        android:src="@drawable/ic_remove"
        app:layout_constraintBottom_toTopOf="@+id/guideline_horizontalHalf"
        app:layout_constraintEnd_toStartOf="@+id/guideline_vertical75"
        app:layout_constraintStart_toStartOf="@+id/guideline_vertical75"
        app:layout_constraintTop_toTopOf="@+id/guideline_horizontalHalf"
        tools:ignore="ContentDescription" />

    <!-- View second background --> 
    
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_added_items"
        android:layout_width="282dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:orientation="horizontal"
        app:reverseLayout="true"
        app:layoutManager="android.support.v7.widget.LinearLayoutManager"
        app:layout_constraintBottom_toBottomOf="@+id/fab"
        app:layout_constraintEnd_toStartOf="@+id/fab"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/fab"
        tools:listitem="@layout/li_detail" />
    
    <!-- FAB -->

    <android.support.constraint.Guideline
        android:id="@+id/guideline_verticalHalf"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline_horizontalHalf"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.5" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline_vertical25"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.25" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline_vertical75"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.75" />

    <android.support.constraint.Guideline
        android:id="@+id/guideline_horizontal25"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.25" />

</android.support.constraint.ConstraintLayout>
```

{% endcode %}

{% code title="DetailActivity.kt" %}

```
class DetailActivity : AppCompatActivity() {

    private var counter = 0
    ...

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        tv_counter.text = counter.toString()
        fab.setImageDrawable(animDrawable)
        fab.setOnClickListener {
            if (!isEditMode) {
                ...
                bt_decrease.visibility = View.VISIBLE
                bt_increase.visibility = View.VISIBLE
            } else {
                ...
                bt_decrease.visibility = View.GONE
                bt_increase.visibility = View.GONE
            }
            isEditMode= !isEditMode
        }

        bt_increase.setOnClickListener { tv_counter.text = "${++counter}" }
        bt_decrease.setOnClickListener {
            tv_counter.text = when {
                counter > 0 -> "${--counter}"
                else -> "$counter"
            }
        }
    }
    ...
```

{% endcode %}

{% code title="li\_detail.xml" %}

```
<android.support.constraint.motion.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/added_item_container"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ImageView
        android:id="@+id/iv_added_item"
        android:layout_width="42dp"
        android:layout_height="42dp"
        android:src="@drawable/avatar_1"
        tools:ignore="ContentDescription" />

</android.support.constraint.motion.MotionLayout>
```

{% endcode %}

## We've put almost everything into place!&#x20;

Right now, it doesn't do much since we haven't added the adapter yet but let's rewind what we've done so far.&#x20;

* We added 2 buttons in our Detail Activity layout; one for adding items and one for removing
* We also added a counter so that we know how many items we've added and removed
* We added a `RecyclerView` to our Detail Activity layout
* And finally we created the layout for our list item of that `RecyclerView`. You may have noticed that in contrast with our previous motion layouts, in this one we haven't specified any constraints. The reason for this is because we are going to add our view constraints from our `MotionScene` XML file. We call this MotionScene "self-contained" since all the ConstraintSets are maintained in a single file.&#x20;

{% hint style="info" %}
The upcoming MotionEditor in Android Studio will likely to only support self-contained MotionScene files.
{% endhint %}

![The upcoming MotionLayout editor in Android Studio. Image from "Introduction to MotionLayout - Google Developers"](https://720760333-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LMI4Smg5kqkZcFtc7nH%2F-LNsqB01Vg-zB9EWpvtu%2F-LNsyMb6shKBR7H4lhO9%2F1_--BinUe-6XZPrZhPys6mzA.gif?alt=media\&token=c7c3aac3-14e9-487b-8481-357b2177338f)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://elizacamber.gitbook.io/animations-2018/rv_item_animation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
