تشغيل وضع "صورة في صورة" في الأوقات الصحيحة

يجب ألا يدخل تطبيقك وضع "نافذة ضمن النافذة" في الحالات التالية:

  • إذا تم إيقاف الفيديو أو إيقافه مؤقتًا
  • إذا كنت في صفحة مختلفة من التطبيق غير مشغّل الفيديو

للتحكّم في وقت دخول تطبيقك وضع "نافذة ضمن النافذة"، أضِف متغيّرًا يتتبّع حالة مشغّل الفيديو باستخدام mutableStateOf.

تبديل الحالة استنادًا إلى ما إذا كان الفيديو قيد التشغيل

لتبديل الحالة استنادًا إلى ما إذا كان مشغّل الفيديو قيد التشغيل، أضِف مستمعًا على مشغّل الفيديو. بدِّل حالة متغيّر الحالة استنادًا إلى ما إذا كان المشغّل قيد التشغيل أم لا:

player.addListener(object : Player.Listener {
    override fun onIsPlayingChanged(isPlaying: Boolean) {
        shouldEnterPipMode = isPlaying
    }
})

تبديل الحالة استنادًا إلى ما إذا تم إيقاف المشغّل

عند إيقاف المشغّل، اضبط متغيّر الحالة على false:

fun releasePlayer() {
    shouldEnterPipMode = false
}

استخدام الحالة لتحديد ما إذا تم الدخول إلى وضع "نافذة ضمن النافذة" (الإصدارات السابقة لإصدار Android 12)

  1. بما أنّ إضافة وضع "نافذة ضمن النافذة" في الإصدارات السابقة لإصدار Android 12 تستخدم DisposableEffect، عليك إنشاء متغيّر جديد باستخدام rememberUpdatedState مع ضبط newValue على متغيّر الحالة. سيضمن ذلك استخدام الإصدار المعدَّل ضمن DisposableEffect.
  2. في دالة لامدا التي تحدّد السلوك عند تفعيل OnUserLeaveHintListener، أضِف عبارة if مع متغيّر الحالة حول طلب enterPictureInPictureMode():

    val currentShouldEnterPipMode by rememberUpdatedState(newValue = shouldEnterPipMode)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
        Build.VERSION.SDK_INT < Build.VERSION_CODES.S
    ) {
        val context = LocalContext.current
        DisposableEffect(context) {
            val onUserLeaveBehavior = Runnable {
                if (currentShouldEnterPipMode) {
                    context.findActivity()
                        .enterPictureInPictureMode(PictureInPictureParams.Builder().build())
                }
            }
            context.findActivity().addOnUserLeaveHintListener(
                onUserLeaveBehavior
            )
            onDispose {
                context.findActivity().removeOnUserLeaveHintListener(
                    onUserLeaveBehavior
                )
            }
        }
    } else {
        Log.i("PiP info", "API does not support PiP")
    }

استخدام الحالة لتحديد ما إذا تم الدخول إلى وضع "نافذة ضمن النافذة" (الإصدارات اللاحقة لإصدار Android 12)

مرِّر متغيّر الحالة إلى setAutoEnterEnabled لكي يدخل تطبيقك وضع "نافذة ضمن النافذة" في الوقت المناسب فقط:

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()

    // Add autoEnterEnabled for versions S and up
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)

استخدام setSourceRectHint للحصول على صورة متحركة سلسة

تنشئ واجهة برمجة التطبيقات setSourceRectHint صورة متحركة أكثر سلاسة للدخول إلى وضع "نافذة ضمن النافذة" . في Android 12 والإصدارات الأحدث، تنشئ أيضًا صورة متحركة أكثر سلاسة للخروج من وضع "نافذة ضمن النافذة". أضِف واجهة برمجة التطبيقات هذه إلى أداة إنشاء وضع "نافذة ضمن النافذة" للإشارة إلى مساحة النشاط المرئية بعد الانتقال إلى وضع "نافذة ضمن النافذة".

  1. أضِف setSourceRectHint() إلى builder فقط إذا كانت الحالة تحدّد أنّه يجب أن يدخل التطبيق وضع "نافذة ضمن النافذة". يؤدي ذلك إلى تجنُّب احتساب sourceRect عندما لا يحتاج التطبيق إلى الدخول إلى وضع "نافذة ضمن النافذة".
  2. لضبط قيمة sourceRect، استخدِم layoutCoordinates التي يتم الحصول عليها من الدالة onGloballyPositioned في المعدِّل.
  3. استدعِ setSourceRectHint() على builder ومرِّر متغيّر sourceRect.

val context = LocalContext.current

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()
    if (shouldEnterPipMode) {
        val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()
        builder.setSourceRectHint(sourceRect)
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)