MotionLayout으로 캐러셀

Compose 방식으로 사용해 보기
Jetpack Compose는 Android의 권장 UI 도구 키트입니다. Compose에서 캐러셀을 추가하는 방법을 알아보세요.

Carousel 은 사용자가 훑어볼 수 있는 요소 목록을 표시하는 맞춤 캐러셀 뷰를 빌드하는 모션 도우미 객체입니다. 이러한 뷰를 구현하는 다른 방법과 비교할 때 이 도우미를 사용하면 Carousel의 복잡한 모션과 크기 변경을 빠르게 만들 수 있습니다. MotionLayout

Carousel 위젯은 시작과 끝이 있는 목록과 원형 래핑 목록을 지원합니다.

MotionLayout으로 캐러셀 작동 방식

중앙 항목이 확대된 가로 Carousel 뷰를 빌드한다고 가정해 보겠습니다.

이 기본 레이아웃에는 Carousel 항목을 나타내는 여러 뷰가 포함되어 있습니다.

다음 세 가지 상태로 MotionLayout을 만들고 ID를 지정합니다.

  • 이전
  • 시작
  • 다음

시작 상태가 기본 레이아웃에 해당하는 경우 이전 상태와 다음 상태에서 Carousel 항목이 각각 왼쪽과 오른쪽으로 하나씩 이동합니다.

예를 들어 그림 3의 5개 뷰를 가져와 시작 상태에서 뷰 B, C, D가 표시되고 A와 E가 화면 밖에 있다고 가정해 보겠습니다. 뷰가 왼쪽에서 오른쪽으로 이동하면서 A, B, C, D의 위치가 B, C, D, E의 위치가 되도록 이전 상태를 설정합니다. 다음 상태에서는 B, C, D, E가 A, B, C, D의 위치로 이동하고 뷰가 오른쪽에서 왼쪽으로 이동하는 반대 상황이 발생해야 합니다. 이는 그림 4에 나와 있습니다.

뷰가 원래 뷰가 시작되는 위치에 정확히 있어야 합니다. Carousel실제 뷰를 원래 위치로 다시 이동하지만 새 일치 콘텐츠로 다시 초기화하여 요소의 무한 컬렉션이라는 착각을 일으킵니다. 다음 다이어그램은 이 메커니즘을 보여줍니다. '항목 #' 값에 주의하세요.

전환

모션 장면 파일에 정의된 이 세 가지 제약조건 집합을 사용하여 시작 상태와 다음 상태 간, 시작 상태와 이전 상태 간에 두 가지 전환(앞으로 및 뒤로)을 만듭니다. 다음 예와 같이 OnSwipe 핸들러를 추가하여 제스처에 응답하여 전환을 트리거합니다.

    <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>

이 기본 모션 장면이 생성되면 레이아웃에 Carousel 도우미를 추가하고 이전 및 다음 애니메이션을 구현하는 것과 동일한 순서로 뷰를 참조합니다.

Carousel 도우미에 다음 속성을 설정합니다.

  • app:carousel_firstView: Carousel의 첫 번째 요소를 나타내는 뷰입니다. 이 예에서는 C입니다.
  • app:carousel_previousState: 이전 상태의 ConstraintSet ID입니다.
  • app:carousel_nextState: 다음 상태의 ConstraintSet ID입니다.
  • app:carousel_backwardTransition: Transition **시작** 상태와 **이전** 상태 간에 적용되는 ID입니다.
  • app:carousel_forwardTransition: Transition ID applied between the start and next states.

예를 들어 레이아웃 XML 파일에 다음과 같은 내용이 있습니다.

    <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>

코드에서 Carousel 어댑터를 설정합니다.

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.
            }
        })

자바

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.
            }
        });

기타 참고사항

Carousel에서 현재 '선택된' 항목에 따라 이전 또는 이후 항목을 나타내는 뷰를 숨겨 Carousel 시작 을 올바르게 고려해야 할 수 있습니다. Carousel 도우미는 이를 자동으로 처리합니다. 기본적으로 이러한 상황에서 이러한 뷰를 View.INVISIBLE로 표시하므로 전체 레이아웃이 변경되지 않습니다.

Carousel 도우미가 이러한 뷰를 View.GONE으로 표시하는 대체 모드를 사용할 수 있습니다. 다음 속성을 사용하여 이 모드를 설정할 수 있습니다.

app:carousel_emptyViewsBehavior="gone"

캐러셀 도우미를 사용하는 더 많은 예는 샘플 프로젝트 를 GitHub에서 참고하세요.