Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate a view from 0dp width to MATCH_PARENT

I'm trying to animate my RecyclerView item when its clicked by making a rectangle grow from zero width to 100% (MATCH_PARENT) and become the background of the item.

However I can't see the animation working. I mean, the initial background is white, but the rectangle is gray, so the clicked item would become gray. But this is not happening.

Here's the item xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 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="wrap_content"
    app:cardCornerRadius="0dp"
    android:focusable="true"
    android:clickable="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="72dp"
        android:orientation="horizontal">

        <View
            android:id="@+id/colored_bar"
            android:layout_width="3dp"
            android:layout_height="match_parent"
            android:background="@drawable/colored_bar_bg1"></View>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <View
                android:id="@+id/option_background_container"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:background="#e0e0e0"></View>

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingBottom="16dp"
                android:paddingTop="16dp">

                <ImageView
                    android:id="@+id/icon"
                    android:layout_width="48dp"
                    android:layout_height="48dp"
                    android:layout_alignParentLeft="true"
                    android:layout_alignParentStart="true"
                    android:layout_alignParentTop="true"
                    android:layout_marginLeft="13dp"
                    app:srcCompat="@drawable/ic_lock" />

                <TextView
                    android:id="@+id/card_title"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentTop="true"
                    android:layout_toEndOf="@+id/icon"
                    android:layout_toRightOf="@+id/icon"
                    android:paddingBottom="16dp"
                    android:paddingLeft="8dp"
                    android:textColor="?android:attr/textColorPrimary"
                    android:textSize="16sp"
                    tools:text="@string/option_title_label" />

                <TextView
                    android:id="@+id/card_subtitle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignBottom="@+id/card_title"
                    android:layout_toEndOf="@+id/icon"
                    android:layout_toRightOf="@+id/icon"
                    android:paddingLeft="8dp"
                    android:textSize="14sp"
                    tools:text="@string/option_description_label" />
            </RelativeLayout>
        </FrameLayout>
    </LinearLayout>
</android.support.v7.widget.CardView>

And the code to make the animation:

public class OptionListItemHolder extends RecyclerView.ViewHolder {

        private TextView cardTitle;
        private TextView cardSubtitle;
        private ImageView icon;
        private View coloredBar;
        private View optionBackground;

        public OptionListItemHolder(View v) {
            super(v);
            cardTitle = (TextView)v.findViewById(R.id.card_title);
            cardSubtitle = (TextView)v.findViewById(R.id.card_subtitle);
            icon = (ImageView)v.findViewById(R.id.icon);
            coloredBar = v.findViewById(R.id.colored_bar);
            optionBackground = v.findViewById(R.id.option_background_container);

            v.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    ObjectAnimator animation = ObjectAnimator.ofInt(optionBackground, "width", 0, view.getWidth());
                    animation.setDuration(600);
                    animation.setInterpolator(new DecelerateInterpolator());

                    animation.start();
                }
            });
        }
    }

Why it is not working?

like image 247
Juliano Nunes Silva Oliveira Avatar asked Mar 02 '17 19:03

Juliano Nunes Silva Oliveira


1 Answers

I've found that using a ValueAnimator instead works

ValueAnimator widthAnimator = ValueAnimator.ofInt(view.getWidth(), newWidth);
widthAnimator.setDuration(500);
widthAnimator.setInterpolator(new DecelerateInterpolator());
widthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        view.getLayoutParams().width = (int) animation.getAnimatedValue();
        view.requestLayout();
    }
});
widthAnimator.start();

If the view's width needs to match the parent, you can get the width of the parent by

int parentWidth = ((View)view.getParent()).getMeasuredWidth();
like image 63
Rubberduck Avatar answered Oct 12 '22 23:10

Rubberduck