Giới thiệu
Bài viết hướng dẫn tạo animation (hoạt ảnh) bằng file XML trong thư mục res/anim/ và áp dụng lên View. Android hỗ trợ 4 loại animation chính: Alpha (độ trong suốt), Scale (kích thước), Translate (vị trí), Rotate (xoay).
Các bước thực hiện
Bước 1: Tạo dự án mới
Android Studio → File → New Project → Empty Activity.
Bước 2: Layout chính (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Chúc bạn một ngày tuyệt vời!"
android:textSize="24sp"
android:textStyle="bold" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Bắt đầu Animation" />
</RelativeLayout>
Bước 3: Tạo thư mục anim và các file animation
Chuột phải vào res → New → Android Resource Directory → Resource type: anim → OK.
1. Fade In/Out (res/anim/my_anim.xml)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="https://schemas.android.com/apk/res/android"
android:fillAfter="true">
<alpha
android:duration="1000"
android:fromAlpha="0.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="1.0" />
</set>
2. Zoom In (res/anim/zoom.xml)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="https://schemas.android.com/apk/res/android"
android:fillAfter="true">
<scale
android:duration="1000"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="3"
android:toYScale="3" />
</set>
3. Blink (Nhấp nháy) (res/anim/blink.xml)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="https://schemas.android.com/apk/res/android">
<alpha
android:duration="600"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:repeatMode="reverse"
android:repeatCount="infinite" />
</set>
4. Slide In Left (res/anim/slide_in_left.xml) - Bổ sung
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="https://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromXDelta="-100%"
android:toXDelta="0%"
android:interpolator="@android:anim/decelerate_interpolator" />
<alpha
android:duration="500"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
Bước 4: Logic (src/MainActivity.java)
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements Animation.AnimationListener {
TextView textView;
Button button;
Animation animation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
button = findViewById(R.id.button);
// Load animation blink từ XML
animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.blink);
animation.setAnimationListener(this);
button.setOnClickListener(v -> {
textView.setVisibility(View.VISIBLE);
textView.startAnimation(animation);
});
}
@Override
public void onAnimationStart(Animation animation) {
// Animation bắt đầu
}
@Override
public void onAnimationEnd(Animation animation) {
// Animation kết thúc (chỉ khi không repeat infinite)
}
@Override
public void onAnimationRepeat(Animation animation) {
// Mỗi lần lặp lại (blink)
}
}
Bước 5: Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.sample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
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>
</application>
</manifest>
Chạy ứng dụng
Kết nối thiết bị, nhấn Run. Nhấn nút "Bắt đầu Animation" → TextView nhấp nháy.

Các thuộc tính quan trọng
| Thuộc tính | Ý nghĩa |
|---|---|
android:duration | Thời gian animation (milliseconds) |
android:fillAfter | true = giữ trạng thái cuối sau khi kết thúc |
android:repeatCount | Số lần lặp (infinite = vô hạn) |
android:repeatMode | reverse = đảo ngược, restart = bắt đầu lại |
android:interpolator | Hàm easing: accelerate, decelerate, bounce, linear... |
android:pivotX/Y | Điểm neo cho scale/rotate (0-100% hoặc px) |
AnimationListener vs Animation.AnimationListener
Interface Animation.AnimationListener có 3 callback:
onAnimationStart()onAnimationEnd()onAnimationRepeat()
Cách hiện đại: ViewPropertyAnimator / MotionLayout
Từ API 12+, khuyến dùng View.animate() (ViewPropertyAnimator):
textView.animate()
.alpha(0f)
.scaleX(0.5f)
.scaleY(0.5f)
.setDuration(1000)
.setInterpolator(new AccelerateDecelerateInterpolator())
.withEndAction(() -> textView.setVisibility(View.GONE))
.start();
Cho UI phức tạp: MotionLayout (ConstraintLayout 2.0) - định nghĩa chuyển trạng thái trong XML, hỗ trợ seek, transition tự động.