將使用者介面轉移為回應式的版面配置

隨著大環境的裝置板型規格不斷擴大,Android 應用程式必須找出因應之道。應用程式的使用者介面必須要能支援各種螢幕大小、螢幕方向和裝置狀態。

回應式使用者介面著重在確保靈活性和連續性。

靈活性是指版面配置可充分運用空間,並在可用空間變更時進行調整。調整則可以有多種形式:單純調大單一檢視畫面的大小、重新調整檢視畫面的位置,使其更容易存取、顯示或隱藏其他檢視畫面,或上述功能的組合。

連續性是指在切換特定視窗大小時,能提供流暢的使用者體驗。無論使用者的參與體驗如何,前提是不能中斷。由於變更大小可能會導致整個檢視區塊階層被刪除 (然後再重新建立),因此請務必確保使用者不會因此變換了原本所在的畫面位置,或是失去自己的資料。

應避免的事項

避免根據實體、硬體的值來決定版面配置。您可能會根據固定的值做出決定,但在許多情況下,這些值並不代表使用者介面可以使用的空間。

在平板電腦中,應用程式可能會以多視窗模式執行,這表示可能會有兩個應用程式共用螢幕畫面;而在 ChromeOS 中,應用程式則可能會在可調整大小的視窗中執行。甚至可能會有多個實體螢幕,例如可折疊式裝置或具有多個螢幕的裝置。在這些情況下,實體螢幕的大小與決定如何顯示內容無關。

多部裝置顯示不同大小的應用程式視窗。
圖 1. 視窗大小可能因實體裝置或螢幕大小而異。

基於同樣的原因,請避免為應用程式採用固定的方向或顯示比例。雖然裝置本身可能有特定的方向,但應用程式可能會因裝置視窗大小而採用不同的方向。舉例來說,橫向的平板電腦在多個視窗模式下時,應用程式可能會以直向顯示,因為其高度大於寬度。

此外,也請避免判斷裝置是手機或平板電腦。 平板電腦具體的定義方式並無客觀標準:究竟是根據特定大小、長寬比,還是要綜合考量大小和長寬比?隨著板型規格推陳出新,這些假設很容易發生變化,因此這些區別也就不是那麼重要。

與其嘗試上述任何策略,不如改用中斷點和視窗大小類別。

中斷點和視窗大小類別

實際分配給應用程式的螢幕部分即為應用程式的視窗。它可以佔滿整個螢幕或部分螢幕,因此在為應用程式版面配置做出整體的決策時,請以視窗大小為依據。

在為多種板型規格進行設計時,請找出這類整體決策在各個方向的閾值。為此,您可以利用提供寬度和高度中斷點的 Material Design 回應式版面配置格線,將原始大小對應至獨立的標準化群組,也就是視窗大小類別。由於垂直捲動非常普遍,大多數應用程式主要考量的是寬度大小類別,因此只需處理幾個中斷點,就能針對各種螢幕大小進行最佳化。(如要進一步瞭解視窗大小類別,請參閱「支援不同的螢幕大小」。)

永久性 UI 元素

Material Design 版面配置指南定義了用於應用程式列、導覽和內容的區域。一般來說,前兩者屬於永久性的使用者介面元素,位於(或非常接近)檢視區塊階層的根層級。請注意,「永久性」不代表該檢視畫面會持續可見,而是指可以停留在某個地方,而其他內容檢視畫面可能會移動或改變。舉例來說,導覽元素可能位於螢幕畫面外的滑動導覽匣中,但導覽匣始終處於定位。

永久性元素可以是回應式元素,通常會占滿視窗的最大寬度或高度,因此建議使用大小類別決定這類元素的位置。這個做法可以劃定留給內容的顯示空間。在下列程式碼片段中,活動會在精簡版螢幕中使用底部列,並在較大的螢幕採用頂端應用程式列。符合資格的版面配置則使用寬度中斷點 (如前文所述)。

<!-- res/layout/main_activity.xml -->

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- content view(s) -->

    <com.google.android.material.bottomappbar.BottomAppBar
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        ... />
</androidx.constraintlayout.widget.ConstraintLayout>


<!-- res/layout-w600dp/main_activity.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        ... />

    <!-- content view(s) -->
</androidx.constraintlayout.widget.ConstraintLayout>

內容

將永久性的使用者介面元素定位好後,請將剩餘的空間供內容使用,例如使用 NavHostFragment 以及應用程式的導覽圖。其他注意事項請參閱回應式使用者介面的導覽

確保所有資料皆可用於各種尺寸

現今大多數的應用程式架構使用的資料模型,都與 UI 所屬 Android 元件 (活動、片段和檢視畫面) 分開使用。使用 Jetpack 時,這通常是透過 ViewModel 來完成,ViewModel 的另一項好處是,在設定變更後仍會保持不變 (詳情請參閱「ViewModel 總覽」一文)。

在實作可適應不同大小的版面配置時,您可能會很想根據目前的大小選用其他資料模型。然而,這與單向資料流程的原則背道而馳。資料應該要向下流向檢視畫面,使用者互動等事件則應向上流。在其他方向建立依附元件時,資料模型會取決於使用者介面層的設定,因此會大大增加複雜性。應用程式變更大小時,您必須把資料模型轉換成另一種資料模型。

反之,讓資料模型可容納最大的大小類別,然後選擇性地在使用者介面中顯示、隱藏或調整內容位置,以適應目前的大小類別。下列幾項策略可用來決定版面配置在大小類別轉換時的行為。

展開式內容

標準版面配置:動態饋給

可展開式空間可以讓內容放大及重新調整內容格式,使其更易於存取。

放大集合。 許多應用程式會在捲動容器中顯示一組項目,例如 RecyclerViewScrollView。啟用一個會自動放大的容器,表示可以顯示更多內容。但請注意容器中的內容不會被過度拉長或扭曲。舉例來說,在使用 RecyclerView 時,當寬度壓縮不夠時,可考慮使用其他版面配置管理工具,例如 GridLayoutManagerStaggeredGridLayoutManagerFlexboxLayout

裝置折疊及展開時,不同的版面配置管理工具根據寬度大小類別,以不同的方式排列應用程式。
圖 2. 針對不同的視窗大小類別使用不同的版面配置管理工具。

個別項目也可以使用不同的大小或形狀來顯示更多內容,這樣也能更容易區別項目的邊界。

強調主頁橫幅元素。 如果版面配置有特定的焦點(例如圖片或影片),當應用程式視窗變大時,可將其展開,以持續吸引使用者的注意力。其他輔助元素可重新安排在主頁橫幅檢視畫面周圍或下方。

建立這類版面配置的方法有很多種,但 ConstraintLayout 特別合適,因為這項方法可以用多種方式限制子檢視畫面的大小 (包括透過百分比或強制執行顯示比例),並可根據子檢視畫面或子項判定其他子項的相對位置。如要進一步瞭解這些功能,請參閱「使用 ConstraintLayout 建構回應式 UI」一文。

依預設顯示可收合的內容。如果有可用的空間,可顯示僅可透過使用者其他互動方式存取的內容(例如輕觸、捲動或手勢)。舉例來說,如果在壓縮時內容以分頁的介面顯示,當空間足夠時,可改以欄或清單的形式重新安排內容。

展開邊界。如果空間太大,即使已充分運用所有內容,仍無法找到適合的佈局,則可以展開版面配置的邊界,讓內容保持置中,每個檢視畫面有其自然大小,且彼此之間留有空間。

或者可將全螢幕元件轉換成浮動對話方塊使用者介面。如果元件需要專屬的聚焦以立即完成使用者的工作(例如撰寫電子郵件或建立日曆活動),就特別適合使用這個方法。

標準手機顯示全螢幕對話方塊,而展開的折疊式手機則以浮動視窗顯示相同的對話方塊。
圖 3. 全螢幕對話方塊在中型或展開的寬度下,轉換為標準對話方塊。

新增內容

標準版面配置:輔助窗格和清單詳細資料檢視畫面

使用輔助窗格。輔助窗格可顯示與主要內容相關的額外內容或關聯動作,例如文件中的留言或播放清單中的項目。一般而言,這些項目的展開高度為螢幕底部三分之一處,展開寬度則為尾端三分之一處。

請務必考量在空間不足以顯示窗格的情況下,這類內容應顯示在何處。以下提供幾種替代方案:

  • 使用 DrawerLayout 將其放置於結尾邊緣的導覽匣
  • 使用 BottomSheetBehavior 將其放置於底部導覽匣
  • 放置於可用輕觸選單圖示方式存取的選單或彈出式視窗
圖 4. 在輔助窗格展示額外內容的其他方式。

建立雙窗格版面配置。大螢幕可能可以一併顯示多項功能,這些功能在較小的螢幕上通常會分開顯示。許多應用程式常見的互動模式是顯示項目清單 (例如聯絡人或搜尋結果),並在使用者選取項目後,切換至該項目的詳細資料畫面。在較大的螢幕上,比起放大清單內容,應使用清單詳細資料檢視畫面,以雙窗格版面配置並排顯示兩項功能。不同於輔助窗格,清單詳細資料檢視畫面的詳細資料窗格是獨立的元素,可單獨顯示在較小的螢幕上。

請使用 SlidingPaneLayout 的專用小工具實作清單詳細資料檢視畫面。此小工具會根據兩個窗格指定的 layout_width 值,自動判斷是否有足夠的空間顯示兩個窗格,然後使用 layout_weight 來分配剩餘空間。如果沒有足夠的空間,每個窗格會使用版面配置的完整寬度,詳細資料窗格會從螢幕滑出或位於清單窗格頂端。

在具有寬螢幕的裝置中,SlidingPaneLayout 顯示清單/詳細資料版面配置的兩個窗格。
圖 5. SlidingPaneLayout 在展開寬度下顯示兩個窗格,並在精簡寬度下顯示一個窗格。

如要進一步瞭解如何使用 SlidingPaneLayout,請參閱「建立雙窗格版面配置」。另請注意,此模式可能會影響導覽圖的結構 (詳情請參閱「回應式 UI 導覽功能」)。

其他資源