Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách tạo animation slide Left-Right (trượt trái/phải) trên Android bằng Kotlin

Giới thiệu

Hướng dẫn này trình bày cách tạo hiệu ứng trượt (slide animation) từ trái sang phải và ngược lại cho View trên Android sử dụng TransitionManager và Slide transition (API 19+ / KitKat+), với Kotlin.

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

Bước 1: Tạo dự án mới

Tạo project: File → New Project.

Bước 2: Thiết kế 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/btnSlideLeft"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="30dp"
        android:text="Slide Left" />

    <Button
        android:id="@+id/btnSlideRight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btnSlideLeft"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="Slide Right" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Cristiano Ronaldo is the Best Player in the World"
        android:textSize="16sp"
        android:textStyle="bold"
        android:visibility="invisible" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/textView"
        android:layout_centerInParent="true"
        android:text="Messi is the Best Player in the World"
        android:textSize="16sp"
        android:textStyle="bold"
        android:visibility="invisible" />

</RelativeLayout>

Bước 3: Xử lý logic (src/MainActivity.kt)

import android.os.Bundle
import android.transition.Slide
import android.transition.TransitionManager
import android.view.Gravity
import android.view.View
import android.widget.Button
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private lateinit var btnSlideLeft: Button
    private lateinit var btnSlideRight: Button
    private lateinit var textView: TextView
    private lateinit var textView1: TextView
    private lateinit var relativeLayout: RelativeLayout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "KotlinApp"

        textView = findViewById(R.id.textView)
        textView1 = findViewById(R.id.textView1)
        btnSlideLeft = findViewById(R.id.btnSlideLeft)
        btnSlideRight = findViewById(R.id.btnSlideRight)
        relativeLayout = findViewById(R.id.relativeLayout)

        btnSlideLeft.setOnClickListener {
            val slide = Slide().apply {
                slideEdge = Gravity.START // Trái
                duration = 500 // ms
            }
            TransitionManager.beginDelayedTransition(relativeLayout, slide)
            textView.visibility = View.VISIBLE
        }

        btnSlideRight.setOnClickListener {
            val slide = Slide().apply {
                slideEdge = Gravity.END // Phải
                duration = 500
            }
            TransitionManager.beginDelayedTransition(relativeLayout, slide)
            textView1.visibility = View.VISIBLE
        }
    }
}

Bước 4: Cấu hình Manifest (androidManifest.xml)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.q11">

    <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 "Slide Left" → TextView 1 trượt vào từ trái. Nhấn "Slide Right" → TextView 2 trượt vào từ phải.

Giải thích

  • TransitionManager.beginDelayedTransition(root, transition): Tự động animate các thay đổi thuộc tính (visibility, position, size...) của children trong root view.
  • Slide: Transition trượt vào/ra. slideEdge xác định hướng: Gravity.START (trái), Gravity.END (phải), Gravity.TOP, Gravity.BOTTOM.
  • Chỉ cần thay đổi state (visibility, text, v.v.) sau khi gọi beginDelayedTransition.

Các Transition có sẵn khác

Kết hợp nhiều Transition (TransitionSet)

val set = TransitionSet().apply {
    addTransition(Fade().setDuration(300))
    addTransition(Slide(Gravity.START).setDuration(500))
    ordering = TransitionSet.ORDERING_TOGETHER // Song song
}
TransitionManager.beginDelayedTransition(root, set)

Cách cũ: Animation XML (vẫn dùng được)

res/anim/slide_in_left.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="https://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="-100%"
        android:toXDelta="0%"
        android:duration="500" />
</set>

Sử dụng:

val anim = AnimationUtils.loadAnimation(this, R.anim.slide_in_left)
textView.startAnimation(anim)
textView.visibility = View.VISIBLE

So sánh

  • Transition API (API 19+): Declarative, tự động tính toán, hỗ trợ Material Motion, khuyên dùng cho layout changes.
  • View Animation (API 1+): Imperative, chỉ transform vẽ (không thay đổi layout params), phù hợp cho effect đơn giản.
  • MotionLayout (ConstraintLayout 2.0+): Phức tạp nhất, cho animation phức tạp, timeline, seek.

Lưu ý

  • Transition chỉ hoạt động trên ViewGroup container (RelativeLayout, LinearLayout, ConstraintLayout...).
  • Cần bật android:animateLayoutChanges="true" trên container để auto animate mà không cần code (nhưng ít kiểm soát hơn).
Transition Hiệu ứng
FadeFade in/out (mờ dần)
SlideTrượt từ cạnh
ExplodeNổ từ trung tâm ra 4 hướng
ChangeBoundsDi chuyển/resize view
ChangeTransformScale/rotate view
ChangeImageTransformScale image trong ImageView
AutoTransitionKết hợp Fade + Move + Resize (mặc định)