Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transition from Button to EditText

I want to have a transition in my android views on view is Button and other is EditText, transitions must be like this animation

Button to EditText Transitions

I tried in this way

Layout xml is

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="app.itc.org.todo.MainActivity">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:weightSum="2">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="vertical"
            android:background="@android:color/white"
            android:gravity="center_horizontal|center_vertical">

            <TextView
                android:id="@+id/title_tv"
                android:text="@string/to_do"
                android:textSize="22sp"
                android:textStyle="bold"
                android:textColor="@android:color/black"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"/>

            <TextView
                android:id="@+id/date_tv"
                android:textSize="16sp"
                android:textColor="@android:color/darker_gray"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />


        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@color/colorGray"
            android:gravity="center_horizontal|center_vertical"
            android:orientation="vertical">

            <TextView
                android:text="@string/what_do_you_want_to_do_today"
                android:textSize="16sp"
                android:textColor="@android:color/darker_gray"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"/>

            <TextView
                android:text="@string/start_adding_items_to_your_to_do_list"
                android:textSize="16sp"
                android:textColor="@android:color/darker_gray"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>


        </LinearLayout>

    </LinearLayout>

    <FrameLayout
        android:id="@+id/transitions_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible">

        <Button
            android:id="@+id/add_btn"
            android:layout_width="200dp"
            android:layout_height="60dp"
            android:text="@string/add_item"
            android:textSize="18sp"
            android:paddingLeft="20dp"
            android:textColor="@android:color/white"
            android:drawableLeft="@drawable/ic_add_24dp"
            android:background="@drawable/rounded_black_bg"
            android:layout_gravity="center"/>

        <EditText
            android:id="@+id/item_input_et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone"
            android:minHeight="50dp"
            android:layout_marginLeft="@dimen/margin_30dp"
            android:layout_marginRight="@dimen/margin_30dp"
            android:paddingLeft="@dimen/dimen_20dp"
            android:paddingRight="@dimen/dimen_50dp"
            android:textColor="@android:color/black"
            android:inputType="text"
            android:background="@drawable/rounded_edit_text"
            android:layout_gravity="center"/>


    </FrameLayout>

</RelativeLayout>

Preview is

Java code is

public class MainActivity extends AppCompatActivity {

    private EditText mItemInputEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView dateTextView = (TextView) findViewById(R.id.date_tv);

        mItemInputEditText = (EditText) findViewById(R.id.item_input_et);
        final Button addButton = (Button) findViewById(R.id.add_btn);

        final ViewGroup transitionsContainer = (ViewGroup) findViewById(R.id.transitions_container);

        mItemInputEditText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {



                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    TransitionSet set = new TransitionSet()
                            .addTransition(new Fade())
                            .setInterpolator(new FastOutLinearInInterpolator());

                    TransitionManager.beginDelayedTransition(transitionsContainer, set);
                }

                addButton.setVisibility(View.VISIBLE);
                mItemInputEditText.setVisibility(View.GONE);
            }
        });

        addButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    TransitionSet set = new TransitionSet()
                            .addTransition(new Fade())
                            .setInterpolator(new FastOutLinearInInterpolator());

                    TransitionManager.beginDelayedTransition(transitionsContainer, set);
                }

                addButton.setVisibility(View.GONE);
                mItemInputEditText.setVisibility(View.VISIBLE);
            }

        });

        SimpleDateFormat dt = new SimpleDateFormat("EEE d MMM yyyy");
        dateTextView.setText(dt.format(new Date()));

    }
}

but with this code the resulting transition is

My Resulting transition

As you can see this is bit weird as compared to expected one, can any one suggest me some changes to get the desired transitions.

like image 650
Arshad Ali Avatar asked Oct 07 '17 04:10

Arshad Ali


1 Answers

Transitions API is surely nice thing, but it cannot solve each and everything for you. You haven't instructed how to perform that animation to the transition framework, how come it would understand what is the final animation that you want to perform?

I'm not sure this animation can be achieved using solely Transitions API. Instead, you can stick to standard animations APIs, e.g. ValueAnimator.

The animation consists of several stages. When a button is clicked, you want it to become slightly wider, also losing its transparency. And after this is done, you want the EditText to come into the scene and be animated to its final value starting from the width, where the button was landed at.

So, inside button click listener:


    @Override
    public void onClick(View v) {

        final int from = addButton.getWidth();
        final int to = (int) (from * 1.2f); // increase by 20%
        final LinearInterpolator interpolator = new LinearInterpolator();

        ValueAnimator firstAnimator = ValueAnimator.ofInt(from, to);
        firstAnimator.setTarget(addButton);
        firstAnimator.setInterpolator(interpolator);
        firstAnimator.setDuration(DURATION);

        final ViewGroup.LayoutParams params = addButton.getLayoutParams();
        firstAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                params.width = (Integer) animation.getAnimatedValue();
                addButton.setAlpha(1 - animation.getAnimatedFraction());
                addButton.requestLayout();
            }
        });

        firstAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                // reset alpha channel
                addButton.setAlpha(1.0f);
                addButton.setVisibility(View.GONE);

                mItemInputEditText.setVisibility(View.VISIBLE);

                ValueAnimator secondAnimator = ValueAnimator.ofInt(to, editTextWidth);
                secondAnimator.setTarget(mItemInputEditText);
                secondAnimator.setInterpolator(interpolator);
                secondAnimator.setDuration(DURATION);

                final ViewGroup.LayoutParams params = mItemInputEditText.getLayoutParams();
                secondAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        params.width = (Integer) animation.getAnimatedValue();
                        mItemInputEditText.requestLayout();
                    }
                });

                secondAnimator.start();
            }
        });

        firstAnimator.start();
    }

Similar actions are performed when coming back from EditText to button:


    @Override
    public void onClick(View view) {

        final int from = mItemInputEditText.getWidth();
        final int to = (int) (from * 0.8f);
        final LinearInterpolator interpolator = new LinearInterpolator();

        ValueAnimator firstAnimator = ValueAnimator.ofInt(from, to);
        firstAnimator.setTarget(mItemInputEditText);
        firstAnimator.setInterpolator(interpolator);
        firstAnimator.setDuration(DURATION);

        final ViewGroup.LayoutParams params = mItemInputEditText.getLayoutParams();
        firstAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                params.width = (Integer) animation.getAnimatedValue();
                mItemInputEditText.requestLayout();
            }
        });

        firstAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mItemInputEditText.setVisibility(View.GONE);
                addButton.setVisibility(View.VISIBLE);

                ValueAnimator secondAnimator = ValueAnimator.ofInt(to, buttonWidth);
                secondAnimator.setTarget(addButton);
                secondAnimator.setInterpolator(interpolator);
                secondAnimator.setDuration(DURATION);

                final ViewGroup.LayoutParams params = addButton.getLayoutParams();
                secondAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        params.width = (Integer) animation.getAnimatedValue();
                        addButton.setAlpha(animation.getAnimatedFraction());
                        addButton.requestLayout();
                    }
                });

                secondAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        addButton.setAlpha(0.0f);
                    }
                });

                secondAnimator.start();
            }
        });

        firstAnimator.start();
    }

editTextWidth and buttonWidth are initial sizes of views:


    private int editTextWidth, buttonWidth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ...

        // `transitions_container` is the parent of both `EditText` and `Button`
        // Thus, posting on it ensures that both of those views are laid out when this runnable is executed
        findViewById(R.id.transitions_container).post(new Runnable() {
            @Override
            public void run() {
                editTextWidth = mItemInputEditText.getWidth();
                // `mItemInputEditText` should be left visible from XML in order to get measured
                // setting to GONE after we have got actual width
                mItemInputEditText.setVisibility(View.GONE);
                buttonWidth = addButton.getWidth();
            }
        });
    }

Here's the output:

enter image description here

You can have the patch file with changes here.

like image 121
azizbekian Avatar answered Oct 13 '22 00:10

azizbekian