Animation và Transition trong lập trình Android cơ bản
Khóa học lập trình Android cơ bản

Danh sách bài học
Animation và Transition trong lập trình Android cơ bản
Dẫn nhập
Ở các bài học trước, chúng ta đã cùng nhau tìm hiểu về GIAO DIỆN TRƯỢT NGANG BẰNG VIEWPAGER & TAB (nhằm tạo ra các ứng dụng đọc sách / truyện / báo. Và cũng nhờ đó mà các bạn cũng thấy được một chút về hiệu ứng chuyển động trong các thành phần giao diện Android.
Hôm nay chúng ta sẽ đào sâu thêm một chút vào nó: Animation và Transition – các loại hiệu ứng trong Android. Mình sẽ cố gắng đưa nhiều hình ảnh để các bạn xem cho sướng lỗ mắt. À nhưng đừng quên đọc code để hiểu nhé.
Nội dung
Để đọc hiểu bài này tốt nhất các bạn nên có kiến thức cơ bản về các phần:
- VIEW TRONG ANDROID
- CÁCH TẠO MỘT PROJECT CƠ BẢN TRONG ANDROID
- CÁCH KHỞI TẠO CÁC VIEW VÀ VIEWGROUP
Trong bài học này, chúng ta sẽ cùng tìm hiểu các vấn đề:
- Animation trong Android.
- Cách tạo một số animation thông dụng.
- Một số thư viện hỗ trợ animation.
Animation
Bước 1: Để bắt đầu thực hành, chúng ta tạo một project mới toanh mang tên AnimationExample nhé:
Các bạn chú ý: Do Animation API được cung cấp từ API 11, tuy nhiên sau một vài level thì API mới đầy đủ hơn, nên chúng ta đặt mức API của project là 13:
Bước 2: Chọn loại Activity là Empty Activity. Đặt tên là MainActivity. Sau đó tạo thêm một Activity thứ hai là SecondActivity. Cả 2 Acitivty đều có layout XML tương ứng là activity_main.xml và activity_second.xml:
Ok, chúng ta sẽ đi từ animation đơn giản đầu tiên. Nhìn chung tùy loại máy Android mà hiệu ứng chuyển cảnh giữa các Activity khác nhau. Nhưng mình để ý thì kiểu sau đây khá phổ biến:
Animation chuyển giữa các Activity
Các bạn xong 2 bước dạo đầu ở trên rồi chứ? Chúng ta sang một phần mới ngay đây:
Bước 1: Tạo một Button có nhiệm vụ chuyển từ MainActivity.java sang SecondActivity.java. Quá dễ phải không? Nếu chưa biết các bạn hãy xem lại bài INTENT & MANIFEST nhé.
Activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.howkteam.animationexample.MainActivity">
<Button
android:text="To Second Activity"
android:id="@+id/btn_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
MainActivity.java
package com.howkteam.animationexample;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private Button btnChange;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnChange = (Button) findViewById(R.id.btn_change);
final Intent changeActivity = new Intent(this, SecondActivity.class);
btnChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(changeActivity);
}
});
}
}
Và đừng quên khai báo SecondActivity trong file AndroidManifest.xml nhé, nếu không sẽ bị crash app đó:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.howkteam.animationexample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SecondActivity">
</activity>
</application>
</manifest>
Và chạy app, chúng ta sẽ được một màn chuyển cảnh dạng như sau (để ý lúc ấn nút):
Bước 3: Các bạn chuột phải vào thư mục /res trong cửa sổ Android Studio > chọn New > Android resource directory:
Và tạo một folder resource mới, ở Resource type các bạn chọn là Anim và nhấn OK:
Và chúng ta có folder anim ở cột trái như hình:
Bước 4: Bây giờ chúng ta sẽ tạo ra file xml chứa hiệu ứng di chuyển từ phải sang trái và từ trái sang phải cho 2 activity đã tạo từ đầu nhé: Chuột phải vào thư mục anim/ , chọn New > Animation Resource file:
Chúng ta soạn 2 file xml trong /anim , file code xml có tên và nội dung tương ứng là:
slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromXDelta="100%p"
android:toXDelta="0"/>
<alpha
android:duration="400"
android:fromAlpha="1.0"
android:startOffset="100"
android:toAlpha="1.0"/>
</set>
slide_out_left.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromXDelta="0"
android:toXDelta="-100%p"/>
<alpha
android:duration="400"
android:fromAlpha="1.0"
android:startOffset="100"
android:toAlpha="1.0"/>
</set>
Và cuối cùng, nhét 2 hiệu ứng này vào Activity thông qua hàm overridePendingTransition:
MainActivity.java
package com.howkteam.animationexample;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private Button btnChange;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
btnChange = (Button) findViewById(R.id.btn_change);
final Intent changeActivity = new Intent(this, SecondActivity.class);
btnChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(changeActivity);
}
});
}
}
SecondActivity.java
package com.howkteam.animationexample;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
}
}
Chạy lại app. Ngạc nhiên chưa?
OK chắc các bạn cần lời giải thích một chút về animation. Ở đây mình giải thích file slide_in_right.xml nhé:
- Thời gian diễn ra hiệu ứng là 400ms (mili giây): android:duration=400
- fromXdelta: Đặt vị trí gốc là bên trái 100% so với vị trí ban đầu (giống như bước từ cánh gà trên sân khấu ra.
- 2 thuộc tính alpha là để chỉ định độ trong suốt. Ở đây đều đặt là 100 (không dùng đến). Các bạn thử thay đổi sổ và chạy lại xem sao.
OK. Vậy là chúng ta đã xong một dạng animation hết sức cơ bản rồi nhé. Nào, cùng sang vòng tiếp theo!
Hiệu ứng với ViewPropertyAnimator
Để thực hành phần này, chúng ta cần có một chút thay đổi là nâng mức API lên 16 vì một số hàm chỉ có trong API 16.
Bước 1: Các bạn mở file build.gradle (Module: app) lên như hình. Có 2 file build.gradle, nhớ chọn đúng cái nó ghi Module: app nhé:
Nếu như vì lý do nào đó mà cột bên trái của bạn trông như này thì đừng lo, nó là file build.gradle trong thư mục app/
Sửa số bên cạnh dòng minSdkVersion thành 16 (1) rồi nhấn Sync Now (2):
Đợi một lúc cho Android Studio sync project rồi sang bước tiếp theo.
Bước 2: Chúng ta sẽ sử dụng lại code ở ví dụ thứ nhất, và thêm một button nữa, đặt chữ trong nút đó là “Di chuyen”:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.howkteam.animationexample.MainActivity">
<Button
android:id="@+id/btn_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="To Second Activity"/>
<Button
android:id="@+id/btn_move"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn_change"
android:text="Di chuyen"/>
</RelativeLayout>
* Ghi chú: Các bạn có để ý là mình sử dụng thuộc tính layout_below không? Đó là vì ViewGroup bao ngoài là RelativeLayout, nếu không sử dụng layout_below thì nút nọ sẽ đè lên nút kia. Học bài mới nhưng không quên bài cũ, nhỉ? CÁC THÀNH PHẦN GIAO DIỆN CƠ BẢN
Bước 3: Phần hay là đây: Chúng ta sẽ đặt thuộc tính chuyển động cho View bằng ViewPropertyAnimator. Ở ví dụ này là translationX:
MainActivity.java
package com.howkteam.animationexample;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private Button btnChange;
private Button btnMove;
boolean clicked = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
btnChange = (Button) findViewById(R.id.btn_change);
btnMove = (Button) findViewById(R.id.btn_move);
final Intent changeActivity = new Intent(this, SecondActivity.class);
btnChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(changeActivity);
}
});
btnMove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!clicked) {
btnMove.animate().translationX(400).withLayer();
clicked = true;
} else {
btnMove.animate().translationX(0).withLayer();
clicked = false;
}
}
});
}
}
Và chúng ta có được màn hình MainActivity với 2 nút. Bấm vào để xem hiệu ứng nhé:
Layout Animation
Bằng cách sử dụng lớp LayoutTransition, chúng ta cũng có thể thay đổi hiệu ứng ở layout bao ngoài, và những thay đổi của các thành phần con trong nó cũng sẽ được tạo hiệu ứng.
Bước 1: Thêm id cho layout bao ngoài (cái RecyclerView ý), đổi nó thành LinearLayout (để làm gì thì lát nữa bạn sẽ thấy), đồng thời thêm 1 button thứ ba để khi click vào, ta tạo một button :
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.howkteam.animationexample.MainActivity">
<Button
android:id="@+id/btn_change"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="To Second Activity"/>
<Button
android:id="@+id/btn_move"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Di chuyen"/>
<Button
android:id="@+id/btn_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Them"/>
</LinearLayout>
Bước 2: Và kế tiếp là file MainActivity.java
package com.howkteam.animationexample;
import android.animation.LayoutTransition;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
private Button btnChange;
private Button btnMove;
private Button btnAdd;
private LinearLayout container;
boolean clicked = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
container = (LinearLayout) findViewById(R.id.activity_main);
LayoutTransition l = new LayoutTransition();
l.enableTransitionType(LayoutTransition.CHANGING);
container.setLayoutTransition(l);
btnAdd = (Button) findViewById(R.id.btn_add);
btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
container.addView(new Button(MainActivity.this));
}
});
btnChange = (Button) findViewById(R.id.btn_change);
btnMove = (Button) findViewById(R.id.btn_move);
final Intent changeActivity = new Intent(this, SecondActivity.class);
btnChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(changeActivity);
}
});
btnMove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!clicked) {
btnMove.animate().translationX(400).withLayer();
clicked = true;
} else {
btnMove.animate().translationX(0).withLayer();
clicked = false;
}
}
});
}
}
Giải thích một chút với các bạn:
- Đối tượng LayoutTransition nhằm tạo hiệu ứng khi nhấn nút tạo ra nút mới.
- LinearLayout hay RelativeLayout đều là ViewGroup, nên chúng đều có hàm setLayoutTransition.
- Nếu không sử dụng hàm setLayoutTransition thì khi nhấn nút Thêm, chúng ta sẽ chỉ thấy nút mới hiện ra mà không có hiệu ứng gì cả.
Và kết quả là:
Click vào nút “Them”, bạn sẽ thấy hiệu ứng diễn ra.
Kết luận
Qua bài này chúng ta đã nắm được Animation cơ bản trong Android và một số cách tạo hiệu ứng cơ bản.
Bài sau chúng ta sẽ tìm hiểu Cách kết nối với Web API, gửi nhận dữ liệu và phân tích chúng bằng OkHttp và Moshi thông qua bài XỬ LÝ BẤT ĐỒNG BỘ.
Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.
Tải xuống
Tài liệu
Nhằm phục vụ mục đích học tập Offline của cộng đồng, Kteam hỗ trợ tính năng lưu trữ nội dung bài học Animation và Transition trong lập trình Android cơ bản dưới dạng file PDF trong link bên dưới.
Ngoài ra, bạn cũng có thể tìm thấy các tài liệu được đóng góp từ cộng đồng ở mục TÀI LIỆU trên thư viện Howkteam.com
Đừng quên like và share để ủng hộ Kteam và tác giả nhé!

Thảo luận
Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.
Nội dung bài viết
Tác giả/Dịch giả
Khóa học
Khóa học lập trình Android cơ bản
Serial tutorial hướng dẫn lập trình Android cơ bản
Tuyệt vời