未摺疊的大型螢幕和獨特的摺疊狀態能在 摺疊式裝置。如要為應用程式採用摺疊機制,請使用 Jetpack WindowManager 程式庫,提供摺疊式裝置視窗功能的 API 介面 例如摺疊和轉軸應用程式採用摺疊機制時,可調整版面配置 ,避免在摺疊或轉軸區域放置重要內容,並應使用摺疊畫面 以及轉軸做為自然分隔符
瞭解裝置是否支援桌面或書本等設定 防護機制可做為決定支援不同版面配置或提供 特定功能
視窗資訊
Jetpack WindowManager 的 WindowInfoTracker
介面可公開視窗版面配置資訊。此介面的 windowLayoutInfo()
方法會傳回一連串的 WindowLayoutInfo
資料,告知應用程式摺疊式裝置的摺疊狀態。WindowInfoTracker#getOrCreate()
方法會建立
WindowInfoTracker
例項。
WindowManager 支援使用 Kotlin 流程和 Java 回呼收集 WindowLayoutInfo
資料。
Kotlin 資料流
如要開始及停止WindowLayoutInfo
資料收集,請使用可重新啟動的可重新啟動
生命週期感知協同程式,其中 repeatOnLifecycle
程式碼區塊
會在生命週期至少為 STARTED
時執行,並在
生命週期為 STOPPED
。當生命週期再度為 STARTED
時,系統會自動重新開始執行程式碼區塊。在以下範例中,程式碼區塊會收集並使用 WindowLayoutInfo
資料:
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 回呼
回呼相容性層,包含在
androidx.window:window-java
依附元件可讓您收集
在不使用 Kotlin 資料流的情況下更新 WindowLayoutInfo
。構件包括
WindowInfoTrackerCallbackAdapter
類別,該類別會根據
WindowInfoTracker
用於支援註冊 (及取消註冊) 回呼
接收 WindowLayoutInfo
更新,例如:
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 支援
如果您已在使用 RxJava
(版本 2
或 3
),請善用可讓您使用 Observable
或 Flowable
的特定構件,以收集 WindowLayoutInfo
更新,無需使用 Kotlin 資料流。
androidx.window:window-rxjava2
和 androidx.window:window-rxjava3
依附元件提供的相容性層包含 WindowInfoTracker#windowLayoutInfoFlowable()
和 WindowInfoTracker#windowLayoutInfoObservable()
方法,可讓應用程式接收 WindowLayoutInfo
更新,例如:
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 of the WindowLayoutInfo observable.
disposable?.dispose()
}
}
折疊式裝置螢幕功能
Jetpack WindowManager 的 WindowLayoutInfo
類別可用 DisplayFeature
元素清單形式提供顯示視窗功能。
FoldingFeature
是一種 DisplayFeature
,可以提供資訊
有關摺疊式裝置螢幕的資訊,包括:
state
:裝置摺疊狀態,可為FLAT
或HALF_OPENED
orientation
:摺疊或轉軸方向,可為HORIZONTAL
或VERTICAL
isSeparating
:摺疊或轉軸是否會建立兩個邏輯顯示區域,可為 true 或 false
處於 HALF_OPENED
狀態的摺疊式裝置一律會將 isSeparating
回報為 true
因為螢幕會分割成兩個顯示區域此外,如果應用程式在雙螢幕裝置上橫跨兩個螢幕顯示,則 isSeparating
也會一律為 true。
FoldingFeature
bounds
屬性 (沿用自 DisplayFeature
)
代表摺疊或轉軸等摺疊功能的邊界矩形。
此界框可用來將元素放置在螢幕上相對於此功能的位置:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... lifecycleScope.launch(Dispatchers.Main) { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { // Safely collects from WindowInfoTracker 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<FoldingFeature>() .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. } } } }
桌面姿勢
應用程式可以使用 FoldingFeature
物件中包含的資訊,
支援多種型態,例如手機放在平面上,轉軸是
而摺疊式螢幕開著。
桌面型態可讓使用者在沒有手機的情況下操作手機 並握住手機桌面型態非常適合用來觀看媒體 拍攝相片和進行視訊通話。

使用 FoldingFeature.State
和 FoldingFeature.Orientation
判斷裝置是否處於桌面型態:
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); }
確認裝置處於桌面型態後,請更新應用程式版面配置 。以媒體應用程式來說,通常是指將播放內容放在 就 Android 裝置而言,摺疊以及放置控制項和補充內容 不必動手就能觀看或聆聽音樂。
在 Android 15 (API 級別 35) 以上版本中,您可以叫用同步 API,無論裝置目前的狀態為何,都能偵測裝置是否支援桌面模式。
API 會提供裝置支援的姿勢清單。如果清單 包含桌面型態,您可以分割應用程式版面配置來支援一種型態 ,並針對桌面和全螢幕版面配置,在應用程式 UI 上執行 A/B 版本測試。
Kotlin
if (WindowSdkExtensions.getInstance().extensionsVersion >= 6) { val postures = WindowInfoTracker.getOrCreate(context).supportedPostures if (postures.contains(TABLE_TOP)) { // Device supports tabletop posture. } }
Java
if (WindowSdkExtensions.getInstance().getExtensionVersion() >= 6) { List<SupportedPosture> postures = WindowInfoTracker.getOrCreate(context).getSupportedPostures(); if (postures.contains(SupportedPosture.TABLETOP)) { // Device supports tabletop posture. } }
範例
MediaPlayerActivity
應用程式:瞭解如何使用 Media3 Exoplayer 和 WindowManager 可製作採用摺疊機制的影片 廣告。使用 Jetpack WindowManager 最佳化適用於摺疊式裝置的相機應用程式程式碼研究室:瞭解如何實作攝影應用程式的桌面模式。節目 位於螢幕上半部 (不需捲動位置) 的觀景窗 控制按鈕 (位於需捲動位置)。
書本型態
另一種獨特的摺疊型態是書本型態,亦即裝置半開,轉軸為垂直方向。書本適合用來閱讀電子書。在大螢幕摺疊式裝置上利用雙頁版面配置閱讀書籍,呈現翻開實體精裝書的感觸。
此外,如果想使用免持方式拍攝不同顯示比例的相片,也可以使用這項功能。
實作書本型態時,採用的技術應與桌面型態相同。唯一的差別在於程式碼應檢查摺疊功能螢幕方向是否為垂直,而非水平:
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); }
視窗大小變化
應用程式的顯示區域可能會因為裝置設定而變更。 例如裝置處於摺疊、展開或旋轉狀態,或是視窗 我們在多視窗模式下重新調整大小。
Jetpack WindowManager WindowMetricsCalculator
類別可讓您:
擷取目前視窗指標和最大視窗指標。像平台一樣
WindowMetrics
是在 API 級別 30 中導入,WindowManager
WindowMetrics
提供視窗邊界,但 API 具有回溯相容性
降至 API 級別 14
請參閱「使用視窗大小類別」。
其他資源
範例
- Jetpack WindowManager:Jetpack 使用範例 WindowManager 程式庫
- Jetcaster:使用 Compose 實作桌面型態