Büyük, açılmış ekranlar ve benzersiz katlanmış durumlar, katlanabilir cihazlarda yeni kullanıcı deneyimlerine olanak tanır. Uygulamanızı katlanabilir hale getirmek için kıvrımlar ve menteşeler gibi katlanabilir cihaz penceresi özellikleri için API yüzeyi sağlayan Jetpack WindowManager kitaplığını kullanın. Uygulamanız katlanmaya duyarlı olduğunda düzeni, kıvrımlar veya menteşeler bulunan alanlara önemli içerik yerleştirmeyecek şekilde uyarlayabilir ve kıvrımları ve menteşeleri doğal ayırıcılar olarak kullanabilir.
Pencere bilgileri
Jetpack WindowManager'daki WindowInfoTracker
arayüzü, pencere düzeni bilgilerini gösterir. Arayüzün windowLayoutInfo()
yöntemi, katlanabilir cihazların katlanma durumu hakkında uygulamanızı bilgilendirmek için WindowLayoutInfo
veri akışı döndürür. WindowInfoTracker
getOrCreate()
yöntemi, WindowInfoTracker
öğesinin bir örneğini oluşturur.
WindowManager, Kotlin Akışları ve Java geri çağırmaları kullanarak WindowLayoutInfo
verilerini toplamak için destek sağlar.
Kotlin Akışları
WindowLayoutInfo
veri toplama işlemini başlatmak ve durdurmak için, yaşam döngüsü en az STARTED
olduğunda repeatOnLifecycle
kod bloğunun yürütüldüğü ve yaşam döngüsü STOPPED
olduğunda durdurulduğu yeniden başlatılabilir yaşam döngüsüne duyarlı bir eş yordam kullanabilirsiniz. Yaşam döngüsü tekrar STARTED
olduğunda kod bloğunun yürütülmesi otomatik olarak yeniden başlatılır. Aşağıdaki örnekte kod bloğu WindowLayoutInfo
verilerini toplayıp kullanır:
class DisplayFeaturesActivity : AppCompatActivity() {
private lateinit var binding: ActivityDisplayFeaturesBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDisplayFeaturesBinding.inflate(layoutInflater)
setContentView(binding.root)
lifecycleScope.launch(Dispatchers.Main) {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
WindowInfoTracker.getOrCreate(this@DisplayFeaturesActivity)
.windowLayoutInfo(this@DisplayFeaturesActivity)
.collect { newLayoutInfo ->
// Use newLayoutInfo to update the layout.
}
}
}
}
}
Java geri çağırma işlevleri
androidx.window:window-java
bağımlılığında yer alan geri çağırma uyumluluk katmanı, Kotlin Akışı kullanmadan WindowLayoutInfo
güncellemelerini toplamanızı sağlar. Yapı, WindowLayoutInfo
güncellemelerini almak için geri çağırmaları kaydetmek (ve kayıt iptallerini) desteklemek üzere bir WindowInfoTracker
uyarlayan WindowInfoTrackerCallbackAdapter
sınıfını içeriyor. Örneğin:
public class SplitLayoutActivity extends AppCompatActivity {
private WindowInfoTrackerCallbackAdapter windowInfoTracker;
private ActivitySplitLayoutBinding binding;
private final LayoutStateChangeCallback layoutStateChangeCallback =
new LayoutStateChangeCallback();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivitySplitLayoutBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
windowInfoTracker =
new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(this));
}
@Override
protected void onStart() {
super.onStart();
windowInfoTracker.addWindowLayoutInfoListener(
this, Runnable::run, layoutStateChangeCallback);
}
@Override
protected void onStop() {
super.onStop();
windowInfoTracker
.removeWindowLayoutInfoListener(layoutStateChangeCallback);
}
class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> {
@Override
public void accept(WindowLayoutInfo newLayoutInfo) {
SplitLayoutActivity.this.runOnUiThread( () -> {
// Use newLayoutInfo to update the layout.
});
}
}
}
RxJava desteği
RxJava
'ı (2
veya 3
sürümü) kullanıyorsanız Kotlin Akışı kullanmadan WindowLayoutInfo
güncellemeleri toplamak için Observable
veya Flowable
kullanmanızı sağlayan yapılardan yararlanabilirsiniz.
androidx.window:window-rxjava2
ve androidx.window:window-rxjava3
bağımlılıkları tarafından sağlanan uyumluluk katmanı, uygulamanızın WindowLayoutInfo
güncellemelerini almasını sağlayan WindowInfoTracker#windowLayoutInfoFlowable()
ve WindowInfoTracker#windowLayoutInfoObservable()
yöntemlerini içerir. Örneğin:
class RxActivity: AppCompatActivity {
private lateinit var binding: ActivityRxBinding
private var disposable: Disposable? = null
private lateinit var observable: Observable<WindowLayoutInfo>
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivitySplitLayoutBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Create a new observable
observable = WindowInfoTracker.getOrCreate(this@RxActivity)
.windowLayoutInfoObservable(this@RxActivity)
}
@Override
protected void onStart() {
super.onStart();
// Subscribe to receive WindowLayoutInfo updates
disposable?.dispose()
disposable = observable
.observeOn(AndroidSchedulers.mainThread())
.subscribe { newLayoutInfo ->
// Use newLayoutInfo to update the layout
}
}
@Override
protected void onStop() {
super.onStop();
// Dispose the WindowLayoutInfo observable
disposable?.dispose()
}
}
Katlanabilir ekranların özellikleri
Jetpack WindowManager'ın WindowLayoutInfo
sınıfı, görüntüleme penceresinin özelliklerini DisplayFeature
öğelerinin bir listesi olarak kullanılabilir hale getirir.
FoldingFeature
, aşağıdakiler de dahil olmak üzere katlanabilir ekranlarla ilgili bilgi sağlayan bir DisplayFeature
türüdür:
state
: Cihazın katlanmış durumu,FLAT
veyaHALF_OPENED
orientation
: Katlama veya menteşenin yönü,HORIZONTAL
ya daVERTICAL
occlusionType
: Kıvrımın veya menteşenin ekranın bir kısmını gizleyip kapatmayacağı,NONE
veyaFULL
isSeparating
: Ekranın veya menteşenin doğru ve yanlış olmak üzere iki mantıksal görüntüleme alanı oluşturup oluşturmadığı
HALF_OPENED
özelliği olan katlanabilir cihazlar, ekran iki görüntüleme alanına ayrıldığından isSeparating
değerini her zaman doğru olarak bildirir. Ayrıca, uygulama her iki ekranı da kapsıyorsa isSeparating
, çift ekranlı cihazlarda her zaman geçerlidir.
FoldingFeature
bounds
özelliği (DisplayFeature
kaynağından devralınır), katlama veya menteşe gibi katlama özelliğinin sınırlayıcı dikdörtgenini temsil eder. Sınırlar, ekrandaki öğeleri özelliğe göre konumlandırmak için kullanılabilir.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { // Safely collects from windowInfoRepo when the lifecycle is STARTED // and stops collection when the lifecycle is STOPPED WindowInfoTracker.getOrCreate(this@MainActivity) .windowLayoutInfo(this@MainActivity) .collect { layoutInfo -> // New posture information val foldingFeature = layoutInfo.displayFeatures .filterIsInstance() .firstOrNull() // Use information from the foldingFeature object } } } }
Java
private WindowInfoTrackerCallbackAdapter windowInfoTracker; private final LayoutStateChangeCallback layoutStateChangeCallback = new LayoutStateChangeCallback(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { ... windowInfoTracker = new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(this)); } @Override protected void onStart() { super.onStart(); windowInfoTracker.addWindowLayoutInfoListener( this, Runnable::run, layoutStateChangeCallback); } @Override protected void onStop() { super.onStop(); windowInfoTracker.removeWindowLayoutInfoListener(layoutStateChangeCallback); } class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> { @Override public void accept(WindowLayoutInfo newLayoutInfo) { // Use newLayoutInfo to update the Layout List<DisplayFeature> displayFeatures = newLayoutInfo.getDisplayFeatures(); for (DisplayFeature feature : displayFeatures) { if (feature instanceof FoldingFeature) { // Use information from the feature object } } } }
Masa üstü modu
Uygulamanız, FoldingFeature
nesnesindeki bilgileri kullanarak masaüstü modu,
Telefon bir yüzeyde duruyor, menteşe yatay konumda ve katlanabilir ekran yarı açık.
Masa üstü modu, kullanıcılara telefonlarını tabletleri kullanmadan elinde tutmuştu. Masa üstü modu medya izlemek, fotoğraf çekmek ve görüntülü görüşme yapmak için idealdir.
FoldingFeature.State
kullanın
ve FoldingFeature.Orientation
cihazın masaüstü modunda olup olmadığını belirlemek için:
Kotlin
fun isTableTopPosture(foldFeature : FoldingFeature?) : Boolean { contract { returns(true) implies (foldFeature != null) } return foldFeature?.state == FoldingFeature.State.HALF_OPENED && foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL }
Java
boolean isTableTopPosture(FoldingFeature foldFeature) { return (foldFeature != null) && (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) && (foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL); }
Cihazın masaüstü moduna geçtiğinden emin olduktan sonra uygulama düzeninizi buna göre güncelleyin. Medya uygulamaları için bu, genellikle oynatmayı ekranın üst kısmına yerleştirmek ve Hemen alt kısımda yer alan konumlandırma kontrolleri ve ek içerikler, ellerinizi kullanmadan izleme veya dinleme deneyimi sunar.
Örnekler
MediaPlayerActivity
uygulaması: Media3 Exoplayer'ın nasıl kullanılacağına ve Katlanabilir video oynatıcı oluşturmak için WindowManager'ı tıklayın.Kamera deneyiminizi açın codelab: Fotoğraf uygulamaları için masaüstü modunu nasıl uygulayacağınızı öğrenin. Vizörü ekranın üst yarısında, ekranın üst kısmında ve alt yarısındaki kontrolleri ekranın alt kısmında gösterin.
Rezervasyon modu
Bir başka benzersiz katlanabilir duruş da cihazın yarım açık olduğu kitap modudur. menteşesi ise dikey. Kitap modu, e-kitap okumak için idealdir. İki sayfalık büyük ekranda, bağlı kitap gibi açılabilir katlanabilir ekran düzeni; kitap modu ile deneyimi yakalar bir deneyim olduğunu düşünüyorum.
Ellerinizi kullanmadan fotoğraf çekerken farklı en boy oranları yakalamak istiyorsanız, fotoğraf için de kullanılabilir.
Kitap modunu, masa üstü modu için kullanılan tekniklerle uygulayın. Tek fark kodunun, katlama özelliğinin yönünün yatay yerine dikey olup olmadığını kontrol etmesi gerekir:
Kotlin
fun isBookPosture(foldFeature : FoldingFeature?) : Boolean { contract { returns(true) implies (foldFeature != null) } return foldFeature?.state == FoldingFeature.State.HALF_OPENED && foldFeature.orientation == FoldingFeature.Orientation.VERTICAL }
Java
boolean isBookPosture(FoldingFeature foldFeature) { return (foldFeature != null) && (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) && (foldFeature.getOrientation() == FoldingFeature.Orientation.VERTICAL); }
Pencere boyutu değişiklikleri
Cihaz yapılandırmasında yapılan bir değişiklik nedeniyle uygulamanın görüntüleme alanı değişebilir. Örneğin, cihaz katlanmışsa veya açılmışsa, döndürüldüğünde ya da çoklu pencere modunda bir pencere yeniden boyutlandırıldığında.
Jetpack WindowManager WindowMetricsCalculator
sınıfı, geçerli ve maksimum pencere metriklerini almanızı sağlar. API düzeyi 30'da kullanıma sunulan platform WindowMetrics
gibi WindowManager WindowMetrics
pencere sınırlarını sağlar ancak API, API düzeyi 14'e kadar geriye dönük uyumludur.
Pencere boyutu sınıfları başlıklı makaleyi inceleyin.
Ek kaynaklar
Örnekler
- Jetpack WindowManager: Jetpack WindowManager kitaplığının nasıl kullanılacağını gösteren örnek
- Jetcaster: Compose ile masa üstünde duruş uygulaması
Codelab'ler
- Jetpack WindowManager ile katlanabilir ve çift ekranlı cihazları destekleme
- Kamera deneyiminizi açın
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Jetpack WindowManager ile katlanabilir ve çift ekranlı cihazları destekleme
- Jetpack WindowManager ile katlanabilir cihazlarda kamera uygulamanızı optimize etme
- Cihaz uyumluluk modu