只要在搭載 Android 15 以上版本的裝置中指定 SDK 35 以上版本,您的應用程式就會顯示無邊框設計。視窗會在系統資訊列後方繪製,橫跨整個螢幕的寬度和高度。系統列包括狀態列、說明文字列和導覽列
許多應用程式都有頂端應用程式列。頂端應用程式列應延伸至螢幕頂端邊緣,並顯示在狀態列後方。您可以選擇在內容捲動時,將頂端應用程式列縮小為狀態列的高度。
許多應用程式也有底部應用程式列或底部導覽列。這些列也應延伸至畫面底部邊緣,並顯示在導覽列後方。否則,應用程式應在導覽列後方顯示捲動內容。
在應用程式中實作無邊框版面配置時,請注意下列事項:
- 啟用無邊框螢幕
- 處理任何視覺重疊問題。
- 建議你在系統資訊列後方顯示剪裁。
啟用無邊框顯示
如果應用程式指定目標為 SDK 35 以上版本,系統會自動為 Android 15 以上版本的裝置啟用無邊框畫面。
如要在先前的 Android 版本中啟用無邊框功能,請按照下列步驟操作:
請在應用程式或模組的
build.gradle
檔案中,將依附元件新增至androidx.activity
程式庫:Kotlin
dependencies { val activity_version =
activity_version
// Java language implementation implementation("androidx.activity:activity:$activity_version") // Kotlin implementation("androidx.activity:activity-ktx:$activity_version") }Groovy
dependencies { def activity_version =
activity_version
// Java language implementation implementation 'androidx.activity:activity:$activity_version' // Kotlin implementation 'androidx.activity:activity-ktx:$activity_version' }將
enableEdgeToEdge
擴充功能函式匯入應用程式:
在 Activity
的 onCreate
中呼叫 enableEdgeToEdge
,即可手動啟用無邊框顯示。請在 setContentView
之前呼叫這個方法。
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) ... }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { EdgeToEdge.enable(this); super.onCreate(savedInstanceState); ... }
根據預設,enableEdgeToEdge()
會將系統列設為透明,但在 3 鍵導覽模式下,狀態列會變成半透明的遮罩。系統圖示和薄板的顏色會根據系統淺色或深色主題進行調整。
enableEdgeToEdge()
函式會自動宣告應用程式應採用無邊框設計,並調整系統資訊列的顏色。
如要在應用程式中啟用無邊框顯示,但不使用 enableEdgeToEdge()
函式,請參閱「手動設定無邊框顯示」。
使用內嵌處理重疊
部分應用程式檢視畫面可能會繪製在系統列後方,如圖 3 所示。
您可以回應插邊來解決重疊問題,指定畫面的哪些部分與系統 UI 交集,例如導覽列或狀態列。互動表示在內容上方顯示,但也可以讓應用程式瞭解系統手勢。
適用於邊到邊顯示應用程式的內嵌類型如下:
系統資訊列插邊:最適合可輕觸且不得被系統資訊列遮擋的檢視畫面。
螢幕凹口插邊:如果出現因裝置形狀而有螢幕凹口的區域,
系統手勢內嵌:系統使用的手勢導覽區域,優先於應用程式。
系統列內嵌
系統列插邊是最常用的插邊類型,這些區域代表系統 UI 在應用程式上方 Z 軸顯示的區域。這些區域最適合用於移動或填充應用程式中的可點選檢視畫面,且不得讓系統列遮蔽檢視畫面。
例如,圖 3 中的懸浮動作按鈕 (FAB) 遭到導覽列的部分內容遮蓋:
如要在手勢模式或按鈕模式中避免這種視覺重疊情形,您可以使用 getInsets(int)
搭配 WindowInsetsCompat.Type.systemBars()
增加檢視畫面的邊界。
以下程式碼範例說明如何實作系統列內嵌:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) // Apply the insets as a margin to the view. This solution sets // only the bottom, left, and right dimensions, but you can apply whichever // insets are appropriate to your layout. You can also update the view padding // if that's more appropriate. v.updateLayoutParams<MarginLayoutParams> { leftMargin = insets.left, bottomMargin = insets.bottom, rightMargin = insets.right, } // Return CONSUMED if you don't want want the window insets to keep passing // down to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // Apply the insets as a margin to the view. This solution sets only the // bottom, left, and right dimensions, but you can apply whichever insets are // appropriate to your layout. You can also update the view padding if that's // more appropriate. MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams(); mlp.leftMargin = insets.left; mlp.bottomMargin = insets.bottom; mlp.rightMargin = insets.right; v.setLayoutParams(mlp); // Return CONSUMED if you don't want want the window insets to keep passing // down to descendant views. return WindowInsetsCompat.CONSUMED; });
如果您將這項解決方案套用至圖 3 所示的範例,按鈕模式就不會發生視覺重疊,如圖 4 所示:
這也適用於手勢操作模式,如圖 5 所示:
顯示螢幕凹口內嵌
部分裝置配備螢幕凹口。通常,裁切區會位於螢幕頂端,並包含在狀態列中。裝置螢幕處於橫向模式時,螢幕邊緣可能會出現缺口。視應用程式在畫面上顯示的內容而定,您應該實作邊框間距,避免顯示螢幕凹口。根據預設,應用程式會在螢幕凹口中繪製。
舉例來說,許多應用程式畫面都會顯示項目清單。請勿讓螢幕缺口或系統列遮蓋清單項目。
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets -> val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() ) v.updatePadding( left = bars.left, top = bars.top, right = bars.right, bottom = bars.bottom, ) WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> { Insets bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() ); v.setPadding(bars.left, bars.top, bars.right, bars.bottom); return WindowInsetsCompat.CONSUMED; });
請取用系統資訊列和螢幕凹口類型的邏輯「或」,判斷 WindowInsetsCompat
的值。
將 clipToPadding
設為 RecyclerView
,讓邊框與清單項目一起捲動。這樣一來,使用者捲動畫面時,系統資訊列後方就會顯示項目,如以下範例所示。
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
系統手勢內嵌
系統手勢內嵌表示視窗的哪些區域系統手勢優先於應用程式。這些區域在圖 6 中以橘色標示:
如同系統資訊列插邊,您可以搭配使用 getInsets(int)
和 WindowInsetsCompat.Type.systemGestures()
,避免重疊系統手勢插邊。
使用這些內嵌,將可滑動的檢視區塊移離邊緣或加寬邊緣。常見的用途包括底部功能表、遊戲中的清除功能,以及使用 ViewPager2
實作的輪轉介面。
在 Android 10 以上版本中,系統手勢插邊包含主畫面手勢的底部插邊,以及返回手勢的左右插邊:
以下程式碼範例說明如何實作系統手勢內嵌:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.updatePadding(insets.left, insets.top, insets.right, insets.bottom) // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()); // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.setPadding(insets.left, insets.top, insets.right, insets.bottom); // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. return WindowInsetsCompat.CONSUMED; });
Material Design 元件
許多以 View 為基礎的 Android Material 元件 (com.google.android.material){:.external} 會自動處理插邊,包括 BottomAppBar
、BottomNavigationView
、NavigationRailView
和 NavigationView
不過,AppBarLayout
不會自動處理內嵌區塊。新增 android:fitsSystemWindows="true"
來處理頂端插邊。
瞭解如何使用 Compose 中的 Material 元件處理插邊。
沉浸模式
某些內容最適合以全螢幕模式觀看,可為使用者提供更身歷其境的體驗。您可以使用 WindowInsetsController
和 WindowInsetsControllerCompat
程式庫,在沉浸模式下隱藏系統資訊列:
Kotlin
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) // Hide the system bars. windowInsetsController.hide(Type.systemBars()) // Show the system bars. windowInsetsController.show(Type.systemBars())
Java
Window window = getWindow(); WindowInsetsControllerCompat windowInsetsController = WindowCompat.getInsetsController(window, window.getDecorView()); if (windowInsetsController == null) { return; } // Hide the system bars. windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); // Show the system bars. windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
如要進一步瞭解如何實作這項功能,請參閱「在沉浸模式下隱藏系統資訊列」。
系統資訊列保護功能
應用程式指定目標為 SDK 35 以上版本後,系統會強制執行無邊框設計。系統狀態列和手勢導覽列呈現透明狀態,但三按鈕導覽列呈現透明狀態。
如要移除預設的半透明三按鈕操作模式背景保護措施,請將 Window.setNavigationBarContrastEnforced
設為 false
。
其他資源
如要進一步瞭解 WindowInsets
、手勢操作和插邊的運作方式,請參閱以下參考資料: