برنامه خود را برای PiP تنظیم کنید

در تگ activity فایل AndroidManifest.xml خود، موارد زیر را انجام دهید:

  1. برای اعلام اینکه از قابلیت تصویر در تصویر (PiP) در برنامه خود استفاده خواهید کرد، supportsPictureInPicture اضافه کنید و آن را روی true تنظیم کنید.
  2. configChanges اضافه کنید و آن را روی orientation|screenLayout|screenSize|smallestScreenSize تنظیم کنید تا مشخص شود که activity شما تغییرات پیکربندی طرح‌بندی را مدیریت می‌کند. به این ترتیب، activity شما هنگام تغییر طرح‌بندی در طول انتقال حالت PiP دوباره راه‌اندازی نمی‌شود.
<activity
    android:name=".SnippetsActivity"
    android:exported="true"
    android:supportsPictureInPicture="true"
    android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
    android:theme="@style/Theme.Snippets">

در کد Compose خود، موارد زیر را انجام دهید:

  1. این افزونه را به Context اضافه کنید. در طول این راهنما چندین بار از این افزونه برای دسترسی به فعالیت استفاده خواهید کرد.
    internal fun Context.findActivity(): ComponentActivity {
        var context = this
        while (context is ContextWrapper) {
            if (context is ComponentActivity) return context
            context = context.baseContext
        }
        throw IllegalStateException("Picture in picture should be called in the context of an Activity")
    }

برنامه PiP در حالت مرخصی برای اندرویدهای قبل از ۱۲ اضافه شد

برای افزودن PiP برای نسخه‌های قبل از اندروید ۱۲، از addOnUserLeaveHintProvider استفاده کنید. برای افزودن PiP برای نسخه‌های قبل از اندروید ۱۲، این مراحل را دنبال کنید:

  1. یک گیت نسخه اضافه کنید تا این کد فقط در نسخه‌های O تا R قابل دسترسی باشد.
  2. از یک DisposableEffect با Context به عنوان کلید استفاده کنید.
  3. درون DisposableEffect ، رفتاری را برای زمانی که onUserLeaveHintProvider با استفاده از یک لامبدا فعال می‌شود، تعریف کنید. در لامبدا، تابع enterPictureInPictureMode() روی findActivity() فراخوانی کنید و PictureInPictureParams.Builder().build() به آن منتقل کنید.
  4. با استفاده از findActivity() addOnUserLeaveHintListener اضافه کنید و لامبدا را به آن ارسال کنید.
  5. در onDispose ، با استفاده از findActivity() removeOnUserLeaveHintListener را اضافه کنید و لامبدا را به آن ارسال کنید.

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 {
            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")
}

برنامه PiP در حالت مرخصی را برای نسخه‌های پس از اندروید ۱۲ اضافه کنید

پس از اندروید ۱۲، PictureInPictureParams.Builder از طریق یک اصلاح‌کننده که به پخش‌کننده ویدیوی برنامه ارسال می‌شود، اضافه می‌شود.

  1. یک modifier ایجاد کنید و onGloballyPositioned روی آن فراخوانی کنید. مختصات طرح‌بندی در مرحله‌ی بعدی استفاده خواهد شد.
  2. یک متغیر برای PictureInPictureParams.Builder() ایجاد کنید.
  3. یک دستور if اضافه کنید تا بررسی کنید که آیا SDK نسخه S یا بالاتر است یا خیر. اگر چنین است، setAutoEnterEnabled به سازنده اضافه کنید و آن را روی true تنظیم کنید تا با کشیدن انگشت، حالت PiP وارد شود. این کار انیمیشن روان‌تری نسبت به enterPictureInPictureMode ارائه می‌دهد.
  4. از findActivity() برای فراخوانی setPictureInPictureParams() استفاده کنید. build() روی builder فراخوانی کنید و آن را ارسال کنید.

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

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

از setAspectRatio برای تنظیم نسبت ابعاد پنجره PiP استفاده کنید

برای تنظیم نسبت ابعاد پنجره PiP، می‌توانید یا یک نسبت ابعاد خاص را انتخاب کنید یا از عرض و ارتفاع اندازه ویدیوی پخش‌کننده استفاده کنید. اگر از پخش‌کننده media3 استفاده می‌کنید، قبل از تنظیم نسبت ابعاد، بررسی کنید که پخش‌کننده null نباشد و اندازه ویدیوی پخش‌کننده برابر با VideoSize.UNKNOWN نباشد.

val context = LocalContext.current

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()
    if (shouldEnterPipMode && player != null && player.videoSize != VideoSize.UNKNOWN) {
        val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()
        builder.setSourceRectHint(sourceRect)
        builder.setAspectRatio(
            Rational(player.videoSize.width, player.videoSize.height)
        )
    }

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

VideoPlayer(pipModifier)

اگر از یک پخش‌کننده‌ی سفارشی استفاده می‌کنید، نسبت ابعاد را روی ارتفاع و عرض پخش‌کننده با استفاده از سینتکس مخصوص پخش‌کننده‌ی خود تنظیم کنید. توجه داشته باشید که اگر پخش‌کننده‌ی شما در حین راه‌اندازی اولیه تغییر اندازه دهد، اگر خارج از محدوده‌ی معتبر نسبت ابعاد قرار گیرد، برنامه‌ی شما از کار می‌افتد. ممکن است لازم باشد بررسی‌هایی را در مورد زمان محاسبه‌ی نسبت ابعاد انجام دهید، مشابه نحوه‌ی انجام این کار برای پخش‌کننده‌ی media3.