CyStack logo
  • Sản phẩm & Dịch vụ
  • Giải pháp
  • Bảng giá
  • Công ty
  • Tài liệu
Vi

vi

Mục lục

Trang chủBlogAnimation trong Android v...
Android

Animation trong Android với XML: Toàn tập từ cơ bản đến nâng cao”

8 phút đọc23/08/2025
CyStack Author
Chris Pham

Technical Writer

0 lượt xem
Reading Time: 8 minutes

Animation trong Android được sử dụng để tạo giao diện người dùng (UI) sống động, mang lại trải nghiệm trực quan và hấp dẫn hơn. Trong các ứng dụng Android, bạn có thể thực hiện animation thông qua XML hoặc viết trực tiếp bằng mã Java/Kotlin. Trong hướng dẫn này, chúng ta sẽ sử dụng mã XML để thêm các hiệu ứng animation vào ứng dụng.

Animation trong Android

Khái niệm Animation trong Android

Animation trong Android là quá trình tạo chuyển động và thay đổi hình dạng. Các loại animation cơ bản mà chúng ta sẽ tìm hiểu trong bài viết này bao gồm:

  1. Fade In Animation
  2. Fade Out Animation
  3. Cross Fading Animation
  4. Blink Animation
  5. Zoom In Animation
  6. Zoom Out Animation
  7. Rotate Animation
  8. Move Animation
  9. Slide Up Animation
  10. Slide Down Animation
  11. Bounce Animation
  12. Sequential Animation
  13. Together Animation

Ví dụ Animation bằng XML trong Android

Chúng ta sẽ tạo một thư mục tài nguyên mới có tên anim trong thư mục res/, dùng để chứa tất cả các file XML định nghĩa logic animation. Dưới đây là một ví dụ file XML đơn giản mô tả logic animation trong Android: sample_animation.xml



  • android:interpolator: Đây là thuộc tính xác định tốc độ thay đổi của animation theo thời gian. Chúng ta có thể tự định nghĩa interpolator riêng bằng cách sử dụng thời gian làm ràng buộc. Trong ví dụ XML trên, chúng ta đã gán một interpolator có sẵn (inbuilt interpolator).
  • android:duration: Thời lượng của animation – tức là khoảng thời gian animation sẽ được thực thi. Trong ví dụ này là 300 mili giây. Đây cũng là khoảng thời gian lý tưởng để thể hiện hiệu ứng chuyển động mượt mà trên màn hình. Thời điểm bắt đầu và kết thúc của animation có thể được thiết lập thông qua các thuộc tính sau:
android:fromTRANSFORMATION
android:toTRANSFORMATION
  • TRANSFORMATION: là phép biến đổi mà chúng ta muốn xác định. Trong trường hợp này, chúng ta bắt đầu với tỉ lệ x và y bằng 0 và kết thúc với tỉ lệ x và y bằng 1.
  • android:fillAfter: thuộc tính này xác định liệu view có được hiển thị hay ẩn đi sau khi animation kết thúc. Trong đoạn mã trên, chúng ta đã đặt nó hiển thị (true). Nếu đặt là false, phần tử sẽ trở về trạng thái ban đầu sau khi animation hoàn tất.
  • android:startOffset: là khoảng thời gian chờ trước khi animation bắt đầu. Thuộc tính này chủ yếu được sử dụng khi thực hiện nhiều animation theo thứ tự tuần tự.
  • android:repeatMode: hữu ích khi bạn muốn lặp lại animation.
  • android:repeatCount: xác định số lần lặp lại của animation. Nếu chúng ta đặt giá trị này là infinite (vô hạn) thì animation sẽ được lặp lại vô số lần.

Animation khi widget giao diện người dùng được nhấn

****Mục tiêu của chúng ta là hiển thị một animation khi bất kỳ widget nào (ví dụ như TextView) được nhấn vào. Để làm điều đó, chúng ta cần sử dụng lớp Animation. Tệp XML chứa logic animation sẽ được tải bằng lớp AnimationUtils bằng cách gọi hàm loadAnimation(). Phần bên dưới minh họa cách triển khai này.

Animation animation;
animation = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.sample_animation);

Để bắt đầu animation, chúng ta cần gọi hàm startAnimation() trên phần tử giao diện người dùng, như minh họa trong đoạn mã bên dưới.

sampleTextView.startAnimation(animation);

Ở đây, chúng ta thực hiện animation trên một thành phần textview bằng cách truyền kiểu Animation làm tham số.

Thiết lập Animation Listeners

Chúng ta chỉ cần phần này nếu muốn lắng nghe các sự kiện như bắt đầu, kết thúc hoặc lặp lại animation. Để làm điều đó, activity cần implement AnimationListener và override các phương thức sau:

  • onAnimationStart: được kích hoạt khi animation bắt đầu
  • onAnimationEnd: được kích hoạt khi animation kết thúc
  • onAnimationRepeat: được kích hoạt nếu animation được lặp lại

Cấu trúc dự án Android Animation

Ví dụ Animation trong Android

Như bạn có thể thấy, chúng ta đã bao gồm các tệp XML cho hầu hết các loại animation chính được đề cập ở trên.

Ví dụ về mã XML Animation trong Android

Dưới đây là các đoạn mã ví dụ cho hầu hết các animation phổ biến trong Android.

Fade In Animation

fade_in.xml



    


Trong đoạn này, alpha đại diện cho độ mờ của một đối tượng. Một đối tượng có giá trị alpha thấp sẽ trong suốt hơn, còn một đối tượng có giá trị alpha cao thì ít trong suốt hơn, tức là đục hơn. Animation dạng “fade in” đơn giản là quá trình tăng giá trị alpha từ 0 đến 1.

Fade Out Animation

fade_out.xml



    


Fade out animation trong Android là quá trình ngược lại so với fade in, tức là giảm giá trị alpha từ 1 xuống 0.

Cross Fading Animation

Cross fading là hiệu ứng đồng thời: một TextView thực hiện animation fade in trong khi một TextView khác thực hiện fade out. Có thể đạt được hiệu ứng này bằng cách áp dụng fade_in.xmlfade_out.xml lần lượt cho hai TextView. Mã nguồn ví dụ sẽ được trình bày trong MainActivity.java.

blink.xml


    

Ở đây, hiệu ứng fade in và fade out được thực hiện lặp lại vô hạn, mỗi lần sẽ đảo ngược chế độ (reverse mode) so với lần trước.

Zoom In Animation zoom_in.xml



    
    


Chúng ta sử dụng pivotX="50%"pivotY="50%" để thực hiện thu nhỏ từ tâm của phần tử.

Zoom Out Animation zoom_out.xml



    
    


Lưu ý rằng android:fromandroid:to có giá trị ngược nhau trong zoom_in.xmlzoom_out.xml.

Rotate Animation rotate.xml


    


Thẻ from/toDegrees được sử dụng ở đây để xác định góc độ, và một bộ nội suy chu kỳ (cyclic interpolator) được sử dụng.

Move Animation move.xml



   

Slide Up Animation slide_up.xml



    


Điều này được thực hiện bằng cách thiết lập android:fromYScale=”1.0″android:toYScale=”0.0″ bên trong thẻ scale.

Slide Down Animation slide_down.xml



    


Bounce Animation bounce.xml



    


Sequential Animation sequential.xml



  
    
    
    
    
    

    
    


Một giá trị android:startOffset khác được sử dụng cho các chuyển động để đảm bảo chúng diễn ra tuần tự.

Together Animation together.xml



    
    
    
    

    
    


Code

Layout activity_main.xml bao gồm một ScrollView và RelativeLayout (chúng ta sẽ thảo luận phần này trong một hướng dẫn sau), trong đó mỗi loại animation được kích hoạt trên văn bản thông qua các nút tương ứng. Tệp xml được trình bày bên dưới: activity_main.xml



    

        

Tóm lại, RelativeLayout sắp xếp các thành phần giao diện UI dựa trên vị trí tương đối với nhau. Tệp MainActivity.java chứa các onclick listener (trình lắng nghe sự kiện nhấp chuột) cho từng nút tương ứng với loại animation của nó. Mã nguồn được trình bày bên dưới.

package com.journaldev.animations;

import android.app.Activity;
import android.content.Intent;
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 Activity {

    Button btnFadeIn, btnFadeOut, btnCrossFade, btnBlink, btnZoomIn,
            btnZoomOut, btnRotate, btnMove, btnSlideUp, btnSlideDown,
            btnBounce, btnSequential, btnTogether;
    Animation animFadeIn,animFadeOut,animBlink,animZoomIn,animZoomOut,animRotate
            ,animMove,animSlideUp,animSlideDown,animBounce,animSequential,animTogether,animCrossFadeIn,animCrossFadeOut;
    TextView txtFadeIn,txtFadeOut,txtBlink,txtZoomIn,txtZoomOut,txtRotate,txtMove,txtSlideUp,
                txtSlideDown,txtBounce,txtSeq,txtTog,txtIn,txtOut;

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

        btnFadeIn = (Button) findViewById(R.id.btnFadeIn);
        btnFadeOut = (Button) findViewById(R.id.btnFadeOut);
        btnCrossFade = (Button) findViewById(R.id.btnCrossFade);
        btnBlink = (Button) findViewById(R.id.btnBlink);
        btnZoomIn = (Button) findViewById(R.id.btnZoomIn);
        btnZoomOut = (Button) findViewById(R.id.btnZoomOut);
        btnRotate = (Button) findViewById(R.id.btnRotate);
        btnMove = (Button) findViewById(R.id.btnMove);
        btnSlideUp = (Button) findViewById(R.id.btnSlideUp);
        btnSlideDown = (Button) findViewById(R.id.btnSlideDown);
        btnBounce = (Button) findViewById(R.id.btnBounce);
        btnSequential = (Button) findViewById(R.id.btnSequential);
        btnTogether = (Button) findViewById(R.id.btnTogether);
        txtFadeIn=(TextView)findViewById(R.id.txt_fade_in);
        txtFadeOut=(TextView)findViewById(R.id.txt_fade_out);
        txtBlink=(TextView)findViewById(R.id.txt_blink);
        txtZoomIn=(TextView)findViewById(R.id.txt_zoom_in);
        txtZoomOut=(TextView)findViewById(R.id.txt_zoom_out);
        txtRotate=(TextView)findViewById(R.id.txt_rotate);
        txtMove=(TextView)findViewById(R.id.txt_move);
        txtSlideUp=(TextView)findViewById(R.id.txt_slide_up);
        txtSlideDown=(TextView)findViewById(R.id.txt_slide_down);
        txtBounce=(TextView)findViewById(R.id.txt_bounce);
        txtSeq=(TextView)findViewById(R.id.txt_seq);
        txtTog=(TextView)findViewById(R.id.txt_tog);
        txtIn=(TextView)findViewById(R.id.txt_in);
        txtOut=(TextView)findViewById(R.id.txt_out);
        animFadeIn = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.fade_in);
		
        animFadeIn = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.fade_in);
        // fade in
        btnFadeIn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                txtFadeIn.setVisibility(View.VISIBLE);
                txtFadeIn.startAnimation(animFadeIn);
            }
        });

        animFadeOut = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.fade_out);

        // fade out
        btnFadeOut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtFadeOut.setVisibility(View.VISIBLE);
                txtFadeOut.startAnimation(animFadeOut);
            }
        });
        animCrossFadeIn = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.fade_in);
        animCrossFadeOut = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.fade_out);
        // cross fade
        btnCrossFade.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtOut.setVisibility(View.VISIBLE);
                // start fade in animation
                txtOut.startAnimation(animCrossFadeIn);

                // start fade out animation
                txtIn.startAnimation(animCrossFadeOut);
            }
        });
        animBlink = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.blink);
        // blink
        btnBlink.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtBlink.setVisibility(View.VISIBLE);
                txtBlink.startAnimation(animBlink);
            }
        });

        animZoomIn = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.zoom_in);
        // Zoom In
        btnZoomIn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtZoomIn.setVisibility(View.VISIBLE);
                txtZoomIn.startAnimation(animZoomIn);
            }
        });
        animZoomOut = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.zoom_out);
        // Zoom Out
        btnZoomOut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtZoomOut.setVisibility(View.VISIBLE);
                txtZoomOut.startAnimation(animZoomOut);
            }
        });
        animRotate = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.rotate);

        // Rotate
        btnRotate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtRotate.startAnimation(animRotate);
            }
        });
        animMove = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.move);
        // Move
        btnMove.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtMove.startAnimation(animMove);
            }
        });
        animSlideUp = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.slide_up);
        // Slide Up
        btnSlideUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtSlideUp.startAnimation(animSlideUp);
            }
        });
        animSlideDown = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.slide_down);
        // Slide Down
        btnSlideDown.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtSlideDown.startAnimation(animSlideDown);
            }
        });
        animBounce = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.bounce);
        // Slide Down
        btnBounce.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtBounce.startAnimation(animBounce);
            }
        });
        animSequential = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.sequential);
        // Sequential
        btnSequential.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                        txtSeq.startAnimation(animSequential);
            }
        });
        animTogether = AnimationUtils.loadAnimation(getApplicationContext(),
                R.anim.together);

        // Together
        btnTogether.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                txtTog.startAnimation(animTogether);
            }
        });

    }
}

Như đã đề cập trước đó, mỗi animation cho TextView được bắt đầu bằng cách gọi đối tượng animation tương ứng, trong đó logic animation được tải bằng phương thức AnimationUtils.loadAnimation(). Animation crossFade bao gồm hai TextView, một cái mờ dần biến mất (fade out) và cái còn lại hiện dần lên (fade in). Bên dưới là một đoạn video ngắn trình bày tất cả các animation trong ứng dụng của chúng ta.

Ví dụ Animation trong Android

Animation together được minh họa trong hình phía trên. Lưu ý rằng các animation này khi chạy trên trình giả lập có thể không mượt, vì vậy nên chạy ứng dụng trên thiết bị thật.

Về tác giả

Chris Pham
Chris PhamTechnical Writer

I have over 5 years of experience writing technical documentation for tech products, making them accessible and user-friendly. My focus is always on providing clear and precise information. @#@ Tôi đã có hơn 5 năm kinh nghiệm viết tài liệu kỹ thuật cho các sản phẩm công nghệ, giúp người dùng dễ dàng tiếp cận và sử dụng. Tôi luôn tập trung vào việc cung cấp thông tin chính xác và dễ hiểu.

Cập nhật thông tin mới nhấtNhận các thông tin mới nhất về mối đe dọa, báo cáo an ninh mạng từ CyStack về hòm thư điện tử của bạn

Thảo luận (0)

Đăng nhập để thảo luận

Bài viết liên quan