Băng chuyền có MotionLayout

Carousel là một đối tượng trợ giúp chuyển động để tạo thành phần hiển thị băng chuyền tuỳ chỉnh hiển thị danh sách các phần tử mà người dùng có thể lướt qua. So với những cách khác để triển khai các thành phần hiển thị như vậy, trình trợ giúp này cho phép bạn nhanh chóng tạo các thay đổi phức tạp về chuyển động và kích thước cho Carousel bằng cách tận dụng MotionLayout.

Tiện ích Carousel hỗ trợ các danh sách có bắt đầu và kết thúc cũng như các danh sách bao quanh theo vòng tròn.

Cách hoạt động của Băng chuyền với MotionLayout

Giả sử bạn muốn tạo thành phần hiển thị Carousel theo chiều ngang, với mục ở giữa được mở rộng:

Bố cục cơ bản này chứa một số khung hiển thị đại diện cho các mục Carousel:

Tạo MotionLayout có 3 trạng thái sau đây và đặt mã nhận dạng cho các trạng thái đó:

  • trước
  • bắt đầu
  • tiếp theo

Nếu trạng thái start tương ứng với bố cục cơ sở, thì ở trạng thái trước và trạng thái tiếp theo, các mục Carousel sẽ được dịch chuyển lần lượt sang trái và sang phải.

Ví dụ: lấy 5 khung hiển thị trong hình 3 và giả định rằng ở trạng thái bắt đầu, các khung hiển thị B, C và D đều xuất hiện, còn A và E nằm ngoài màn hình. Thiết lập trạng thái trước đó sao cho vị trí của A, B, C và D là B, C, D và E, trong đó các khung hiển thị di chuyển từ trái sang phải. Ở trạng thái tiếp theo, điều ngược lại cần xảy ra, trong đó B, C, D và E di chuyển đến vị trí A, B, C và D và các khung hiển thị di chuyển từ phải sang trái. Điều này được thể hiện trong hình 4:

Điều quan trọng là lượt xem kết thúc chính xác tại điểm bắt đầu của lượt xem ban đầu. Carousel tạo ảo giác về một tập hợp phần tử vô hạn bằng cách di chuyển các chế độ xem thực tế về vị trí trước đó, nhưng khởi tạo lại chúng bằng nội dung phù hợp mới. Sơ đồ dưới đây cho thấy cơ chế này. Chú ý đến các giá trị "mục #"):

Kiểu chuyển cảnh

Với 3 bộ quy tắc ràng buộc này được xác định trong tệp cảnh chuyển động, hãy tạo 2 hiệu ứng chuyển đổi tiến và lùi giữa trạng thái start (bắt đầu) và next (tiếp theo) cũng như trạng thái start (bắt đầu) và trước đó. Thêm trình xử lý OnSwipe để kích hoạt hiệu ứng chuyển đổi phản hồi một cử chỉ, như trong ví dụ sau:

    <Transition
        motion:constraintSetStart="@id/start"
        motion:constraintSetEnd="@+id/next"
        motion:duration="1000"
        android:id="@+id/forward">
        <OnSwipe
            motion:dragDirection="dragLeft"
            motion:touchAnchorSide="left" />
    </Transition>

    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/previous"
        android:id="@+id/backward">
        <OnSwipe
            motion:dragDirection="dragRight"
            motion:touchAnchorSide="right" />
    </Transition>

Sau khi tạo cảnh chuyển động cơ bản này, hãy thêm trình trợ giúp Carousel vào bố cục và tham chiếu các khung hiển thị theo cùng thứ tự triển khai ảnh động trước đó và tiếp theo.

Đặt các thuộc tính sau cho trình trợ giúp Carousel:

  • app:carousel_firstView: khung hiển thị đại diện cho phần tử đầu tiên của Carousel – trong ví dụ này là C.
  • app:carousel_previousState: mã nhận dạng ConstraintSet của trạng thái trước đó.
  • app:carousel_nextState: mã nhận dạng ConstraintSet của trạng thái tiếp theo.
  • app:carousel_backwardTransition: mã nhận dạng Transition được áp dụng giữa trạng thái bắt đầutrước đó.
  • app:carousel_forwardTransition: mã nhận dạng Transition được áp dụng giữa trạng thái bắt đầutiếp theo.

Ví dụ: bạn có nội dung như sau trong tệp XML bố cục:

    <androidx.constraintlayout.motion.widget.MotionLayout ... >

        <ImageView  android:id="@+id/imageView0" .. />
        <ImageView  android:id="@+id/imageView1" .. />
        <ImageView  android:id="@+id/imageView2" .. />
        <ImageView  android:id="@+id/imageView3" .. />
        <ImageView  android:id="@+id/imageView4" .. />

        <androidx.constraintlayout.helper.widget.Carousel
            android:id="@+id/carousel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:carousel_forwardTransition="@+id/forward"
            app:carousel_backwardTransition="@+id/backward"
            app:carousel_previousState="@+id/previous"
            app:carousel_nextState="@+id/next"
            app:carousel_infinite="true"
            app:carousel_firstView="@+id/imageView2"
            app:constraint_referenced_ids="imageView0,imageView1,imageView2,imageView3,imageView4" />

    </androidx.constraintlayout.motion.widget.MotionLayout>

Thiết lập bộ chuyển đổi Carousel trong mã:

Kotlin

carousel.setAdapter(object : Carousel.Adapter {
            override fun count(): Int {
              // Return the number of items in the Carousel.
            }

            override fun populate(view: View, index: Int) {
                // Implement this to populate the view at the given index.
            }

            override fun onNewItem(index: Int) {
                // Called when an item is set.
            }
        })

Java

carousel.setAdapter(new Carousel.Adapter() {
            @Override
            public int count() {
                // Return the number of items in the Carousel.
            }

            @Override
            public void populate(View view, int index) {
                // Populate the view at the given index.
            }

            @Override
            public void onNewItem(int index) {
                 // Called when an item is set.
            }
        });

Ghi chú khác

Tuỳ thuộc vào mục hiện tại "được chọn" trong Carousel, các khung hiển thị biểu thị các mục trước hoặc sau có thể cần được ẩn để tính đến đúng Carousel bắt đầukết thúc. Trình trợ giúp Carousel sẽ tự động xử lý vấn đề này. Theo mặc định, khung hiển thị này sẽ đánh dấu các khung hiển thị đó là View.INVISIBLE trong các trường hợp này, vì vậy, bố cục tổng thể không thay đổi.

Có một chế độ thay thế, trong đó trình trợ giúp Carousel đánh dấu các khung hiển thị đó là View.GONE. Bạn có thể đặt chế độ này bằng thuộc tính sau:

app:carousel_emptyViewsBehavior="gone"

Ví dụ

Để biết thêm ví dụ về cách sử dụng trình trợ giúp Băng chuyền, hãy xem các dự án mẫu trên GitHub.