Android 8.0 (API düzeyi 26) sürümünden itibaren Android, etkinliklerin pencere içinde pencere (PIP) modunda başlatılmasına izin verir. PiP, çoğunlukla video oynatmak için kullanılan özel bir çok pencere modudur. Kullanıcıların uygulamalar arasında geçiş yaparken veya ana ekrandaki içeriklere göz atarken ekranın bir köşesine sabitlenmiş küçük bir pencerede video izlemesine olanak tanır.
PiP, sabitlenmiş video yer paylaşımı penceresini sağlamak için Android 7.0'da kullanıma sunulan çok pencereli API'lerden yararlanır. Uygulamanıza PiP eklemek için PiP'yi destekleyen etkinliklerinizi kaydetmeniz, etkinliğinizi gerektiğinde PiP moduna geçirmeniz ve etkinlik PiP modundayken kullanıcı arayüzü öğelerinin gizlendiğinden ve video oynatmanın devam ettiğinden emin olmanız gerekir.
PiP penceresi, ekranın en üst katmanında, sistem tarafından seçilen bir köşede görünür.
PiP, Android 14 (API düzeyi 34) veya sonraki sürümleri çalıştıran uyumlu Android TV OS cihazlarda da desteklenir. İkisi arasında birçok benzerlik olsa da TV'de PiP'yi kullanırken dikkate alınması gereken başka noktalar da vardır.
Kullanıcılar PiP penceresiyle nasıl etkileşim kurabilir?
Kullanıcılar PiP penceresini başka bir yere sürükleyebilir. Android 12'den itibaren kullanıcılar şunları da yapabilir:
Tam ekran açma/kapatma düğmesi, kapat düğmesi, ayarlar düğmesi ve uygulamanızın sağladığı özel işlemleri (örneğin, oynatma kontrolleri) görüntülemek için pencereye bir kez dokunun.
Mevcut PiP boyutu ile maksimum veya minimum PiP boyutu arasında geçiş yapmak için pencereye iki kez dokunun. Örneğin, ekranı kaplayacak şekilde büyütülmüş bir pencereye iki kez dokunduğunuzda pencere simge durumuna küçültülür. Bunun tersi de geçerlidir.
Pencereyi sol veya sağ kenara sürükleyerek güvenceye alın. Pencereyi gizleme modundan çıkarmak için gizlenen pencerenin görünür kısmına dokunun veya pencereyi dışarı sürükleyin.
İki parmağınızla yakınlaştırıp uzaklaştırarak PiP penceresini yeniden boyutlandırın.
Mevcut etkinliğin PiP moduna ne zaman gireceğini uygulamanız kontrol eder. Aşağıda bazı örnekler verilmiştir:
Kullanıcı ana sayfa düğmesine dokunduğunda veya ana sayfaya doğru kaydırdığında etkinlik PiP moduna girebilir. Kullanıcı aynı anda başka bir etkinlik yürütürken Google Haritalar bu şekilde yol tarifini göstermeye devam eder.
Kullanıcı videodan geri dönüp diğer içeriklere göz atarken uygulamanız videoyu PiP moduna geçirebilir.
Kullanıcı, içeriğin sonunu izlerken uygulamanız videoyu PiP moduna geçirebilir. Ana ekranda, serinin bir sonraki bölümüyle ilgili tanıtım amaçlı veya özet bilgiler görüntülenir.
Uygulamanız, kullanıcıların video izlerken ek içerikleri sıraya almaları için bir yöntem sunabilir. Ana ekranda içerik seçimi etkinliği gösterilirken video PiP modunda oynatılmaya devam eder.
PIP desteğini bildirme
Sistem, varsayılan olarak uygulamalar için PiP'yi otomatik olarak desteklemez. Uygulamanızda PiP'yi desteklemek istiyorsanız android:supportsPictureInPicture
değerini true
olarak ayarlayarak video etkinliğinizi manifest dosyanıza kaydedin. Ayrıca, PiP modu geçişlerinde düzen değişiklikleri olduğunda etkinliğinizin yeniden başlatılmaması için etkinliğinizin düzen yapılandırması değişikliklerini işlediğini belirtin.
<activity android:name="VideoActivity"
android:supportsPictureInPicture="true"
android:configChanges=
"screenSize|smallestScreenSize|screenLayout|orientation"
...
Etkinliğinizi PIP'e geçirme
Android 12'den itibaren setAutoEnterEnabled
işaretini true
olarak ayarlayarak etkinliğinizi PiP moduna geçirebilirsiniz. Bu ayar sayesinde, bir etkinlik onUserLeaveHint
içinde enterPictureInPictureMode()
çağrılmasına gerek kalmadan gerektiğinde otomatik olarak PiP moduna geçer. Bu, çok daha sorunsuz geçişler sağlamanın ek avantajını da sunar. Ayrıntılar için Hareketle gezinme sırasında PiP moduna geçişleri daha sorunsuz hale getirme başlıklı makaleyi inceleyin.
Android 11 veya önceki sürümleri hedefliyorsanız bir etkinliğin PiP moduna geçmek için enterPictureInPictureMode()
çağrısı yapması gerekir. Örneğin, aşağıdaki kod, kullanıcı uygulamanın kullanıcı arayüzünde özel bir düğmeyi tıkladığında bir etkinliği PiP moduna geçirir:
Kotlin
override fun onActionClicked(action: Action) { if (action.id.toInt() == R.id.lb_control_picture_in_picture) { activity?.enterPictureInPictureMode() return } }
Java
@Override public void onActionClicked(Action action) { if (action.getId() == R.id.lb_control_picture_in_picture) { getActivity().enterPictureInPictureMode(); return; } ... }
Bir etkinliği arka plana taşımak yerine PiP moduna geçiren mantık ekleyebilirsiniz. Örneğin, Google Haritalar uygulamada gezinme sırasında kullanıcı ana sayfa veya son aramalar düğmesine basarsa PIP moduna geçer. onUserLeaveHint()
değerini geçersiz kılarak bu destek kaydını yakalayabilirsiniz:
Kotlin
override fun onUserLeaveHint() { if (iWantToBeInPipModeNow()) { enterPictureInPictureMode() } }
Java
@Override public void onUserLeaveHint () { if (iWantToBeInPipModeNow()) { enterPictureInPictureMode(); } }
Önerilen: Kullanıcılara kusursuz bir PiP geçiş deneyimi sunun
Android 12, tam ekran ve PiP pencereleri arasındaki animasyonlu geçişlerde önemli görsel iyileştirmeler yaptı. Geçerli tüm değişiklikleri uygulamanızı önemle tavsiye ederiz. Bu değişiklikleri yaptıktan sonra, başka bir işlem yapmanıza gerek kalmadan katlanabilir cihazlar ve tabletler gibi büyük ekranlara otomatik olarak ölçeklendirilir.
Uygulamanız geçerli güncellemeleri içermiyorsa PIP geçişleri çalışmaya devam eder ancak animasyonlar daha az cilalıdır. Örneğin, tam ekrandan PiP moduna geçiş yaparken PiP penceresi geçiş sırasında kaybolabilir ve geçiş tamamlandığında yeniden görünür.
Bu değişiklikler şunlardır:
- Hareketle gezinmeden PiP moduna daha kolay geçiş yapma
- PiP moduna girmek ve bu moddan çıkmak için uygun bir
sourceRectHint
ayarlanıyor - Video olmayan içerik için sorunsuz yeniden boyutlandırmayı devre dışı bırakma
Sorunsuz bir geçiş deneyimi sunmak için referans olarak Android Kotlin PictureInPicture örneğine bakın.
Hareketle gezinme modundan PIP moduna geçişleri daha sorunsuz hale getirme
Android 12'den itibaren setAutoEnterEnabled
işaretçisi, hareketle gezinme özelliğini kullanarak PiP modunda video içeriğine geçiş için çok daha akıcı animasyonlar sağlar (ör. tam ekrandan ana sayfaya kaydırırken).
Bu değişikliği yapmak için aşağıdaki adımları uygulayın ve referans olarak bu örneği inceleyin:
PictureInPictureParams.Builder
oluşturmak içinsetAutoEnterEnabled
kullanın:Kotlin
setPictureInPictureParams(PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .setSourceRectHint(sourceRectHint) .setAutoEnterEnabled(true) .build())
Java
setPictureInPictureParams(new PictureInPictureParams.Builder() .setAspectRatio(aspectRatio) .setSourceRectHint(sourceRectHint) .setAutoEnterEnabled(true) .build());
setPictureInPictureParams
numaralı telefonu, güncel bilgi içinPictureInPictureParams
erkenden arayın. Uygulama,onUserLeaveHint
geri çağırma işlevini beklemez (Android 11'de beklediği gibi).Örneğin, en boy oranı değişirse ilk oynatmada ve sonraki oynatmada
setPictureInPictureParams
yöntemini çağırmak isteyebilirsiniz.setAutoEnterEnabled(false)
'ü yalnızca gerektiğinde arayın. Örneğin, mevcut oynatma duraklatılmış durumdaysa büyük olasılıkla PiP moduna girmek istemezsiniz.
PiP moduna girmek ve bu moddan çıkmak için uygun bir sourceRectHint
belirleyin
Android 8.0'da PiP'nin kullanıma sunulmasından itibaren setSourceRectHint
, etkinliğin pencere içinde pencere moduna geçişten sonra görünen alanını (ör. bir video oynatıcıdaki video görüntüleme sınırları) belirtiyordu.
Android 12'de sistem, hem PiP moduna girerken hem de bu moddan çıkarken çok daha akıcı bir animasyon uygulamak için sourceRectHint
kullanır.
PiP moduna girmek ve moddan çıkmak için sourceRectHint
'ü doğru şekilde ayarlamak üzere:
sourceRectHint
olarak uygun sınırları kullanarakPictureInPictureParams
oluşturun. Video oynatıcıya bir düzen değişikliği dinleyicisi de eklemenizi öneririz:Kotlin
val mOnLayoutChangeListener = OnLayoutChangeListener { v: View?, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int, newLeft: Int, newTop: Int, newRight: Int, newBottom: Int -> val sourceRectHint = Rect() mYourVideoView.getGlobalVisibleRect(sourceRectHint) val builder = PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint) setPictureInPictureParams(builder.build()) } mYourVideoView.addOnLayoutChangeListener(mOnLayoutChangeListener)
Java
private final View.OnLayoutChangeListener mOnLayoutChangeListener = (v, oldLeft, oldTop, oldRight, oldBottom, newLeft, newTop, newRight, newBottom) -> { final Rect sourceRectHint = new Rect(); mYourVideoView.getGlobalVisibleRect(sourceRectHint); final PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint); setPictureInPictureParams(builder.build()); }; mYourVideoView.addOnLayoutChangeListener(mOnLayoutChangeListener);
Gerekirse sistem çıkış geçişini başlatmadan önce
sourceRectHint
öğesini güncelleyin. Sistem PiP modundan çıkmak üzereyken etkinliğin görüntü hiyerarşisi hedef yapılandırmasına (ör. tam ekran) göre düzenlenir. Uygulama, etkinliği algılamak için kök görünümüne veya hedef görünümüne (video oynatıcı görünümü gibi) bir düzen değişikliği işleyici ekleyebilir ve animasyon başlamadan öncesourceRectHint
öğesini güncelleyebilir.Kotlin
// Listener is called immediately after the user exits PiP but before animating. playerView.addOnLayoutChangeListener { _, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom -> if (left != oldLeft || right != oldRight || top != oldTop || bottom != oldBottom) { // The playerView's bounds changed, update the source hint rect to // reflect its new bounds. val sourceRectHint = Rect() playerView.getGlobalVisibleRect(sourceRectHint) setPictureInPictureParams( PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint) .build() ) } }
Java
// Listener is called right after the user exits PiP but before animating. playerView.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { if (left != oldLeft || right != oldRight || top != oldTop || bottom != oldBottom) { // The playerView's bounds changed, update the source hint rect to // reflect its new bounds. final Rect sourceRectHint = new Rect(); playerView.getGlobalVisibleRect(sourceRectHint); setPictureInPictureParams( new PictureInPictureParams.Builder() .setSourceRectHint(sourceRectHint) .build()); } });
Video olmayan içerikler için sorunsuz yeniden boyutlandırmayı devre dışı bırakma
Android 12'de, PiP penceresindeki video dışı içerikler yeniden boyutlandırıldığında çok daha yumuşak bir geçiş animasyonu sağlayan setSeamlessResizeEnabled
işareti eklendi. Önceden, video olmayan içeriği bir PiP penceresinde yeniden boyutlandırmak, rahatsız edici görsel yapılar oluşturabiliyordu.
Video olmayan içeriklerde sorunsuz yeniden boyutlandırmayı devre dışı bırakmak için:
Kotlin
setPictureInPictureParams(PictureInPictureParams.Builder() .setSeamlessResizeEnabled(false) .build())
Java
setPictureInPictureParams(new PictureInPictureParams.Builder() .setSeamlessResizeEnabled(false) .build());
PiP sırasında kullanıcı arayüzünü işleme
Etkinlik, Pencere İçinde Pencere (PIP) moduna girdiğinde veya bu moddan çıktığında sistem, Activity.onPictureInPictureModeChanged()
veya Fragment.onPictureInPictureModeChanged()
yöntemini çağırır.
Android 15, PiP moduna geçerken daha da sorunsuz bir geçiş sağlayan değişiklikler sunar. Bu, PiP'e giren ana kullanıcı arayüzünün üzerine yerleştirilmiş kullanıcı arayüzü öğeleri olan uygulamalar için faydalıdır.
Geliştiriciler, üste binen kullanıcı arayüzü öğelerinin görünürlüğünü değiştiren mantığı tanımlamak için onPictureInPictureModeChanged()
geri çağırma işlevini kullanır.
Bu geri çağırma işlevi, PiP'ye girme veya çıkma animasyonu tamamlandığında tetiklenir.
Android 15'ten itibaren PictureInPictureUiState
sınıfı yeni bir durum içeriyor.
Bu yeni kullanıcı arayüzü durumunda, Android 15'i hedefleyen uygulamalar, PiP animasyonu başlar başlamaz Activity#onPictureInPictureUiStateChanged()
geri çağırma işlevinin isTransitioningToPip()
ile çağrıldığını gözlemler.
PiP modundayken uygulamayla alakalı olmayan birçok kullanıcı arayüzü öğesi vardır. Örneğin, öneriler, yaklaşan video, derecelendirmeler ve başlıklar gibi bilgileri içeren görünümler veya düzenler. Uygulama PiP moduna geçtiğinde bu kullanıcı arayüzü öğelerini gizlemek için onPictureInPictureUiStateChanged()
geri çağırma yöntemini kullanın. Uygulama PiP penceresinden tam ekran moduna geçtiğinde, bu öğeleri göstermek için aşağıdaki örneklerde gösterildiği gibi onPictureInPictureModeChanged()
geri çağırma yöntemini kullanın:
Kotlin
override fun onPictureInPictureUiStateChanged(pipState: PictureInPictureUiState) { if (pipState.isTransitioningToPip()) { // Hide UI elements. } }
Java
@Override public void onPictureInPictureUiStateChanged(PictureInPictureUiState pipState) { if (pipState.isTransitioningToPip()) { // Hide UI elements. } }
Kotlin
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) { if (isInPictureInPictureMode) { // Unhide UI elements. } }
Java
@Override public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) { if (isInPictureInPictureMode) { // Unhide UI elements. } }
Alakasız kullanıcı arayüzü öğelerinin (PiP penceresi için) bu hızlı görünürlük açma/kapatma özelliği, PiP giriş animasyonunun daha akıcı ve titreşimsiz olmasını sağlar.
Etkinliğin kullanıcı arayüzü öğelerini yeniden çizmek için bu geri çağırma işlevlerini geçersiz kılın. PiP modunda etkinliğinizin küçük bir pencerede gösterildiğini unutmayın. Uygulama PiP modundayken kullanıcılar uygulamanızın kullanıcı arayüzü öğeleriyle etkileşimde bulunamaz ve küçük kullanıcı arayüzü öğelerinin ayrıntılarını görmek zor olabilir. En iyi kullanıcı deneyimini, minimal kullanıcı arayüzüne sahip video oynatma etkinlikleri sağlar.
Uygulamanızın PiP için özel işlemler sağlaması gerekiyorsa bu sayfadaki Denetimler ekleme bölümüne bakın. Etkinliğiniz PiP'ye girmeden önce diğer kullanıcı arayüzü öğelerini kaldırın ve etkinliğiniz tekrar tam ekran olduğunda bunları geri yükleyin.
Kontrol ekle
PiP penceresi, kullanıcı pencerenin menüsünü açtığında (mobil cihazda pencereye dokunarak veya TV uzaktan kumandasından menüyü seçerek) kontrolleri gösterebilir.
Bir uygulamada etkin medya oturumu varsa oynatma, duraklatma, sonraki ve önceki kontroller görünür.
Ayrıca, PiP moduna girmeden önce PictureInPictureParams.Builder.setActions()
ile PictureInPictureParams
derleyerek de özel işlemleri açıkça belirtebilirsiniz. enterPictureInPictureMode(android.app.PictureInPictureParams)
veya setPictureInPictureParams(android.app.PictureInPictureParams)
kullanarak PiP moduna girdiğinizde parametreleri iletebilirsiniz.
Dikkatli olun. getMaxNumPictureInPictureActions()
değerinden daha fazla ekleme yapmaya çalışırsanız yalnızca maksimum sayıyı alırsınız.
PiP modundayken video oynatmaya devam etme
Etkinliğiniz PiP'ye geçtiğinde sistem, etkinliği duraklatılmış duruma yerleştirir ve etkinliğin onPause()
yöntemini çağırır. Video oynatma duraklatılmamalıdır. PiP moduna geçilirken etkinlik duraklatılırsa video oynatmaya devam edin.
Android 7.0 ve sonraki sürümlerde, sistem etkinliğinizin onStop()
ve onStart()
yöntemlerini çağrdığında video oynatmayı duraklatıp devam ettirmeniz gerekir. Bunu yaparak, uygulamanızın onPause()
'te PiP modunda olup olmadığını kontrol etmek ve oynatmaya açıkça devam etmek zorunda kalmazsınız.
setAutoEnterEnabled
işaretini true
olarak ayarlamadıysanız ve onPause()
uygulamanızda oynatmayı duraklatmanız gerekiyorsa, isInPictureInPictureMode()
yöntemini çağırarak PiP modunu kontrol edin ve oynatma işlemini uygun şekilde gerçekleştirin. Örnek:
Kotlin
override fun onPause() { super.onPause() // If called while in PiP mode, do not pause playback. if (isInPictureInPictureMode) { // Continue playback. } else { // Use existing playback logic for paused activity behavior. } }
Java
@Override public void onPause() { // If called while in PiP mode, do not pause playback. if (isInPictureInPictureMode()) { // Continue playback. ... } else { // Use existing playback logic for paused activity behavior. ... } }
Etkinliğiniz PiP modundan tam ekran moduna geri döndüğünde sistem etkinliğinizi devam ettirir ve onResume()
yönteminizi çağırır.
PiP için tek bir oynatma etkinliği kullanma
Uygulamanızda, bir video oynatma etkinliği PiP modundayken kullanıcı ana ekranda içeriklere göz atarken yeni bir video seçebilir. Kullanıcının kafasını karıştırabilecek yeni bir etkinlik başlatmak yerine, yeni videoyu mevcut oynatma etkinliğinde tam ekran modunda oynatın.
Video oynatma istekleri için tek bir etkinliğin kullanılmasını ve gerektiğinde PiP moduna girip çıkmasını sağlamak üzere manifest dosyanızda etkinliğin android:launchMode
değerini singleTask
olarak ayarlayın:
<activity android:name="VideoActivity"
...
android:supportsPictureInPicture="true"
android:launchMode="singleTask"
...
Etkinliğinizde onNewIntent()
değerini geçersiz kılın ve gerekirse mevcut video oynatmayı durdurarak yeni videoyu işleyin.
En iyi uygulamalar
PiP, RAM'i düşük olan cihazlarda devre dışı bırakılabilir. Uygulamanız PiP'yi kullanmadan önce hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
çağrısını yaparak bu özelliğin kullanılabilir olup olmadığını kontrol edin.
PiP, tam ekran video oynatan etkinlikler için tasarlanmıştır. Etkinliğinizi PiP moduna geçirirken video içeriği dışında bir şey göstermeyin. Etkinliğinizin PiP moduna ne zaman girdiğini izleyin ve PiP sırasında kullanıcı arayüzünü yönetme bölümünde açıklandığı gibi kullanıcı arayüzü öğelerini gizleyin.
Bir etkinlik PiP modundayken varsayılan olarak giriş odağına alınmaz. PIP modundayken giriş etkinlikleri almak için MediaSession.setCallback()
simgesini kullanın.
setCallback()
simgesini kullanma hakkında daha fazla bilgi için Ne çalıyor kartı görüntüleme başlıklı makaleyi inceleyin.
Uygulamanız PiP modundayken PiP penceresinde video oynatma, müzik çalar uygulaması veya sesli arama uygulaması gibi başka bir uygulamayla ses parazitine neden olabilir. Bu durumu önlemek için videoyu oynatmaya başladığınızda ses odağını isteyin ve Ses Odaklılığını Yönetme bölümünde açıklandığı şekilde ses odağı değişikliği bildirimlerini işleme alın. PiP modundayken ses odağının kaybolduğuna dair bildirim alırsanız video oynatmayı duraklatın veya durdurun.
Uygulamanız PiP'ye girmek üzereyken yalnızca en üstteki etkinliğin PiP'ye girdiğini unutmayın. Çok pencereli cihazlar gibi bazı durumlarda, aşağıdaki etkinliğin artık PiP etkinliğiyle birlikte gösterilmesi ve tekrar görünür hale gelmesi mümkündür. Aşağıdaki onResume()
veya onPause()
geri çağırma etkinliği de dahil olmak üzere bu destek kaydını uygun şekilde ele almanız gerekir. Kullanıcının etkinlikle etkileşime geçmesi de mümkündür. Örneğin, PiP modunda gösterilen bir video listesi etkinliğiniz ve video oynatma etkinliğiniz varsa kullanıcı listeden yeni bir video seçebilir. PiP etkinliği buna göre güncellenir.
Ek örnek kod
Kotlin ile yazılmış örnek bir uygulamayı indirmek için Android PictureInPicture Sample (Kotlin) sayfasına göz atın.