گردونه با MotionLayout

امتحان کردن روش Compose
Jetpack Compose جعبه‌ابزار واسط کاربر توصیه‌شده برای Android است. با نحوه افزودن گردونه در Compose آشنا شوید.

Carousel یک شیء کمکی حرکت برای ساختن نماهای گردونه سفارشی است که فهرستی از عناصر را نشان می‌دهد که کاربر می‌تواند آن‌ها را مرور کند. درمقایسه با روش‌های دیگر برای پیاده‌سازی چنین نماهایی، این کمک‌کننده به شما امکان می‌دهد بااستفاده از MotionLayout، به‌سرعت تغییرات پیچیده حرکت و بُعد را برای Carousel خود ایجاد کنید.

ابزاره Carousel از فهرست‌های دارای شروع و پایان و همچنین فهرست‌های چرخشی پشتیبانی می‌کند.

نحوه عملکرد «گردونه» با MotionLayout

فرض کنید می‌خواهید نمای افقی Carousel بسازید که در آن عنصر مرکزی بزرگ شده باشد:

این چیدمان پایه حاوی چند نما است که Carousel مورد را نشان می‌دهد:

یک MotionLayout با سه حالت زیر ایجاد کنید و به آن‌ها شناسه بدهید:

  • قبلی
  • شروع
  • بعدی

اگر حالت شروع با چیدمان پایه مطابقت داشته باشد، در حالت قبلی و حالت بعدی، موارد Carousel به‌ترتیب یک واحد به چپ و راست جابه‌جا می‌شوند.

برای مثال، پنج نمای شکل ۳ را درنظر بگیرید و فرض کنید که در وضعیت شروع، نماهای B،‏ C، و D نمایان هستند و A و E خارج از صفحه‌نمایش قرار دارند. وضعیت قبلی را طوری تنظیم کنید که موقعیت‌های A،‏ B،‏ C، و D جایی باشد که B،‏ C،‏ D، و E بودند و نماها از چپ به راست حرکت کنند. در حالت بعدی، عکس این اتفاق باید بیفتد، یعنی B،‏ C،‏ D، و E به جایی که A،‏ B،‏ C، و D بودند منتقل شوند و نماها از راست به چپ حرکت کنند. این مورد در شکل ۴ نشان داده شده است:

بسیار مهم است که نماها دقیقاً در جایی که نماهای اصلی شروع می‌شوند، پایان یابند. ‫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 مربوط به وضعیت قبلی.
  • app:carousel_nextState: شناسه ConstraintSet وضعیت بعدی.
  • app:carousel_backwardTransition: Transition شناسه اعمال‌شده بین حالت‌های شروع و قبلی.
  • ‫app:carousel_forwardTransition: شناسه Transition اعمال‌شده بین وضعیت‌های شروع و بعدی.

برای مثال، چیزی شبیه به این در فایل 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 در کد:

کاتلین

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 helper handles this automatically. به‌طور پیش‌فرض، این نماها را در این شرایط به‌عنوان View.INVISIBLE علامت‌گذاری می‌کند، بنابراین چیدمان کلی تغییر نمی‌کند.

حالت جایگزینی دردسترس است که در آن کمک‌کننده Carousel درعوض آن نماها را به‌عنوان View.GONE علامت‌گذاری می‌کند. می‌توانید این حالت را بااستفاده از ویژگی زیر تنظیم کنید:

app:carousel_emptyViewsBehavior="gone"

مثال‌ها

برای مثال‌های بیشتر بااستفاده از کمک‌کننده «گردونه»، پروژه‌های نمونه را در GitHub ببینید.