Etkinlik yerleştirme, bir uygulamanın görev penceresini iki etkinlik veya aynı etkinliğin iki örneği arasında bölerek büyük ekranlı cihazlardaki uygulamaları optimize eder.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/settings_app.png?authuser=0&hl=tr)
Uygulamanız birden fazla etkinlikten oluşuyorsa etkinlik yerleştirme, tabletler, katlanabilir cihazlar ve ChromeOS cihazlarda gelişmiş bir kullanıcı deneyimi sunmanıza olanak tanır.
Etkinlik yerleştirme için kod yeniden düzenlemesi gerekmez. Bir XML yapılandırma dosyası oluşturarak veya Jetpack WindowManager API çağrıları yaparak uygulamanızın etkinliklerini nasıl (yan yana veya yığılmış olarak) göstereceğini siz belirlersiniz.
Küçük ekranlar için destek otomatik olarak sağlanır. Uygulamanız küçük ekranlı bir cihazda olduğunda etkinlikler birbirinin üzerine yığılır. Büyük ekranlarda etkinlikler yan yana gösterilir. Sistem, sunumu oluşturduğunuz yapılandırmaya göre belirler. Dallanma mantığı gerekmez.
Etkinlik yerleştirme, cihaz yön değişikliklerini karşılar ve katlanabilir cihazlarda sorunsuz bir şekilde çalışır. Cihaz katlandığında ve açıldığında etkinlikleri yığınlar ve yığınları dağıtır.
Etkinlik yerleştirme, Android 12L (API düzeyi 32) ve sonraki sürümleri çalıştıran büyük ekranlı cihazların çoğunda desteklenir.
Görev penceresini bölme
Etkinlik yerleştirme, uygulama görev penceresini birincil ve ikincil olmak üzere iki kapsayıcıya böler. Kapsayıcılarda, ana etkinlikten veya kapsayıcılarda bulunan diğer etkinliklerden başlatılan etkinlikler bulunur.
Etkinlikler, başlatıldıkları sırada ikincil kapsayıcıya yığılır ve küçük ekranlarda ikincil kapsayıcı birincil kapsayıcının üzerine yığılır. Bu nedenle, etkinlik yığma ve geri gezinme, uygulamanızda zaten yerleşik olan etkinliklerin sıralamasıyla tutarlıdır.
Etkinlik yerleştirme, etkinlikleri çeşitli şekillerde görüntülemenize olanak tanır. Uygulamanız, iki etkinliği aynı anda yan yana başlatarak görev penceresini bölebilir:
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/a_b.png?authuser=0&hl=tr)
Görev penceresinin tamamını kaplayan bir etkinlik, yanında yeni bir etkinlik başlatarak da bölme oluşturabilir:
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/a_to_a_b.png?authuser=0&hl=tr)
Halihazırda bölünmüş durumda olan ve görev penceresi paylaşan etkinlikler, diğer etkinlikleri aşağıdaki yöntemlerle başlatabilir:
Diğer bir etkinliğin üstünde, yan tarafta:
Şekil 4. A etkinliği, B etkinliğinin yanında C etkinliğini başlatır. Önceki birincil etkinliği gizlemek için bölünmüş ekranı yana kaydırın:
Şekil 5. B etkinliği, C etkinliğini yan tarafta başlatır ve bölünmüş ekranı yana doğru kaydırır. Üstte, yani aynı etkinlik yığınında bir etkinlik başlatın:
Şekil 6. B etkinliği, ek intent işaretleri olmadan C etkinliğini başlatır. Aynı görevde etkinlik tam penceresi başlatın:
Şekil 7. A veya B etkinliği, görev penceresini dolduran C etkinliğini başlatır.
Geri gezinme
Farklı uygulama türleri, bölünmüş görev penceresi durumunda etkinlikler arasındaki bağımlılıklara veya kullanıcıların geri etkinliğini nasıl tetiklediğine bağlı olarak farklı geri gezinme kurallarına sahip olabilir. Örneğin:
- Birlikte gitme: Etkinlikler birbiriyle ilişkiliyse ve biri diğeri olmadan gösterilmemeliyse geri gezinme, her ikisini de tamamlayacak şekilde yapılandırılabilir.
- Tek başına hareket etme: Etkinlikler tamamen bağımsızsa bir etkinlikte geri gezinme, görev penceresindeki başka bir etkinliğin durumunu etkilemez.
Düğme gezinme kullanılırken geri etkinliği, odaklanılan son etkinliğe gönderilir.
Hareket tabanlı gezinme için:
Android 14 (API düzeyi 34) ve önceki sürümler: Geri etkinliği, hareketin gerçekleştiği etkinliğe gönderilir. Kullanıcılar ekranın sol tarafından kaydırdığında geri etkinliği, bölünmüş pencerenin sol bölmesinde bulunan etkinliğe gönderilir. Kullanıcılar ekranın sağ tarafından kaydırdığında geri etkinliği sağdaki bölmede etkinliğe gönderilir.
Android 15 (API düzeyi 35) ve sonraki sürümler
Aynı uygulamadaki birden fazla etkinlikle uğraşırken hareket, kaydırma yönünden bağımsız olarak en üstteki etkinliği sonlandırır ve daha birleşik bir deneyim sunar.
Farklı uygulamalardan iki etkinliğin (yer paylaşımı) yer aldığı senaryolarda geri etkinliği, düğme gezinmesinin davranışıyla uyumlu olacak şekilde odaktaki son etkinliğe yönlendirilir.
Çok bölmeli düzen
Jetpack WindowManager, Android 12L (API düzeyi 32) veya sonraki sürümleri çalıştıran büyük ekranlı cihazlarda ve daha eski platform sürümlerini çalıştıran bazı cihazlarda çok bölmeli düzeni yerleştiren bir etkinlik oluşturmanıza olanak tanır. SlidingPaneLayout
gibi fragmentler veya görünüm tabanlı düzenler yerine birden fazla etkinliğe dayanan mevcut uygulamalar, kaynak kodunu yeniden düzenlemeden daha iyi bir büyük ekran kullanıcı deneyimi sağlayabilir.
Liste-ayrıntı bölme işlemi buna örnek verilebilir. Yüksek kaliteli bir sunum sağlamak için sistem liste etkinliğini başlatır, ardından uygulama hemen ayrıntı etkinliğini başlatır. Geçiş sistemi, her iki etkinlik de çizilene kadar bekler ve ardından bunları birlikte gösterir. Kullanıcı için bu iki etkinlik tek bir etkinlik olarak başlatılır.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/launcher_to_list-detail.png?authuser=0&hl=tr)
Bölünmüş özellikler
Görev penceresinin bölünmüş kapsayıcılar arasında nasıl oranlandığını ve kapsayıcıların birbirine göre nasıl düzenlendiğini belirtebilirsiniz.
XML yapılandırma dosyasında tanımlanan kurallar için aşağıdaki özellikleri ayarlayın:
splitRatio
: Kapsayıcı oranlarını ayarlar. Değer, açık aralıktaki (0,0; 1,0) bir kayan nokta sayısıdır.splitLayoutDirection
: Bölünmüş kapsayıcıların birbirine göre nasıl yerleştirileceğini belirtir. Değerler şunlardır:ltr
: Soldan sağartl
: Sağdan solalocale
: Yerel ayardanltr
veyartl
belirlenir
Örnekler için XML yapılandırması bölümüne bakın.
WindowManager API'leri kullanılarak oluşturulan kurallar için SplitAttributes.Builder
ile bir SplitAttributes
nesnesi oluşturun ve aşağıdaki oluşturucu yöntemlerini çağırın:
setSplitType()
: Bölünmüş kapsayıcıların oranlarını ayarlar.SplitAttributes.SplitType.ratio()
yöntemi dahil olmak üzere geçerli bağımsız değişkenler içinSplitAttributes.SplitType
bölümüne bakın.setLayoutDirection()
: Kapsayıcıların düzenini ayarlar. Olası değerler içinSplitAttributes.LayoutDirection
bölümüne bakın.
Örnekler için WindowManager API bölümüne bakın.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/a_b_vs_a_b.png?authuser=0&hl=tr)
Yer tutucular
Yer tutucu etkinlikler, etkinlik bölme alanında yer kaplayan boş ikincil etkinliklerdir. Amaç, bu etkinlikleri içerik barındıran başka bir etkinlikle değiştirmek. Örneğin, bir yer tutucu etkinlik, listeden bir öğe seçilene kadar liste-ayrıntı düzeninde bölünmüş bir etkinliğin ikincil tarafını işgal edebilir. Bu noktada, seçilen liste öğesinin ayrıntı bilgilerini içeren bir etkinlik yer tutucunun yerini alır.
Varsayılan olarak sistem, yer tutucuları yalnızca etkinlik bölme işlemi için yeterli alan olduğunda gösterir. Ekran boyutu, bölünmüş ekranı görüntülemek için çok küçük bir genişlik veya yüksekliğe değiştiğinde yer tutucular otomatik olarak sonlandırılır. Yer varsa sistem, yer tutucuyu yeniden başlatılmış bir durumda yeniden başlatır.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/placeholder_finished_recreated.png?authuser=0&hl=tr)
Ancak SplitPlaceholder.Builder
öğesinin SplitPlaceholderRule
veya setSticky()
yönteminin stickyPlaceholder
özelliği varsayılan davranışı geçersiz kılabilir. Özellik veya yöntem true
değerini belirttiğinde sistem, ekran iki bölmeli ekrandan tek bölmeli ekrana yeniden boyutlandırıldığında yer tutucuyu görev penceresindeki en üst etkinlik olarak gösterir (örnek için Bölünmüş yapılandırma bölümüne bakın).
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/placeholder_sticky.png?authuser=0&hl=tr)
Pencere boyutu değişiklikleri
Cihaz yapılandırması değişiklikleri, görev penceresi genişliğini çok bölmeli bir düzen için yeterince büyük olmayacak şekilde azalttığında (örneğin, büyük ekranlı katlanabilir bir cihaz tablet boyutundan telefon boyutuna katlandığında veya uygulama penceresi çok pencereli modda yeniden boyutlandırıldığında), görev penceresinin ikincil bölmesinde yer tutucu olmayan etkinlikler birincil bölmede yer alan etkinliklerin üzerine yığılır.
Yer tutucu etkinlikler yalnızca bölme için yeterli ekran genişliği olduğunda gösterilir. Küçük ekranlarda yer tutucu otomatik olarak kapatılır. Görüntüleme alanı tekrar yeterince büyük olduğunda yer tutucu yeniden oluşturulur. (Yer tutucular bölümüne bakın.)
WindowManager, ikincil bölmede yer alan etkinlikleri birincil bölmede yer alan etkinliklerin üzerine z-sıralı olarak yerleştirdiği için etkinliklerin yığılması mümkündür.
İkincil bölmede birden fazla etkinlik
B etkinliği, ek intent işaretleri olmadan C etkinliğini yerinde başlatır:
Bu işlem sonucunda, aynı görevdeki etkinliklerin z-sıralı düzeni aşağıdaki gibi olur:
Bu nedenle, daha küçük bir görev penceresinde uygulama, yığının en üstünde C bulunan tek bir etkinliğe küçülür:
Küçük pencerede geriye gitmek, etkinliklerin birbirinin üzerine yığıldığı ekranda gezinmenizi sağlar.
Görev penceresi yapılandırması, birden fazla bölmeyi barındırabilecek daha büyük bir boyuta geri yüklenirse etkinlikler tekrar yan yana gösterilir.
Yığılmış bölme
B etkinliği, C etkinliğini yan tarafta başlatır ve bölünmüş ekranı yana doğru kaydırır:
Sonuç olarak, aynı görevdeki etkinliklerin aşağıdaki z-sıralı listesi elde edilir:
Daha küçük bir görev penceresinde uygulama, üstte C bulunan tek bir etkinliğe küçülür:
Sabit dikey yön
android:screenOrientation manifest ayarı, uygulamaların etkinlikleri dikey veya yatay yönde kısıtlamasını sağlar. Tablet ve katlanabilir cihazlar gibi büyük ekranlı cihazlarda kullanıcı deneyimini iyileştirmek için cihaz üreticileri (OEM'ler), ekran yönü isteklerini yoksayabilir ve uygulamayı yatay ekranlarda dikey yönde veya dikey ekranlarda yatay yönde dikey kenarlıklarla gösterebilir.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/a_letterboxed_portrait_and_landscape.png?authuser=0&hl=tr)
Benzer şekilde, etkinlik yerleştirme etkinleştirildiğinde OEM'ler cihazları, büyük ekranlarda (genişlik ≥ 600 dp) yatay yönde sabit dikey aktiviteler için sinemaskoplu olacak şekilde özelleştirebilir. Sabit dikey bir etkinlik ikinci bir etkinlik başlattığında cihaz, iki etkinliği iki bölmeli bir ekranda yan yana gösterebilir.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/a_letterboxed_portrait_to_a_b.png?authuser=0&hl=tr)
Cihazları, uygulamanızın etkinlik yerleştirmeyi desteklediğini bildirmek için uygulama manifesti dosyanıza her zaman android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED
mülkünü ekleyin (Bölünmüş yapılandırma bölümüne bakın). OEM tarafından özelleştirilen cihazlar, sabit dikey etkinliklerin sinemaskop moduna alınıp alınmayacağını belirleyebilir.
Bölme yapılandırması
Bölme kuralları, etkinlik bölmelerini yapılandırır. Bölme kurallarını bir XML yapılandırma dosyasında veya Jetpack WindowManager API çağrıları yaparak tanımlarsınız.
Her iki durumda da uygulamanız WindowManager kitaplığına erişmeli ve sistemi, uygulamanın etkinlik yerleştirme özelliğini uyguladığını bilgilendirmelidir.
Aşağıdakileri yapın:
En yeni WindowManager kitaplık bağımlılığını uygulamanızın modül düzeyindeki
build.gradle
dosyasına ekleyin. Örneğin:implementation 'androidx.window:window:1.1.0-beta02'
WindowManager kitaplığı, etkinlik yerleştirme için gereken tüm bileşenleri sağlar.
Sistemi, uygulamanızın etkinlik yerleştirme özelliğini uyguladığını bilgilendirin.
android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED
mülkünü uygulama manifesti dosyasının <application> öğesine ekleyin ve değeri true olarak ayarlayın. Örneğin:<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application> <property android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED" android:value="true" /> </application> </manifest>
WindowManager 1.1.0-alpha06 ve sonraki sürümlerde, mülk manifest dosyasına eklenip doğru olarak ayarlanmazsa etkinlik yerleştirme bölmelerini devre dışı bırakılır.
Ayrıca cihaz üreticileri, etkinlik yerleştirmeyi destekleyen uygulamalar için özel özellikleri etkinleştirmek amacıyla bu ayarı kullanır. Örneğin, cihazlar ikinci bir etkinlik başladığında etkinliği iki bölmeli bir düzene geçiş için yönlendirmek amacıyla yatay ekranlarda yalnızca dikey olan bir etkinliği sinemaskop şeklinde gösterebilir (Sabit dikey yön bölümüne bakın).
XML yapılandırması
Etkinlik yerleştirme için XML tabanlı bir uygulama oluşturmak üzere aşağıdaki adımları tamamlayın:
Aşağıdakileri yapan bir XML kaynak dosyası oluşturun:
- Bölünmüşlüğü paylaşan etkinlikleri tanımlar
- Bölme seçeneklerini yapılandırır.
- İçerik mevcut olmadığında bölünmüş içeriğin ikincil kapsayıcısı için bir yer tutucu oluşturur
- Hiçbir zaman bir bölme işleminin parçası olmaması gereken etkinlikleri belirtir.
Örnek:
<!-- main_split_config.xml --> <resources xmlns:window="http://schemas.android.com/apk/res-auto"> <!-- Define a split for the named activities. --> <SplitPairRule window:splitRatio="0.33" window:splitLayoutDirection="locale" window:splitMinWidthDp="840" window:splitMaxAspectRatioInPortrait="alwaysAllow" window:finishPrimaryWithSecondary="never" window:finishSecondaryWithPrimary="always" window:clearTop="false"> <SplitPairFilter window:primaryActivityName=".ListActivity" window:secondaryActivityName=".DetailActivity"/> </SplitPairRule> <!-- Specify a placeholder for the secondary container when content is not available. --> <SplitPlaceholderRule window:placeholderActivityName=".PlaceholderActivity" window:splitRatio="0.33" window:splitLayoutDirection="locale" window:splitMinWidthDp="840" window:splitMaxAspectRatioInPortrait="alwaysAllow" window:stickyPlaceholder="false"> <ActivityFilter window:activityName=".ListActivity"/> </SplitPlaceholderRule> <!-- Define activities that should never be part of a split. Note: Takes precedence over other split rules for the activity named in the rule. --> <ActivityRule window:alwaysExpand="true"> <ActivityFilter window:activityName=".ExpandedActivity"/> </ActivityRule> </resources>
Bir başlatıcı oluşturun.
WindowManager
RuleController
bileşeni, XML yapılandırma dosyasını ayrıştırır ve kuralları sisteme sunar. Jetpack Startup kitaplığıInitializer
, XML dosyasını uygulama başlatılırkenRuleController
'e sunar. Böylece, herhangi bir etkinlik başladığında kurallar geçerli olur.Bir başlatıcı oluşturmak için aşağıdakileri yapın:
Modül düzeyindeki
build.gradle
dosyanıza en yeni Jetpack Startup kitaplık bağımlılığını ekleyin. Örneğin:implementation 'androidx.startup:startup-runtime:1.1.1'
Initializer
arayüzünü uygulayan bir sınıf oluşturun.Başlatıcı, XML yapılandırma dosyasının kimliğini (
main_split_config.xml
)RuleController.parseRules()
yöntemine ileterek bölme kurallarınıRuleController
için kullanılabilir hale getirir.Kotlin
class SplitInitializer : Initializer<RuleController> { override fun create(context: Context): RuleController { return RuleController.getInstance(context).apply { setRules(RuleController.parseRules(context, R.xml.main_split_config)) } } override fun dependencies(): List<Class<out Initializer<*>>> { return emptyList() } }
Java
public class SplitInitializer implements Initializer<RuleController> { @NonNull @Override public RuleController create(@NonNull Context context) { RuleController ruleController = RuleController.getInstance(context); ruleController.setRules( RuleController.parseRules(context, R.xml.main_split_config) ); return ruleController; } @NonNull @Override public List<Class<? extends Initializer<?>>> dependencies() { return Collections.emptyList(); } }
Kural tanımları için bir içerik sağlayıcı oluşturun.
androidx.startup.InitializationProvider
öğesini<provider>
olarak uygulama manifesti dosyanıza ekleyin.RuleController
başlatıcınızın (SplitInitializer
) uygulanmasına dair bir referans ekleyin:<!-- AndroidManifest.xml --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <!-- Make SplitInitializer discoverable by InitializationProvider. --> <meta-data android:name="${applicationId}.SplitInitializer" android:value="androidx.startup" /> </provider>
InitializationProvider
, uygulamanınonCreate()
yöntemi çağrılmadan önceSplitInitializer
'ı bulur ve başlatır. Sonuç olarak, uygulamanın ana etkinliği başladığında bölme kuralları geçerli olur.
WindowManager API
Etkinlik yerleştirmeyi birkaç API çağrısıyla programatik olarak uygulayabilirsiniz. Kuralların herhangi bir etkinlik başlatılmadan önce geçerli olduğundan emin olmak için Application
alt sınıfının onCreate()
yönteminde çağrıları yapın.
Programatik olarak etkinlik bölme oluşturmak için aşağıdakileri yapın:
Bölme kuralı oluşturun:
Bölünmeyi paylaşan etkinlikleri tanımlayan bir
SplitPairFilter
oluşturun:Kotlin
val splitPairFilter = SplitPairFilter( ComponentName(this, ListActivity::class.java), ComponentName(this, DetailActivity::class.java), null )
Java
SplitPairFilter splitPairFilter = new SplitPairFilter( new ComponentName(this, ListActivity.class), new ComponentName(this, DetailActivity.class), null );
Filtreyi bir filtre grubuna ekleyin:
Kotlin
val filterSet = setOf(splitPairFilter)
Java
Set<SplitPairFilter> filterSet = new HashSet<>(); filterSet.add(splitPairFilter);
Bölme için sayfa düzeni özellikleri oluşturun:
Kotlin
val splitAttributes: SplitAttributes = SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build()
Java
final SplitAttributes splitAttributes = new SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build();
SplitAttributes.Builder
, düzen özelliklerini içeren bir nesne oluşturur:setSplitType()
: Mevcut ekran alanının her etkinlik kapsayıcısına nasıl ayrıldığını tanımlar. Oran bölme türü, birincil kapsayıcıya ayrılan kullanılabilir görüntü alanı oranını belirtir. İkincil kapsayıcı, kullanılabilir görüntü alanının geri kalanını kaplar.setLayoutDirection()
: Etkinlik kapsayıcılarının birbirine göre nasıl düzenlendiğini belirtir. Önce birincil kapsayıcı.
SplitPairRule
oluşturun:Kotlin
val splitPairRule = SplitPairRule.Builder(filterSet) .setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.NEVER) .setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS) .setClearTop(false) .build()
Java
SplitPairRule splitPairRule = new SplitPairRule.Builder(filterSet) .setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.NEVER) .setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS) .setClearTop(false) .build();
SplitPairRule.Builder
kuralı oluşturur ve yapılandırır:filterSet
: Bir bölmeyi paylaşan etkinlikleri tanımlayarak kuralın ne zaman uygulanacağını belirleyen bölme çifti filtreleri içerir.setDefaultSplitAttributes()
: Kural için düzen özelliklerini uygular.setMinWidthDp()
: Bölünmeyi etkinleştiren minimum ekran genişliğini (yoğunluktan bağımsız piksel cinsinden, dp) ayarlar.setMinSmallestWidthDp()
: Cihaz yönüne bakılmaksızın bölme etkinleştirmek için iki ekran boyutundan küçük olanın sahip olması gereken minimum değeri (dp cinsinden) ayarlar.setMaxAspectRatioInPortrait()
: Etkinlik bölmelerinin gösterildiği dikey yönde maksimum ekran en boy oranını (yükseklik:genişlik) ayarlar. Dikey ekranın en boy oranı maksimum en boy oranını aşarsa ekranın genişliğinden bağımsız olarak bölmeler devre dışı bırakılır. Not: Varsayılan değer 1,4'tür.Bu değer, etkinliklerin çoğu tablette dikey yönde görev penceresinin tamamını kaplamasına neden olur. AyrıcaSPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT
vesetMaxAspectRatioInLandscape()
sayfalarına göz atın. Yatay için varsayılan değerALWAYS_ALLOW
'dur.setFinishPrimaryWithSecondary()
: İkincil kapsayıcıdaki tüm etkinliklerin tamamlanmasının birincil kapsayıcıdaki etkinlikleri nasıl etkilediğini belirler.NEVER
, ikincil kapsayıcıdaki tüm etkinlikler sona erdiğinde sistemin birincil etkinlikleri bitirmemesi gerektiğini belirtir (Etkinlikleri sonlandırma bölümüne bakın).setFinishSecondaryWithPrimary()
: Birincil kapsayıcıdaki tüm etkinliklerin tamamlanmasının ikincil kapsayıcıdaki etkinlikleri nasıl etkilediğini belirler.ALWAYS
, birincil kapsayıcıdaki tüm etkinlikler sona erdiğinde sistemin her zaman ikincil kapsayıcıdaki etkinlikleri de bitirmesi gerektiğini belirtir (Etkinlikleri sonlandırma bölümüne bakın).setClearTop()
: Kapsayıcıda yeni bir etkinlik başlatıldığında ikincil kapsayıcıdaki tüm etkinliklerin sona erip ermediğini belirtir.false
değeri, yeni etkinliklerin ikincil kapsayıcıda bulunan etkinliklerin üzerine yığıldığını belirtir.
WindowManager
RuleController
sınıfının tekil örneğini alın ve kuralı ekleyin:Kotlin
val ruleController = RuleController.getInstance(this) ruleController.addRule(splitPairRule)
Java
RuleController ruleController = RuleController.getInstance(this); ruleController.addRule(splitPairRule);
İçerik mevcut olmadığında ikincil kapsayıcı için bir yer tutucu oluşturun:
Yer tutucunun görev penceresi bölmesini paylaştığı etkinliği tanımlayan bir
ActivityFilter
oluşturun:Kotlin
val placeholderActivityFilter = ActivityFilter( ComponentName(this, ListActivity::class.java), null )
Java
ActivityFilter placeholderActivityFilter = new ActivityFilter( new ComponentName(this, ListActivity.class), null );
Filtreyi bir filtre grubuna ekleyin:
Kotlin
val placeholderActivityFilterSet = setOf(placeholderActivityFilter)
Java
Set<ActivityFilter> placeholderActivityFilterSet = new HashSet<>(); placeholderActivityFilterSet.add(placeholderActivityFilter);
SplitPlaceholderRule
oluşturma:Kotlin
val splitPlaceholderRule = SplitPlaceholderRule.Builder( placeholderActivityFilterSet, Intent(context, PlaceholderActivity::class.java) ).setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS) .setSticky(false) .build()
Java
SplitPlaceholderRule splitPlaceholderRule = new SplitPlaceholderRule.Builder( placeholderActivityFilterSet, new Intent(context, PlaceholderActivity.class) ).setDefaultSplitAttributes(splitAttributes) .setMinWidthDp(840) .setMinSmallestWidthDp(600) .setMaxAspectRatioInPortrait(EmbeddingAspectRatio.ratio(1.5f)) .setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS) .setSticky(false) .build();
SplitPlaceholderRule.Builder
kuralı oluşturur ve yapılandırır:placeholderActivityFilterSet
: Yer tutucu etkinliğinin ilişkili olduğu etkinlikleri tanımlayarak kuralın ne zaman uygulanacağını belirleyen etkinlik filtrelerini içerir.Intent
: Yer tutucu etkinliğinin başlatılmasını belirtir.setDefaultSplitAttributes()
: Düzen özelliklerini kurala uygular.setMinWidthDp()
: Bölünmeye izin veren minimum ekran genişliğini (yoğunluktan bağımsız piksel cinsinden, dp) ayarlar.setMinSmallestWidthDp()
: Cihaz yönüne bakılmaksızın bölünmeye izin vermek için iki ekran boyutundan küçük olanın sahip olması gereken minimum değeri (dp cinsinden) belirler.setMaxAspectRatioInPortrait()
: Etkinlik bölmelerinin gösterildiği dikey yönde maksimum ekran en boy oranını (yükseklik:genişlik) ayarlar. Not: Varsayılan değer 1,4'tür.Bu değer, etkinliklerin çoğu tablette görev penceresini dikey yönde doldurmasına neden olur. AyrıcaSPLIT_MAX_ASPECT_RATIO_PORTRAIT_DEFAULT
vesetMaxAspectRatioInLandscape()
sayfalarına göz atın. Yatay için varsayılan değerALWAYS_ALLOW
.setFinishPrimaryWithPlaceholder()
: Yer tutucu etkinliğinin tamamlanmasının birincil kapsayıcıdaki etkinlikleri nasıl etkileyeceğini belirler. HER ZAMAN, yer tutucu sona erdiğinde sistemin birincil kapsayıcıdaki etkinlikleri her zaman bitirmesi gerektiğini belirtir (Etkinlikleri sonlandırma bölümüne bakın).setSticky()
: Yer tutucu ilk kez yeterli minimum genişliğe sahip bir bölme içinde göründüğünde yer tutucu etkinliğinin küçük ekranlarda etkinlik yığınının üstünde görünüp görünmeyeceğini belirler.
Kuralı WindowManager'a
RuleController
ekleyin:Kotlin
ruleController.addRule(splitPlaceholderRule)
Java
ruleController.addRule(splitPlaceholderRule);
Hiçbir zaman bölme işlemine dahil edilmemesi gereken etkinlikleri belirtin:
Her zaman görev görüntüleme alanının tamamını kaplaması gereken bir etkinliği tanımlayan bir
ActivityFilter
oluşturun:Kotlin
val expandedActivityFilter = ActivityFilter( ComponentName(this, ExpandedActivity::class.java), null )
Java
ActivityFilter expandedActivityFilter = new ActivityFilter( new ComponentName(this, ExpandedActivity.class), null );
Filtreyi bir filtre grubuna ekleyin:
Kotlin
val expandedActivityFilterSet = setOf(expandedActivityFilter)
Java
Set<ActivityFilter> expandedActivityFilterSet = new HashSet<>(); expandedActivityFilterSet.add(expandedActivityFilter);
Bir
ActivityRule
oluşturun:Kotlin
val activityRule = ActivityRule.Builder(expandedActivityFilterSet) .setAlwaysExpand(true) .build()
Java
ActivityRule activityRule = new ActivityRule.Builder( expandedActivityFilterSet ).setAlwaysExpand(true) .build();
ActivityRule.Builder
kuralı oluşturur ve yapılandırır:expandedActivityFilterSet
: Bölümlere dahil etmek istemediğiniz etkinlikleri tanımlayarak kuralın ne zaman uygulanacağını belirleyen etkinlik filtreleri içerir.setAlwaysExpand()
: Etkinliğin görev penceresinin tamamını doldurup doldurmayacağını belirtir.
Kuralı WindowManager'a
RuleController
ekleyin:Kotlin
ruleController.addRule(activityRule)
Java
ruleController.addRule(activityRule);
Uygulamalar arası yerleştirme
Android 13 (API düzeyi 33) ve sonraki sürümlerde uygulamalar, diğer uygulamalardaki etkinlikleri yerleştirebilir. Uygulamalar arası veya UID etkinliği yerleştirme, birden fazla Android uygulamasındaki etkinliklerin görsel olarak entegrasyonunu sağlar. Sistem, tek uygulama etkinliği yerleştirmede olduğu gibi, barındıran uygulamanın etkinliğini ve başka bir uygulamadan yerleştirilmiş etkinliği ekranda yan yana veya üst üste gösterir.
Örneğin, Ayarlar uygulaması, WallpaperPicker uygulamasındaki duvar kağıdı seçici etkinliğini yerleştirebilir:
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/wallpaper_activity_embedded_in_settings_app.png?authuser=0&hl=tr)
Güven modeli
Diğer uygulamalardan etkinlikleri yerleştiren ana makine işlemleri, boyut, konum, kırpma ve şeffaflık dahil olmak üzere yerleştirilen etkinliklerin sunumunu yeniden tanımlayabilir. Kötü amaçlı barındırıcılar, kullanıcıları yanıltmak ve tıklama tuşuyla saldırı veya kullanıcı arayüzünü değiştirmeye yönelik başka saldırılar oluşturmak için bu özelliği kullanabilir.
Android, uygulama içi etkinlik yerleştirmenin kötüye kullanılmasını önlemek için uygulamaların etkinliklerinin yerleştirilmesine izin vermek üzere etkinleştirme yapmasını zorunlu kılar. Uygulamalar, ana makineleri güvenilir veya güvenilmeyen olarak tanımlayabilir.
Güvenilir ana makineler
Diğer uygulamaların, uygulamanızdaki etkinliklerin sunumunu yerleştirmesine ve tamamen kontrol etmesine izin vermek için uygulamanızın manifest dosyasının <activity>
veya <application>
öğelerinin android:knownActivityEmbeddingCerts
özelliğinde barındıran uygulamanın SHA-256 sertifikasını belirtin.
android:knownActivityEmbeddingCerts
değerini dize olarak ayarlayın:
<activity
android:name=".MyEmbeddableActivity"
android:knownActivityEmbeddingCerts="@string/known_host_certificate_digest"
... />
Birden fazla sertifika belirtmek için bir dize dizisi de kullanabilirsiniz:
<activity
android:name=".MyEmbeddableActivity"
android:knownActivityEmbeddingCerts="@array/known_host_certificate_digests"
... />
Aşağıdaki gibi bir kaynağa referans veren:
<resources>
<string-array name="known_host_certificate_digests">
<item>cert1</item>
<item>cert2</item>
...
</string-array>
</resources>
Uygulama sahipleri, Gradle signingReport
görevini çalıştırarak SHA sertifika özetini alabilir. Sertifika özeti, ayırıcı iki nokta işareti olmadan SHA-256 parmak izidir. Daha fazla bilgi için İmza raporu oluşturma ve İstemcinizin Kimliğini Doğrulama başlıklı makaleleri inceleyin.
Güvenilmeyen ana makineler
Herhangi bir uygulamanın, uygulamanızın etkinliklerini yerleştirmesine ve sunumunu kontrol etmesine izin vermek için uygulama manifest dosyasında <activity>
veya <application>
öğelerinde android:allowUntrustedActivityEmbedding
özelliğini belirtin. Örneğin:
<activity
android:name=".MyEmbeddableActivity"
android:allowUntrustedActivityEmbedding="true"
... />
Özniteliğin varsayılan değeri false olduğundan uygulamalar arası etkinlik yerleştirme engellenir.
Özel kimlik doğrulama
Güvenilir olmayan etkinlik yerleştirme risklerini azaltmak için ana makine kimliğini doğrulayan özel bir kimlik doğrulama mekanizması oluşturun. Ana makine sertifikalarını biliyorsanız kimlik doğrulama için androidx.security.app.authenticator
kitaplığını kullanın. Düzenleyen kullanıcı, etkinliğinizi yerleştirdikten sonra kimlik doğrulaması yaparsa gerçek içeriği gösterebilirsiniz. Aksi takdirde, kullanıcıya işleme izin verilmediğini bildirebilir ve içeriği engelleyebilirsiniz.
Bir barındırıcının etkinliğinizi yerleştirip yerleştirmediğini kontrol etmek için Jetpack WindowManager kitaplığındaki ActivityEmbeddingController#isActivityEmbedded()
yöntemini kullanın. Örneğin:
Kotlin
fun isActivityEmbedded(activity: Activity): Boolean { return ActivityEmbeddingController.getInstance(this).isActivityEmbedded(activity) }
Java
boolean isActivityEmbedded(Activity activity) { return ActivityEmbeddingController.getInstance(this).isActivityEmbedded(activity); }
Minimum boyut kısıtlaması
Android sistemi, uygulama manifest'inde <layout>
öğesinde belirtilen minimum yüksekliği ve genişliği yerleşik etkinliklere uygular. Bir uygulamada minimum yükseklik ve genişlik belirtilmezse sistem varsayılan değerleri geçerli olur (sw220dp
).
Ana makine, yerleşik kapsayıcının boyutunu minimumdan daha küçük bir boyuta değiştirmeye çalışırsa yerleşik kapsayıcı, görev sınırlarının tamamını kaplayacak şekilde genişler.
<activity-alias>
Güvenilir veya güvenilmeyen etkinlik yerleştirmenin <activity-alias>
öğesiyle çalışması için hedef etkinliğe, takma ad yerine android:knownActivityEmbeddingCerts
veya android:allowUntrustedActivityEmbedding
uygulanmalıdır. Sistem sunucusunda güvenliği doğrulayan politika, takma ada değil hedefte ayarlanan işaretlere dayanır.
Ana makine uygulaması
Barındıran uygulamalar, uygulamalar arası etkinlik yerleştirmeyi tek uygulamalı etkinlik yerleştirmeyle aynı şekilde uygular. SplitPairRule
ve SplitPairFilter
veya ActivityRule
ve ActivityFilter
nesneleri, yerleştirilmiş etkinlikleri ve görev penceresi bölmelerini belirtir. Bölme kuralları XML'de statik olarak veya Jetpack WindowManager API çağrıları kullanılarak çalışma zamanında tanımlanır.
Bir barındıran uygulama, uygulamalar arası yerleştirmeyi etkinleştirmemiş bir etkinliği yerleştirmeye çalışırsa etkinlik, görev sınırlarının tamamını kaplar. Bu nedenle, barındıran uygulamaların hedef etkinliklerin uygulamalar arası yerleştirmeye izin verip vermediğini bilmesi gerekir.
Yerleştirilmiş bir etkinlik aynı görevde yeni bir etkinlik başlatırsa ve yeni etkinlik uygulamalar arası yerleştirmeyi etkinleştirmemişse etkinlik, yerleştirilmiş kapsayıcıdaki etkinliği yer paylaşımı yapmak yerine görev sınırlarının tamamını kaplar.
Barındıran uygulama, etkinlikler aynı görevde başlatıldığı sürece kendi etkinliklerini kısıtlama olmadan yerleştirebilir.
Bölme örnekleri
Tam pencereden bölme
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/a_to_a_b.png?authuser=0&hl=tr)
Yeniden yapılandırmaya gerek yoktur. Bölünme yapılandırmasını statik olarak veya çalışma zamanında tanımlayabilir ve ardından ek parametre olmadan Context#startActivity()
işlevini çağırabilirsiniz.
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Varsayılan olarak böl
Bir uygulamanın açılış sayfası büyük ekranlarda iki kapsayıcıya bölünecek şekilde tasarlandığında, kullanıcı deneyimi en iyi şekilde her iki etkinlik de oluşturulup aynı anda sunulduğunda elde edilir. Ancak kullanıcı birincil kapsayıcıdaki etkinlikle etkileşime geçene kadar içerik, bölünmenin ikincil kapsayıcısı için kullanılamayabilir (örneğin, kullanıcı bir gezinme menüsünden bir öğe seçtiğinde). İçerik, bölme işleminin ikincil kapsayıcısında gösterilene kadar yer tutucu etkinlik boşluğu doldurabilir (Yer tutucular bölümüne bakın).
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/launcher_main_placeholder.png?authuser=0&hl=tr)
Yer tutucu içeren bir bölme oluşturmak için bir yer tutucu oluşturun ve bunu birincil etkinlikle ilişkilendirin:
<SplitPlaceholderRule
window:placeholderActivityName=".PlaceholderActivity">
<ActivityFilter
window:activityName=".MainActivity"/>
</SplitPlaceholderRule>
Derin bağlantı bölme
Bir uygulama bir intent aldığında hedef etkinlik, etkinlik bölme işleminin ikincil kısmı olarak gösterilebilir. Örneğin, bir listedeki öğeyle ilgili bilgilerin yer aldığı bir ayrıntı ekranı gösterme isteği. Küçük ekranlarda ayrıntılar, görev penceresinin tamamında, büyük ekranlarda ise listenin yanında gösterilir.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/deep_link_split.png?authuser=0&hl=tr)
Başlatma isteği ana etkinliğe yönlendirilmeli ve hedef ayrıntı etkinliği bölünmüş olarak başlatılmalıdır. Sistem, mevcut ekran genişliğine göre doğru sunumu (yığılmış veya yan yana) otomatik olarak seçer.
Kotlin
override fun onCreate(savedInstanceState Bundle?) { . . . RuleController.getInstance(this) .addRule(SplitPairRule.Builder(filterSet).build()) startActivity(Intent(this, DetailActivity::class.java)) }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { . . . RuleController.getInstance(this) .addRule(new SplitPairRule.Builder(filterSet).build()); startActivity(new Intent(this, DetailActivity.class)); }
Derin bağlantı hedefi, kullanıcının arka gezinme yığınında kullanabileceği tek etkinlik olabilir. Ayrıntı etkinliğini kapatıp yalnızca ana etkinliği bırakmak isteyebilirsiniz:
Bunun yerine, finishPrimaryWithSecondary
özelliğini kullanarak her iki etkinliği de aynı anda bitirebilirsiniz:
<SplitPairRule
window:finishPrimaryWithSecondary="always">
<SplitPairFilter
window:primaryActivityName=".ListActivity"
window:secondaryActivityName=".DetailActivity"/>
</SplitPairRule>
Yapılandırma özellikleri bölümüne bakın.
Bölünmüş kapsayıcılarda birden fazla etkinlik
Bölünmüş bir kapsayıcıda birden fazla etkinliği yığmak, kullanıcıların derin içeriğe erişmesine olanak tanır. Örneğin, liste-ayrıntı bölmelerinde kullanıcının bir alt ayrıntı bölümüne gitmesi ancak birincil etkinliği yerinde tutması gerekebilir:
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/list-detail_to_list-sub-detail.png?authuser=0&hl=tr)
Kotlin
class DetailActivity { . . . fun onOpenSubDetail() { startActivity(Intent(this, SubDetailActivity::class.java)) } }
Java
public class DetailActivity { . . . void onOpenSubDetail() { startActivity(new Intent(this, SubDetailActivity.class)); } }
Alt ayrıntı etkinliği, ayrıntı etkinliğinin üzerine yerleştirilerek gizlenir:
Kullanıcı, grup içinde geri giderek önceki ayrıntı düzeyine geri dönebilir:
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/list-sub-detail_to_list-detail.png?authuser=0&hl=tr)
Etkinlikler aynı ikincil kapsayıcıdaki bir etkinlikten başlatıldığında varsayılan davranış, etkinliklerin birbirinin üzerine yığılmasıdır. Etkin bir bölme içinde birincil kapsayıcıdan başlatılan etkinlikler de etkinlik yığınının üst kısmındaki ikincil kapsayıcıya gönderilir.
Yeni bir görevdeki etkinlikler
Bölünmüş görev penceresindeki etkinlikler yeni bir görevde etkinlik başlattığında yeni görev, bölünmüş görevi içeren görevden ayrıdır ve tam pencerede gösterilir. Sonlar ekranında iki görev gösterilir: Bölünmüş görev ve yeni görev.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/task_1_to_task_2.png?authuser=0&hl=tr)
Etkinlik değiştirme
Etkinlikler, ikincil kapsayıcı yığınında değiştirilebilir. Örneğin, birincil etkinlik üst düzey gezinme için kullanıldığında ve ikincil etkinlik seçili bir hedef olduğunda. Üst düzey gezinme menüsündeki her seçim, ikincil kapsayıcıda yeni bir etkinlik başlatmalı ve daha önce orada bulunan etkinliği veya etkinlikleri kaldırmalıdır.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/menu_screen_a_to_menu_screen_b.png?authuser=0&hl=tr)
Uygulama, gezinme seçimi değiştiğinde ikincil kapsayıcıdaki etkinliği bitirmezse bölme daraltıldığında (cihaz katlandığında) geri gezinme kafa karıştırıcı olabilir. Örneğin, birincil bölmede bir menünüz ve ikincil bölmede A ve B ekranları yığılmışsa kullanıcı telefonu katladığında B, A'nın üstüne, A da menünün üstüne gelir. Kullanıcı B'den geri geldiğinde menü yerine A görünür.
Bu tür durumlarda A ekranı arka yığıntan kaldırılmalıdır.
Mevcut bir bölme üzerinde yeni bir kapsayıcıda yan tarafta başlatıldığında varsayılan davranış, yeni ikincil kapsayıcıları en üste koymak ve eski kapsayıcıları arka yığınta tutmak olur. Bölümleri, önceki ikincil kapsayıcıları clearTop
ile temizleyecek ve yeni etkinlikleri normal şekilde başlatacak şekilde yapılandırabilirsiniz.
<SplitPairRule
window:clearTop="true">
<SplitPairFilter
window:primaryActivityName=".Menu"
window:secondaryActivityName=".ScreenA"/>
<SplitPairFilter
window:primaryActivityName=".Menu"
window:secondaryActivityName=".ScreenB"/>
</SplitPairRule>
Kotlin
class MenuActivity { . . . fun onMenuItemSelected(selectedMenuItem: Int) { startActivity(Intent(this, classForItem(selectedMenuItem))) } }
Java
public class MenuActivity { . . . void onMenuItemSelected(int selectedMenuItem) { startActivity(new Intent(this, classForItem(selectedMenuItem))); } }
Alternatif olarak, aynı ikincil etkinliği kullanın ve birincil (menü) etkinlikten aynı örneğe çözüm bulan ancak ikincil kapsayıcıda bir durum veya kullanıcı arayüzü güncellemesi tetikleyen yeni intent'ler gönderin.
Birden fazla bölme
Uygulamalar, yan tarafta ek etkinlikler başlatarak çok düzeyli derin gezinme sağlayabilir.
İkincil bir kapsayıcıdaki etkinlik, yan tarafta yeni bir etkinlik başlattığında mevcut bölme üzerine yeni bir bölme oluşturulur.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/a_b_to_b_c.png?authuser=0&hl=tr)
Arka yığın, daha önce açılmış tüm etkinlikleri içerir. Böylece kullanıcılar C'yi tamamladıktan sonra A/B bölmelerine gidebilir.
Yeni bir bölme oluşturmak için yeni etkinliği mevcut ikincil kapsayıcıdan yana doğru başlatın. Hem A/B hem de B/C bölmelerinin yapılandırmalarını belirtin ve C etkinliğini normal şekilde B'den başlatın:
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
<SplitPairFilter
window:primaryActivityName=".B"
window:secondaryActivityName=".C"/>
</SplitPairRule>
Kotlin
class B { . . . fun onOpenC() { startActivity(Intent(this, C::class.java)) } }
Java
public class B { . . . void onOpenC() { startActivity(new Intent(this, C.class)); } }
Bölme durumu değişikliklerine tepki verme
Bir uygulamadaki farklı etkinliklerde aynı işlevi gerçekleştiren kullanıcı arayüzü öğeleri olabilir. Örneğin, hesap ayarlarını içeren bir pencere açan bir kontrol.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/main_detail_with_ui_element.png?authuser=0&hl=tr)
Ortak bir kullanıcı arayüzü öğesine sahip iki etkinlik bölünmüşse öğenin her iki etkinlikte de gösterilmesi gereksiz ve belki de kafa karıştırıcıdır.
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/main_detail_with_ui_element_duplicated.png?authuser=0&hl=tr)
Etkinliklerin ne zaman bölündüğünü öğrenmek için SplitController.splitInfoList
akışını kontrol edin veya bölünmüş durumdaki değişiklikler için SplitControllerCallbackAdapter
ile bir dinleyici kaydedin. Ardından kullanıcı arayüzünü uygun şekilde ayarlayın:
Kotlin
val layout = layoutInflater.inflate(R.layout.activity_main, null) val view = layout.findViewById<View>(R.id.infoButton) lifecycleScope.launch { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { splitController.splitInfoList(this@SplitDeviceActivity) // The activity instance. .collect { list -> view.visibility = if (list.isEmpty()) View.VISIBLE else View.GONE } } }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { . . . new SplitControllerCallbackAdapter(SplitController.getInstance(this)) .addSplitListener( this, Runnable::run, splitInfoList -> { View layout = getLayoutInflater().inflate(R.layout.activity_main, null); layout.findViewById(R.id.infoButton).setVisibility( splitInfoList.isEmpty() ? View.VISIBLE : View.GONE); }); }
İş akışı, herhangi bir yaşam döngüsü durumunda başlatılabilir ancak genellikle kaynakları korumak için STARTED
durumunda başlatılır (daha fazla bilgi için Kotlin iş akışlarını yaşam döngüsü bilincine sahip bileşenlerle kullanma başlıklı makaleyi inceleyin).
Geri çağırma, bir etkinlik durdurulduğunda da dahil olmak üzere herhangi bir yaşam döngüsü durumunda yapılabilir. Dinleyiciler genellikle onStart()
'te kayıtlı, onStop()
'te ise kayıtsız olmalıdır.
Tam pencere kalıcı penceresi
Bazı etkinlikler, belirli bir işlem (ör. giriş ekranı etkinliği, politika onayı ekranı veya hata mesajı) gerçekleştirilene kadar kullanıcıların uygulamayla etkileşim kurmasını engeller. Modüler etkinliklerin bölünmüş ekranda gösterilmesi engellenmelidir.
Genişlet yapılandırmasını kullanarak bir etkinliğin her zaman görev penceresini doldurması zorunlu kılınabilir:
<ActivityRule
window:alwaysExpand="true">
<ActivityFilter
window:activityName=".FullWidthActivity"/>
</ActivityRule>
Etkinlikleri tamamlama
Kullanıcılar, ekranın kenarından kaydırarak bölünmüş ekranın her iki tarafındaki etkinlikleri bitirebilir:
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/swipe_gesture_finish_b.png?authuser=0&hl=tr)
![](https://developer.android.google.cn/static/develop/ui/views/images/activity-embedding/swipe_gesture_finish_a.png?authuser=0&hl=tr)
Cihaz, hareketle gezinme yerine geri düğmesini kullanacak şekilde ayarlanmışsa giriş, odaklanan etkinliğe (en son dokunulan veya başlatılan etkinliğe) gönderilir.
Bir kapsayıcıdaki tüm etkinliklerin tamamlanmasının karşı kapsayıcı üzerindeki etkisi, bölme yapılandırmasına bağlıdır.
Yapılandırma özellikleri
Bölünmenin bir tarafındaki tüm etkinliklerin tamamlanmasının, bölünmenin diğer tarafındaki etkinlikleri nasıl etkilediğini yapılandırmak için bölme çifti kural özelliklerini belirtebilirsiniz. Özellikler şunlardır:
window:finishPrimaryWithSecondary
: İkincil kapsayıcıdaki tüm etkinliklerin tamamlanması birincil kapsayıcıdaki etkinlikleri nasıl etkiler?window:finishSecondaryWithPrimary
: Birincil kapsayıcıdaki tüm etkinliklerin tamamlanması, ikincil kapsayıcıdaki etkinlikleri nasıl etkiler?
Özelliklerin olası değerleri şunlardır:
always
: Etkinlikleri her zaman ilişkili kapsayıcıda sonlandırınnever
: İlişkili kapsayıcıdaki etkinlikleri hiçbir zaman bitirmez.adjacent
: İki kapsayıcı yan yana gösterildiğinde ilişkili kapsayıcıdaki etkinlikleri sonlandırın ancak iki kapsayıcı yığıldığında sonlandırmayın.
Örnek:
<SplitPairRule
<!-- Do not finish primary container activities when all secondary container activities finish. -->
window:finishPrimaryWithSecondary="never"
<!-- Finish secondary container activities when all primary container activities finish. -->
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Varsayılan yapılandırma
Bölünmüş bir kapsayıcıdaki tüm etkinlikler sona erdiğinde, kalan kapsayıcı pencerenin tamamını kaplar:
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Etkinlikleri birlikte tamamlama
İkincil kapsayıcıdaki tüm etkinlikler tamamlandığında birincil kapsayıcıdaki etkinlikleri otomatik olarak sonlandırma:
<SplitPairRule
window:finishPrimaryWithSecondary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Birincil kapsayıcıdaki tüm etkinlikler sona erdiğinde ikincil kapsayıcıdaki etkinlikleri otomatik olarak sonlandırma:
<SplitPairRule
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Birincil veya ikincil kapsayıcıdaki tüm etkinlikler tamamlandığında etkinlikleri birlikte sonlandırın:
<SplitPairRule
window:finishPrimaryWithSecondary="always"
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Kapsayıcılarda birden fazla etkinliği tamamlama
Bölünmüş bir kapsayıcıda birden fazla etkinlik yığılmışsa yığının en altındaki bir etkinliğin sonlandırılması, en üstteki etkinliklerin otomatik olarak sonlandırılmasını sağlamaz.
Örneğin, ikincil kapsayıcıda iki etkinlik varsa B'nin üzerinde C:
ve bölme yapılandırması, A ve B etkinliklerinin yapılandırmasına göre belirlenir:
<SplitPairRule>
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Üstteki etkinliği bitirdiğinizde bölme korunur.
İkincil kapsayıcının alt (kök) etkinliği sonlandırılırsa üstteki etkinlikler kaldırılmaz ve bölme korunur.
Etkinlikleri birlikte tamamlamayla ilgili ek kurallar (ör. ikincil etkinliği birincil etkinlikle tamamlama) da uygulanır:
<SplitPairRule
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Bölme, birincil ve ikincil kampanyayı birlikte bitirmek üzere yapılandırıldığında:
<SplitPairRule
window:finishPrimaryWithSecondary="always"
window:finishSecondaryWithPrimary="always">
<SplitPairFilter
window:primaryActivityName=".A"
window:secondaryActivityName=".B"/>
</SplitPairRule>
Bölünmüş özellikleri çalışma zamanında değiştirme
Etkin ve görünür bir bölmenin özellikleri değiştirilemez. Bölme kurallarının değiştirilmesi, ek etkinlik lansmanlarını ve yeni kapsayıcıları etkiler ancak mevcut ve etkin bölme noktalarını etkilemez.
Etkin bölmelerin özelliklerini değiştirmek için bölmedeki yan etkinliği veya etkinlikleri tamamlayın ve yeni bir yapılandırmayla yan tarafta tekrar başlatın.
Dinamik bölünmüş mülkler
Jetpack WindowManager 1.4 ve sonraki sürümler tarafından desteklenen Android 15 (API düzeyi 35) ve sonraki sürümler, etkinlik yerleştirme bölmelerinin yapılandırılabilir olmasını sağlayan dinamik özellikler sunar. Bu özelliklerden bazıları şunlardır:
- Panel genişletme: Etkileşimli ve sürüklenebilir bir bölme, kullanıcıların bölünmüş bir sunudaki panelleri yeniden boyutlandırmasına olanak tanır.
- Etkinlik grubunu sabitleme: Kullanıcılar içeriği bir kapsayıcıya sabitleyebilir ve kapsayıcıdaki gezinmeyi diğer kapsayıcıdaki gezinmeden ayırabilir.
- İletişim kutusunun tam ekranda karartılması: Uygulamalar, iletişim kutusunu görüntülerken görev penceresinin tamamının mı yoksa yalnızca iletişim kutusunu açan kapsayıcının mı karartılacağı belirtebilir.
Bölme genişletmesi
Bölme genişletme, kullanıcıların iki bölmeli düzendeki iki etkinliğe ayrılan ekran alanı miktarını ayarlamalarına olanak tanır.
Pencere bölücünün görünümünü özelleştirmek ve bölücünün sürüklemeli aralığını ayarlamak için aşağıdakileri yapın:
DividerAttributes
örneği oluşturmaBölme özelliklerini özelleştirin:
color
: Taşınabilir bölme ayırıcısının rengi.widthDp
: Taşınabilir bölme ayırıcının genişliği. Bölme genişliğini sistemin belirlemesine izin vermek içinWIDTH_SYSTEM_DEFAULT
olarak ayarlayın.Sürükleme aralığı: Her iki bölmenin de ekranda kaplayabildiği minimum yüzde. 0,33 ile 0,66 arasında olabilir. Sistemin sürükleme aralığını belirlemesine izin vermek için
DRAG_RANGE_SYSTEM_DEFAULT
olarak ayarlayın.
Kotlin
val splitAttributesBuilder: SplitAttributes.Builder = SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) if (WindowSdkExtensions.getInstance().extensionVersion >= 6) { splitAttributesBuilder.setDividerAttributes( DividerAttributes.DraggableDividerAttributes.Builder() .setColor(getColor(context, R.color.divider_color)) .setWidthDp(4) .setDragRange(DividerAttributes.DragRange.DRAG_RANGE_SYSTEM_DEFAULT) .build() ) } val splitAttributes: SplitAttributes = splitAttributesBuilder.build()
Java
SplitAttributes.Builder splitAttributesBuilder = new SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.33f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT); if (WindowSdkExtensions.getInstance().getExtensionVersion() >= 6) { splitAttributesBuilder.setDividerAttributes( new DividerAttributes.DraggableDividerAttributes.Builder() .setColor(ContextCompat.getColor(context, R.color.divider_color)) .setWidthDp(4) .setDragRange(DividerAttributes.DragRange.DRAG_RANGE_SYSTEM_DEFAULT) .build() ); } SplitAttributes splitAttributes = splitAttributesBuilder.build();
Etkinlik yığınını sabitleme
Etkinlik grubu sabitleme, kullanıcıların bölünmüş pencerelerden birini sabitlemelerini sağlar. Böylece kullanıcılar diğer pencerede gezinirken etkinlik olduğu gibi kalır. Etkinlik grubu sabitleme, gelişmiş bir çoklu görev deneyimi sunar.
Uygulamanızda etkinlik grubu sabitlemeyi etkinleştirmek için aşağıdakileri yapın:
Sabitlemek istediğiniz etkinliğin (ör. liste-ayrıntı düzeninin ayrıntı etkinliği) düzen dosyasına bir düğme ekleyin:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/detailActivity" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" tools:context=".DetailActivity"> <TextView android:id="@+id/textViewItemDetail" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="36sp" android:textColor="@color/obsidian" app:layout_constraintBottom_toTopOf="@id/pinButton" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/pinButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/pin_this_activity" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/textViewItemDetail"/> </androidx.constraintlayout.widget.ConstraintLayout>
Etkinliğin
onCreate()
yönteminde, düğmeye bir onclick dinleyici ayarlayın:Kotlin
pinButton = findViewById(R.id.pinButton) pinButton.setOnClickListener { val splitAttributes: SplitAttributes = SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.66f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build() val pinSplitRule = SplitPinRule.Builder() .setSticky(true) .setDefaultSplitAttributes(splitAttributes) .build() SplitController.getInstance(applicationContext).pinTopActivityStack(taskId, pinSplitRule) }
Java
Button pinButton = findViewById(R.id.pinButton); pinButton.setOnClickListener( (view) => { SplitAttributes splitAttributes = new SplitAttributes.Builder() .setSplitType(SplitAttributes.SplitType.ratio(0.66f)) .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT) .build(); SplitPinRule pinSplitRule = new SplitPinRule.Builder() .setSticky(true) .setDefaultSplitAttributes(splitAttributes) .build(); SplitController.getInstance(getApplicationContext()).pinTopActivityStack(getTaskId(), pinSplitRule); });
İletişim kutusu tam ekran loş
Etkinlikler genellikle bir iletişim kutusuna dikkat çekmek için ekranlarını karartır. Etkinlik yerleştirmede, birleşik bir kullanıcı arayüzü deneyimi için iletişim kutusunu açan etkinliği içeren bölmenin yanı sıra bölünmüş ekranın her iki bölmesi de karartılmalıdır.
WindowManager 1.4 ve sonraki sürümlerde, bir iletişim kutusu açıldığında uygulama penceresinin tamamı varsayılan olarak karartılır (EmbeddingConfiguration.DimAreaBehavior.ON_TASK
bölümüne bakın).
Yalnızca iletişim kutusunu açan etkinliğin kapsayıcısını karartmak için EmbeddingConfiguration.DimAreaBehavior.ON_ACTIVITY_STACK
simgesini kullanın.
Bölünmüş pencereden tam ekrana etkinlik çıkarma
Yan etkinliği tam pencerede gösteren yeni bir yapılandırma oluşturun ve ardından etkinliği aynı örneği çözen bir intent ile yeniden başlatın.
Çalışma zamanında bölünmüş destek olup olmadığını kontrol etme
Etkinlik yerleştirme, Android 12L (API düzeyi 32) ve sonraki sürümlerde desteklenir ancak önceki platform sürümlerini çalıştıran bazı cihazlarda da kullanılabilir. Özelliğin kullanılabilirliğini çalışma zamanında kontrol etmek için SplitController.splitSupportStatus
mülkünü veya SplitController.getSplitSupportStatus()
yöntemini kullanın:
Kotlin
if (SplitController.getInstance(this).splitSupportStatus == SplitController.SplitSupportStatus.SPLIT_AVAILABLE) { // Device supports split activity features. }
Java
if (SplitController.getInstance(this).getSplitSupportStatus() == SplitController.SplitSupportStatus.SPLIT_AVAILABLE) { // Device supports split activity features. }
Bölünmeler desteklenmiyorsa etkinlikler, etkinlik yığınının üstünde başlatılır (etkinlik dışı yerleştirme modeline göre).
Sistem geçersiz kılmayı önleme
Android cihaz üreticileri (özgün donanım üreticileri veya OEM'ler), etkinlik yerleştirmeyi cihaz sisteminin bir işlevi olarak uygulayabilir. Sistem, çok etkinli uygulamalar için bölme kurallarını belirtir ve uygulamaların pencereleme davranışını geçersiz kılar. Sistem geçersiz kılma işlemi, çok etkinli uygulamaları sistem tarafından tanımlanan bir etkinlik yerleştirme moduna zorlar.
Sistem etkinliği yerleştirme, uygulamada herhangi bir değişiklik yapmadan liste-ayrıntı gibi çok bölmeli düzenler aracılığıyla uygulama sunumunu iyileştirebilir. Ancak sistemin etkinlik yerleştirmesi, yanlış uygulama düzenleri, hatalara veya uygulama tarafından uygulanan etkinlik yerleştirmeyle çakışmalara da neden olabilir.
Uygulamanız, uygulama manifest dosyasında PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE
ayarını yaparak sistem etkinliğinin yerleştirilmesini engelleyebilir veya buna izin verebilir. Örneğin:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<property
android:name="android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE"
android:value="true|false" />
</application>
</manifest>
Mülk adı, Jetpack WindowManager WindowProperties
nesnesinde tanımlanır. Uygulamanız etkinlik yerleştirme özelliğini uyguluyorsa veya sistemin etkinlik yerleştirme kurallarını uygulamanıza uygulamasını önlemek istiyorsanız değeri false
olarak ayarlayın. Sistemin, sistem tanımlı etkinlik yerleştirme özelliğini uygulamanıza uygulamasına izin vermek için değeri true
olarak ayarlayın.
Sınırlamalar, kısıtlamalar ve uyarılar
- Yalnızca görevin ana etkinliğinin sahibi olarak tanımlanan, görevin ana uygulaması diğer etkinlikleri düzenleyip göreve yerleştirebilir. Yerleştirme ve bölme işlemlerini destekleyen etkinlikler farklı bir uygulamaya ait bir görevde çalıştırılıyorsa bu etkinliklerde yerleşme ve bölme işlemleri çalışmaz.
- Etkinlikler yalnızca tek bir görev içinde düzenlenebilir. Yeni bir görevde başlatılan etkinlikler her zaman mevcut bölmelerin dışında yeni ve genişletilmiş bir pencerede açılır.
- Yalnızca aynı süreçteki etkinlikler düzenlenebilir ve bölünebilir. Farklı işlemlerdeki etkinlikler hakkında bilgi edinmenin bir yolu olmadığından
SplitInfo
geri çağırma işlevi yalnızca aynı işleme ait etkinlikleri raporlar. - Her çift veya tek etkinlik kuralı yalnızca kuralın kaydedilmesinden sonra gerçekleşen etkinlik lansmanları için geçerlidir. Mevcut bölmelerin veya görsel özelliklerinin güncellenmesi şu anda mümkün değildir.
- Bölünmüş çift filtre yapılandırması, etkinlikler tamamen başlatılırken kullanılan intent'lerle eşleşmelidir. Eşleme, uygulama sürecinden yeni bir etkinliğin başlatıldığı noktada gerçekleşir. Bu nedenle, gizli intent'ler kullanıldığında sistem sürecinde daha sonra çözülen bileşen adlarını bilemez. Bir bileşen adı lansman sırasında bilinmiyorsa bunun yerine joker karakter ("*/*") kullanılabilir ve filtreleme, intent işlemine göre yapılabilir.
- Şu anda etkinlikleri kapsayıcılar arasında veya oluşturulduktan sonra bölmelere taşımak mümkün değildir. Bölünmeler yalnızca WindowManager kitaplığı tarafından, eşleşen kurallara sahip yeni etkinlikler başlatıldığında oluşturulur ve bölünmüş kapsayıcıdaki son etkinlik sona erdiğinde bölünmeler yok edilir.
- Yapılandırma değiştiğinde etkinlikler yeniden başlatılabilir. Bu nedenle, bir bölme oluşturulduğunda veya kaldırıldığında ve etkinlik sınırları değiştiğinde etkinlik, önceki örneğin tamamen yok edilmesi ve yenisinin oluşturulması işlemini gerçekleştirebilir. Bu nedenle, uygulama geliştiricileri yaşam döngüsü geri çağırmalarından yeni etkinlikler başlatma gibi konularda dikkatli olmalıdır.
- Cihazlar, etkinlik yerleştirmeyi desteklemek için pencere uzantıları arayüzünü içermelidir. Android 12L (API düzeyi 32) veya sonraki sürümleri çalıştıran neredeyse tüm büyük ekranlı cihazlarda bu arayüz bulunur. Ancak birden fazla etkinlik çalıştıramayan bazı büyük ekranlı cihazlarda pencere uzantıları arayüzü bulunmaz. Büyük ekranlı bir cihaz, çoklu pencere modunu desteklemiyorsa etkinlik yerleştirmeyi de desteklemeyebilir.
Ek kaynaklar
- Codelab'ler:
- Öğrenme rotası: Etkinlik yerleştirme
- Örnek uygulama: activity-embedding