لوحة عرض دوّارة مع تنسيق MotionLayout

تجربة طريقة "الكتابة"
‫Jetpack Compose هي مجموعة أدوات واجهة المستخدم التي يُنصح باستخدامها على Android. تعرَّف على كيفية إضافة لوحة عرض دوّارة في Compose.

Carousel هو عنصر مساعد للحركة يُستخدَم لإنشاء طرق عرض مخصّصة للوحات العرض الدوّارة تعرض قائمة بالعناصر التي يمكن للمستخدم تصفّحها. مقارنةً بالطرق الأخرى لتنفيذ طرق العرض هذه، تتيح لك هذه الفئة المساعدة إنشاء تغييرات معقّدة في الحركة والأبعاد بسرعة لعنصر Carousel من خلال الاستفادة من MotionLayout.

يتوافق عنصر واجهة المستخدم Carousel مع القوائم التي تتضمّن بداية ونهاية، بالإضافة إلى القوائم الدائرية التي تتكرّر فيها العناصر.

طريقة عمل لوحة العرض الدوّارة باستخدام MotionLayout

لنفترض أنّك تريد إنشاء طريقة عرض أفقية Carousel مع تكبير العنصر الأوسط:

يحتوي هذا التصميم الأساسي على عدة طرق عرض تمثّل عناصر Carousel:

أنشِئ MotionLayout بالحالات الثلاث التالية وأعطِها أرقام تعريف:

  • السابق
  • البدء
  • التالي

إذا كانت حالة البدء تتوافق مع التنسيق الأساسي، في حالة السابق وحالة التالي، يتم نقل عناصر Carousel بمقدار واحد إلى اليسار وإلى اليمين على التوالي.

على سبيل المثال، لنفترض أنّ اللقطات الخمس في الشكل 3 معروضة، وأنّه في حالة البدء، تكون اللقطات 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 للحالة السابقة
  • 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 في الرمز:

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

ملاحظات إضافية

استنادًا إلى العنصر الحالي "المحدّد" في Carousel، قد يلزم إخفاء طرق العرض التي تمثّل العناصر السابقة أو اللاحقة لاحتساب Carousel البداية والنهاية بشكل صحيح. يتولّى المساعد Carousel هذه العملية تلقائيًا. يضع النظام تلقائيًا علامة View.INVISIBLE على هذه المشاهدات في الحالات التالية، وبالتالي لا يتغيّر التنسيق العام.

يتوفّر وضع بديل يحدّد فيه العنصر المساعد Carousel هذه طرق العرض على أنّها View.GONE. يمكنك ضبط هذا الوضع باستخدام السمة التالية:

app:carousel_emptyViewsBehavior="gone"

أمثلة

للاطّلاع على المزيد من الأمثلة التي تستخدم أداة Carousel المساعدة، يمكنك الرجوع إلى المشاريع النموذجية على GitHub.