Uber Login Animation Mockup

Khi tôi thấy Animation của màn hình đăng nhập app Uber, tôi đã quyết định thực hiện tương tự trong một ứng dụng taxi cho khách hàng của tôi. Nó không giống nhau y hệt nhưng nhìn cũng khá đẹp.

Nếu bạn quan tâm để biết làm thế nào tôi làm được điều này, hãy kiên nhẫn. Tôi sẽ hướng dẫn từng bước.

Các bước thực hiện

Trước tiên, hãy thiết kế một màn hình giao diên có chứa một ImageView và một groupview chứa ba view: TextView, EditText và Button. Như code bên dưới đây.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        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=".MainActivity">

        <ImageView
            android:id="@+id/bg_img"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/bro_cab"

            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />


        <android.support.constraint.ConstraintLayout
            android:id="@+id/layout"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toBottomOf="@+id/bg_img"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent">

            <TextView
                android:id="@+id/title_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="16dp"
                android:layout_marginBottom="155dp"
                android:text="Connecting with BroCabs"
                android:textColor="@android:color/black"
                android:textSize="20sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent" />

            <android.support.design.widget.TextInputLayout
                android:layout_width="0dp"
                android:layout_height="58dp"
                android:layout_marginLeft="16dp"
                android:layout_marginTop="8dp"
                android:layout_marginRight="32dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/title_tv">

                <android.support.design.widget.TextInputEditText
                    android:id="@+id/mob_et"
                    android:layout_width="match_parent"
                    android:maxLength="10"
                    android:layout_height="wrap_content"
                    android:hint="Enter your mobile number"
                    android:inputType="phone" />
            </android.support.design.widget.TextInputLayout>

            <android.support.design.widget.FloatingActionButton
                android:id="@+id/registerFab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="24dp"
                android:layout_marginBottom="24dp"
                android:clickable="true"
                app:backgroundTint="#c46a28"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                android:src="@drawable/ic_next" />

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

Tiếp theo chúng ta sẽ thực hiện hai phương thức:

  • Thay đổi độ mờ của hình ảnh
  • Thêm animation cho Title, EditText and Fab Button

Để có được hiệu ứng animation này, chúng ta phải sử dụng Physics based animation có tên là Fling Animation. Fling Animation có một động lực ban đầu và dần dần chậm lại.

Để sử dụng Physics based animation, bạn phải thêm dependency như sau:

implementation 'com.android.support:support-dynamic-animation:28.0.0'

Bind view

private void bindViews() {
    bgImg=findViewById(R.id.bg_img);
    layout=findViewById(R.id.layout);
    mobEt=findViewById(R.id.mob_et);
}

Khi mobEt (EditText) nhận được Focus, chúng ta sẽ thay đổi opacity của bgImg (ImageView) và start animation trên layout.

Define một phương thức xử lý animation

private void animate(int direction, float alpha) {

    FlingAnimation flingX = 
             new FlingAnimation(layout, DynamicAnimation.Y)
            .setStartVelocity(direction*height)
            .setFriction(0.5f);
    flingX.start();

    bgImg.animate().alpha(alpha).setDuration(1000).start();

}

Phương thức sẽ được gọi cho cả hai hành động: khi layout được kéo lên trên cùng và khi layout được kéo trở lại xuống dưới cùng. Nó có hai tham số truyền vào, để xác định xem sử dụng animation lên trên hay xuống dưới, các giá trị sẽ là 1 hoặc -1.

Ở đây height là tổng chiều cao của màn hình mà bạn muốn dừng animation của mình và nó có thể được lấy như sau.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
height = metrics.heightPixels-metrics.heightPixels/50.0f;

Start animation

Để start animation chúng ta chỉ cần gọi phương thức animate() trong sự kiện OnFocusChangeListener của TextInputEditText.

mobEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
           animate(-1,0f);
    }
});

Ở đây bạn có thể thấy, khi EditText được focus, animation được bắt đầu. Nhưng có một vấn đề chưa giải quyết được. Đó là khi chúng ta nhấp vào nút back, animation không thực hiện kéo layout xuống dưới. Chúng ta sẽ giải quyết vấn đề đó như sau

Chúng ta sẽ define 1 biến isAnimating, override hàm onBackPress() và xử lý code trong hàm này như bên dưới:

@Override
public void onBackPressed() {

    if(!isAnimating){
        super.onBackPressed();
    }
    else{
        animate(1,1f);
        isAnimating=false;
        mob_et.clearFocus();
    }
}

Sau đó update lại code trong sự kiện onFocusChangeListener của EditText:

mobEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus){
            isAnimating=true;
            animate(-1,0f);
        }
    }
});

Vậy là xong, bạn run app và kiểm tra kết quả nhé!

Nguồn: https://android.jlelse.eu/uber-like-animation-39177ef01510