Di chuyển khung hiển thị bằng ảnh động dựa trên cử chỉ hất

Thử cách dùng Compose
Jetpack Compose là bộ công cụ giao diện người dùng được đề xuất cho Android. Tìm hiểu cách sử dụng Ảnh động trong Compose.

Ảnh động dựa trên cử chỉ hất sử dụng lực ma sát tỷ lệ thuận với tốc độ của đối tượng. Sử dụng thuộc tính này để tạo ảnh động cho một thuộc tính của đối tượng và để kết thúc ảnh động một cách từ từ. Nó có động lượng ban đầu là chủ yếu nhận được nhờ tốc độ cử chỉ, sau đó dần chậm lại. Ảnh động sẽ kết thúc khi tốc độ của ảnh động đủ thấp để không tạo ra thay đổi rõ ràng nào trên màn hình thiết bị.

Hình 1. Ảnh động hất

Để tìm hiểu về các chủ đề có liên quan, hãy đọc các hướng dẫn sau:

Thêm thư viện AndroidX

Để sử dụng ảnh động dựa trên vật lý, bạn phải thêm thư viện AndroidX vào dự án như sau:

  1. Mở tệp build.gradle cho mô-đun ứng dụng.
  2. Thêm thư viện AndroidX vào phần dependencies.

    Groovy

            dependencies {
                implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'
            }
            

    Kotlin

            dependencies {
                implementation("androidx.dynamicanimation:dynamicanimation:1.0.0")
            }
            

Tạo ảnh động hất

Lớp FlingAnimation cho phép bạn tạo ảnh động vuốt nhanh cho một đối tượng. Để tạo ảnh động dựa trên cử chỉ hất, hãy tạo một thực thể của lớp FlingAnimation và cung cấp đối tượng và thuộc tính của đối tượng mà bạn muốn tạo ảnh động.

Kotlin

val fling = FlingAnimation(view, DynamicAnimation.SCROLL_X)

Java

FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X);

Đặt tốc độ

Vận tốc bắt đầu xác định tốc độ của thuộc tính ảnh động những thay đổi ở đầu ảnh động. Vận tốc bắt đầu mặc định là được đặt thành 0 pixel/giây. Do đó, bạn phải xác định tốc độ bắt đầu để đảm bảo ảnh động không kết thúc ngay lập tức.

Bạn có thể dùng một giá trị cố định làm vận tốc ban đầu hoặc dựa vào giá trị đó tốc độ của cử chỉ chạm. Nếu bạn chọn cung cấp giá trị cố định, bạn nên xác định giá trị theo dp mỗi giây, sau đó chuyển đổi giá trị này thành pixel mỗi giây. Việc xác định giá trị tính bằng dp mỗi giây cho phép tốc độ là không phụ thuộc vào mật độ và các kiểu dáng của thiết bị. Để biết thêm thông tin về cách chuyển đổi vận tốc bắt đầu thành pixel/giây, hãy tham khảo phần Chuyển đổi dp/giây thành pixel/giây trong Ảnh động dựa trên lực lò xo.

Để thiết lập tốc độ, hãy gọi phương thức setStartVelocity() và truyền vận tốc tính bằng pixel/giây. Phương thức này trả về đối tượng hất vận tốc được thiết lập.

Lưu ý: Hãy sử dụng GestureDetector.OnGestureListener và Các lớp VelocityTracker để truy xuất và tính toán tốc độ của các cử chỉ chạm, tương ứng.

Đặt phạm vi giá trị ảnh động

Bạn có thể đặt giá trị tối thiểu và tối đa của ảnh động khi muốn hạn chế giá trị thuộc tính ở một phạm vi nhất định. Công cụ kiểm soát phạm vi này là đặc biệt hữu ích khi bạn tạo ảnh động cho các thuộc tính có hàm nội tại phạm vi, chẳng hạn như alpha (từ 0 đến 1).

Lưu ý: Khi giá trị của ảnh động hất đạt đến giá trị tối thiểu hoặc tối đa, ảnh động sẽ kết thúc.

Để đặt giá trị tối thiểu và tối đa, hãy gọi lần lượt các phương thức setMinValue()setMaxValue(). Cả hai phương thức đều trả về đối tượng ảnh động mà bạn đã đặt giá trị.

Đặt độ ma sát

Phương thức setFriction() cho phép bạn thay đổi độ ma sát của ảnh động. Tham số này xác định tốc độ giảm của tốc độ trong ảnh động.

Lưu ý: Nếu bạn không đặt độ ma sát ở đầu ảnh động, thì ảnh động sẽ sử dụng giá trị độ ma sát mặc định là 1.

Phương thức này trả về đối tượng có ảnh động sử dụng giá trị ma sát mà bạn cung cấp.

Mã mẫu

Ví dụ dưới đây minh hoạ một thao tác hất ngang. Tốc độ được ghi lại từ trình theo dõi tốc độ là velocityX và giới hạn cuộn được đặt thành 0 và maxScroll. Độ ma sát được đặt là 1.1.

Kotlin

FlingAnimation(view, DynamicAnimation.SCROLL_X).apply {
    setStartVelocity(-velocityX)
    setMinValue(0f)
    setMaxValue(maxScroll)
    friction = 1.1f
    start()
}

Java

FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X);
fling.setStartVelocity(-velocityX)
        .setMinValue(0)
        .setMaxValue(maxScroll)
        .setFriction(1.1f)
        .start();

Đặt thay đổi tối thiểu có thể nhìn thấy

Khi tạo ảnh động cho một thuộc tính tuỳ chỉnh không được xác định bằng pixel, bạn nên đặt mức thay đổi tối thiểu của giá trị ảnh động mà người dùng có thể nhìn thấy. Phương thức này xác định ngưỡng hợp lý để kết thúc ảnh động.

Bạn không cần gọi phương thức này khi tạo ảnh động cho DynamicAnimation.ViewProperty vì thay đổi tối thiểu có thể nhìn thấy được bắt nguồn từ thuộc tính này. Ví dụ:

  • Giá trị thay đổi hiển thị tối thiểu mặc định là 1 pixel đối với chế độ xem các thuộc tính như TRANSLATION_X, TRANSLATION_Y TRANSLATION_Z, SCROLL_XSCROLL_Y.
  • Đối với ảnh động sử dụng chế độ xoay, chẳng hạn như ROTATION, ROTATION_XROTATION_Y, thay đổi tối thiểu có thể nhìn thấy là MIN_VISIBLE_CHANGE_ROTATION_DEGREES hoặc 1/10 pixel.
  • Đối với ảnh động sử dụng độ mờ, thay đổi tối thiểu có thể nhìn thấy là MIN_VISIBLE_CHANGE_ALPHA hoặc 1/256.

Để đặt thay đổi hiển thị tối thiểu cho ảnh động, hãy gọi phương thức Phương thức setMinimumVisibleChange() và truyền một trong hai một trong các hằng số hiển thị tối thiểu hoặc một giá trị mà bạn cần tính cho một thuộc tính tuỳ chỉnh. Để biết thêm thông tin về cách tính giá trị này, tham chiếu đến Tính toán giá trị thay đổi hiển thị tối thiểu .

Kotlin

anim.minimumVisibleChange = DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE

Java

anim.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);

Lưu ý: Bạn chỉ cần truyền một giá trị khi tạo ảnh động cho một thuộc tính tuỳ chỉnh không được xác định bằng pixel.

Tính giá trị thay đổi tối thiểu có thể nhìn thấy

Để tính toán giá trị thay đổi tối thiểu có thể nhìn thấy cho một thuộc tính tuỳ chỉnh, hãy sử dụng công thức sau:

Mức thay đổi hiển thị tối thiểu = Phạm vi của giá trị thuộc tính tùy chỉnh / Phạm vi hiệu ứng động (tính theo pixel)

Ví dụ: thuộc tính mà bạn muốn tạo ảnh động tiến trình từ 0 đến 100. Điều này tương ứng với thay đổi 200 pixel. Theo công thức, giá trị nhỏ nhất giá trị thay đổi nhìn thấy được là 100 / 200 tương đương với 0,5 pixel.