إتاحة استخدام صور متحركة لإيماءة إظهار شاشة الرجوع في "طرق العرض"

يمكنك إنشاء صور متحركة وانتقالات مخصّصة للخصائص داخل التطبيق، وصور متحركة مخصّصة للانتقال بين الأنشطة، وصور متحركة مخصّصة للانتقال بين الأجزاء باستخدام إيماءات إظهار شاشة الرجوع، وذلك باستخدام طريقة العرض أو Compose. لتجربة طريقة Compose، يُرجى الاطّلاع على مقالة إضافة دعم الصور المتحركة لإيماءة إظهار شاشة الرجوع.

إضافة انتقالات مخصّصة باستخدام Progress API

باستخدام AndroidX Activity 1.8.0-alpha01 أو إصدار أحدث، يمكنك استخدام واجهات برمجة التطبيقات Predictive Back Progress APIs لتطوير صور متحركة مخصّصة لإيماءة إظهار شاشة الرجوع في تطبيقك. تساعد واجهات برمجة التطبيقات Progress APIs في تحريك طرق العرض، ولكنها تواجه قيودًا عند تحريك الانتقالات بين الأجزاء. ضمن OnBackPressedCallback ، قدّمنا الطرق handleOnBackProgressed وhandleOnBackCancelled وhandleOnBackStarted لتحريك العناصر أثناء تمرير المستخدم سريعًا للرج101}وع. استخدِم هذه الطرق إذا كنت بحاجة إلى تخصيص أكثر من الصور المتحركة التلقائية التي يوفّرها النظام أو الصور المتحركة لمكوّنات Material.

نتوقّع أن تستخدم معظم التطبيقات واجهات برمجة التطبيقات AndroidX المتوافقة مع الإصدارات السابقة، ولكن تتوفّر أيضًا واجهات برمجة تطبيقات مشابهة للمنصة ضمن الـ OnBackAnimationCallback لاختبارها في Android 14 والإصدارات الأحدث.

استخدام واجهات برمجة التطبيقات Progress APIs مع AndroidX Transitions

يمكن استخدام واجهات برمجة التطبيقات Progress APIs مع AndroidX Transitions 1.5.0-alpha01 أو إصدار أحدث على Android 14 والإصدارات الأحدث لإنشاء انتقالات إيماءة إظهار شاشة الرجوع.

  1. استخدِم TransitionManager#controlDelayedTransition بدلاً من beginDelayedTransition لتشغيل الانتقالات أثناء تمرير المستخدم سريعًا للرجوع.
  2. أنشئ الانتقال ضمن handleOnBackStarted.
  3. شغِّل الانتقال باستخدام حدث الرجوع ضمن handleOnBackProgressed من خلال ربط currentFraction بـ BackEvent.progress الذي يعرض مدى تمرير المستخدم سريعًا للرجوع.
  4. أنهِ الانتقال بعد أن يُنفّذ المستخدم إيماءة الرجوع في handleOnBackPressed.
  5. أخيرًا، أعِد ضبط حالة الانتقال ضمن handleOnBackCancelled.

يعرض الفيديو والرمز البرمجي بلغة Kotlin وتنسيق XML التاليان انتقالاً مخصّصًا بين مربّعين تم تنفيذهما باستخدام OnBackPressedCallback:

    class MyFragment : Fragment() {

    val transitionSet = TransitionSet().apply {
        addTransition(Fade(Fade.MODE_OUT))
        addTransition(ChangeBounds())
        addTransition(Fade(Fade.MODE_IN))
    }
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val callback = object : OnBackPressedCallback(enabled = false) {

            var controller: TransitionSeekController? = null

            @RequiresApi(34)
            override fun handleOnBackStarted(backEvent: BackEvent) {
                // Create the transition
                controller = TransitionManager.controlDelayedTransition(
                    binding.card,
                    transitionSet
                )
                changeTextVisibility(ShowText.SHORT)
            }

            @RequiresApi(34)
            override fun handleOnBackProgressed(backEvent: BackEvent) {
                // Play the transition as the user swipes back
                if (controller?.isReady == true) {
                    controller?.currentFraction = backEvent.progress
                }
            }

            override fun handleOnBackPressed() {
                // Finish playing the transition when the user commits back
                controller?.animateToEnd()
                this.isEnabled = false
            }

            @RequiresApi(34)
            override fun handleOnBackCancelled() {
                // If the user cancels the back gesture, reset the state
                transition(ShowText.LONG)
            }
        }

        binding.shortText.setOnClickListener {
            transition(ShowText.LONG)
            callback.isEnabled = true
        }

        this.requireActivity().onBackPressedDispatcher.addCallback(callback)
    }

    private fun transition(showText: ShowText) {
        TransitionManager.beginDelayedTransition(
            binding.card,
            transitionSet
        )
        changeTextVisibility(showText)
    }

    enum class ShowText { SHORT, LONG }
    private fun changeTextVisibility(showText: ShowText) {
        when (showText) {
            ShowText.SHORT -> {
                binding.shortText.isVisible = true
                binding.longText.isVisible = false
            }
            ShowText.LONG -> {
                binding.shortText.isVisible = false
                binding.longText.isVisible = true
            }
        }
    }
}
  
<?xml version="1.0" encoding="utf-8"?>
...
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/card"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ...>

        <TextView
            android:id="@+id/short_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            ... />

        <TextView
            android:id="@+id/long_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"
            .../>

    </androidx.constraintlayout.widget.ConstraintLayout>

عند استخدام انتقالات إيماءة إظهار شاشة الرجوع، يُرجى مراعاة ما يلي:

  • استخدِم isSeekingSupported للتحقّق مما إذا كان الانتقال يتيح إيماءة إظهار شاشة الرجوع.
  • ألغِ isSeekingSupported لعرض القيمة "صحيح" لانتقالاتك المخصّصة.
  • أنشئ وحدة تحكّم واحدة لكل صورة متحركة.
  • تتوفّر انتقالات إيماءة إظهار شاشة الرجوع مع انتقالات AndroidX، ولكنها لا تتوفّر مع انتقالات إطار العمل. ننصحك بالانتقال من انتقالات إطار العمل واستخدام Animator وانتقالات AndroidX بدلاً منها.
  • تتوفّر انتقالات إيماءة إظهار شاشة الرجوع على الأجهزة التي تعمل بنظام التشغيل Android 14 والإصدارات الأحدث، ولا تتوافق مع الإصدارات السابقة.
  • تتوفّر أيضًا الانتقالات التي تم إنشاؤها باستخدام مشاهد XML. في handleOnBackStarted، اضبط TransitionSeekController على نتيجة TransitionManager.createSeekController بدلاً من نتيجة controlDelayedTransition.

موارد إضافية