在 Android 應用開發中,常見需求是:頁面頂部保留一個固定標題列或工具列,下方為可滑動的 ListView 或 RecyclerView。若直接將藍色 LinearLayout 放在 ListView 內部,它會隨著列表一起滑動,無法達到「吸頂」效果。本文提供兩種標準佈局架構解決此問題。
最簡單、效能最好的做法是:在根佈局中,將「固定區塊」與「可滑動列表」作為同層級的子元素,根容器使用垂直 LinearLayout 或 ConstraintLayout。
<LinearLayout
xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 固定不動的藍色標題區 -->
<LinearLayout
android:id="@+id/fixed_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#2196F3"
android:orientation="horizontal"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="固定標題"
android:textColor="#FFF"
android:textSize="18sp"/>
</LinearLayout>
<!-- 可滑動的列表區 -->
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
優點:結構清晰、無嵌套滑動衝突、效能最佳、支援所有 API 等級。
適用場景:固定區塊高度固定或自適應,不需隨列表內容動態伸縮。
若固定區塊「必須」放在某個 Tab 頁(Fragment)內部,且該 Tab 頁本身在 ViewPager 中,則不能直接用方案一(因固定區塊會隨 Tab 切換消失)。此時需在 Fragment 佈局中使用 CoordinatorLayout + AppBarLayout 實現 Material Design 滑動行為,或用 NestedScrollView 包裹列表。
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 固定標題,設定 scrollFlags 為 enterAlways 或 snap -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#2196F3"
app:layout_scrollFlags="scroll|enterAlways|snap"
android:orientation="vertical">
<TextView ... />
</LinearLayout>
</com.google.android.material.appbar.AppBarLayout>
<!-- 列表需支援巢狀滑動 (RecyclerView 原生支援,ListView 需 API 21+ 或設定 nestedScrollingEnabled) -->
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
注意:ListView 在舊版 Android 上不支援巢狀滑動,建議改用 RecyclerView。若必須用 ListView,可考慮方案一,將固定區提到 Activity 層級。
ListView 的 headerView 中——它會隨列表滑動。ScrollView 中直接嵌套 ListView——會導致滑動衝突且 ListView 只顯示一行。Toolbar 作為固定標題,直接設定 app:layout_scrollFlags="scroll|enterAlways" 即可輕鬆實現收縮/展開動畫。「固定頂部 + 可滑動列表」的核心原則是:固定區與滑動容器同層,或使用 CoordinatorLayout 協調滑動行為。方案一最通用、效能最好;方案二適用於複雜的 Material Design 交互場景。根據專案架構選擇即可。