Giới thiệu
Ví dụ này minh họa cách tạo hiệu ứng chuyển đổi mượt mà giữa các màu nền (background color) của một View (TextView, Button, Layout...) sử dụng TransitionDrawable.
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: Giao diện (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:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/textView"
android:layout_centerInParent="true"
android:layout_marginBottom="15dp"
android:text="Chạy Animation Màu Nền" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Màu nền của View này đang thay đổi..."
android:textSize="18sp"
android:textStyle="bold" />
</RelativeLayout>
Bước 3: Code MainActivity (src/MainActivity.java)
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView textView;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
textView = findViewById(R.id.textView);
button.setOnClickListener(v -> {
// Tạo mảng các ColorDrawable (màu đỏ, xanh dương, xanh lá)
ColorDrawable[] colorDrawables = {
new ColorDrawable(Color.RED),
new ColorDrawable(Color.BLUE),
new ColorDrawable(Color.GREEN)
};
// Tạo TransitionDrawable từ mảng màu
TransitionDrawable transitionDrawable = new TransitionDrawable(colorDrawables);
// Set làm background của TextView
textView.setBackground(transitionDrawable);
// Bắt đầu chuyển đổi trong 2000ms (2 giây)
transitionDrawable.startTransition(2000);
});
}
}
Bước 4: Manifest (androidManifest.xml)
<?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 "Chạy Animation Màu Nền" để xem TextView chuyển màu đỏ → xanh dương → xanh lá trong 2 giây.

Giải thích kỹ thuật
- TransitionDrawable: Lớp drawable đặc biệt cho phép cross-fade (phân giải chéo) giữa nhiều layer drawable.
- ColorDrawable: Drawable đơn giản chỉ chứa một màu đặc.
- startTransition(durationMs): Bắt đầu animation chuyển đổi trong khoảng thời gian chỉ định (milliseconds).
Mở rộng & Tùy chỉnh
- Tùy chỉnh thời gian: Thay đổi tham số
startTransition(3000)cho 3 giây, v.v. - Lặp lại (Loop):
TransitionDrawablekhông hỗ trợ loop tự động. DùngValueAnimatorhoặcObjectAnimatorvớiArgbEvaluatorcho animation lặp. - Animation phức tạp hơn: Sử dụng
ObjectAnimator.ofObject(view, "backgroundColor", new ArgbEvaluator(), color1, color2, color3)cho kiểm soát chi tiết hơn (reverse, repeat, delay...). - Áp dụng cho bất kỳ View nào: Layout, Button, ImageView... chỉ cần
view.setBackground(transitionDrawable).
Ví dụ ObjectAnimator (nâng cao)
ObjectAnimator animator = ObjectAnimator.ofObject(
textView,
"backgroundColor",
new ArgbEvaluator(),
Color.RED, Color.BLUE, Color.GREEN, Color.RED
);
animator.setDuration(3000);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.REVERSE);
animator.start();