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

يجب ألا يدخل تطبيقك في وضع PiP في الحالات التالية:

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

للتحكّم في وقت دخول تطبيقك في وضع "نافذة ضمن النافذة"، أضِف متغيّرًا يتتبّع حالة مشغّل الفيديو باستخدام 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. في دالة Lambda التي تحدّد السلوك عند تفعيل 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 لكي يدخل تطبيقك في وضع &quot;نافذة ضمن النافذة&quot; في الوقت المناسب فقط:

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 صورة متحركة أكثر سلاسة للدخول إلى وضع &quot;نافذة ضمن النافذة&quot;. في الإصدار 12 من Android والإصدارات الأحدث، تنشئ هذه الميزة أيضًا حركة أكثر سلاسة للخروج من وضع "نافذة ضمن النافذة". أضِف واجهة برمجة التطبيقات هذه إلى أداة إنشاء PiP للإشارة إلى منطقة النشاط التي تظهر بعد الانتقال إلى PiP.

  1. يجب إضافة setSourceRectHint() إلى builder فقط إذا كانت الحالة تحدّد أنّ التطبيق يجب أن يدخل في وضع "نافذة ضمن النافذة". يؤدي ذلك إلى تجنُّب احتساب sourceRect عندما لا يحتاج التطبيق إلى الدخول في وضع &quot;نافذة ضمن النافذة&quot;.
  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)