ListView 內建支援空視圖(empty view),當適配器資料為空時自動顯示指定視圖,隱藏列表。關鍵在於正確設定 android:id="@android:id/empty"(注意 @android:id/ 前綴),而非自訂 ID。
<RelativeLayout
xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@android:id/list" <!-- 或自訂 id,但需在代碼 setEmptyView 關聯 -->
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- 空視圖:必須使用 android:id="@android:id/empty" -->
<TextView
android:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="暫無資料"
android:textSize="16sp"
android:textColor="#999" />
<ProgressBar
android:id="@+id/loadingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
ListView listView = findViewById(R.id.myListView);
View emptyView = findViewById(R.id.myEmptyView); // 自訂 ID
listView.setEmptyView(emptyView); // 手動關聯
| 錯誤寫法 | 現象 | 修正 |
|---|---|---|
android:id="@+id/empty" | 空視圖永不顯示或常駐顯示 | 改為 android:id="@android:id/empty" |
android:id="@id/android:empty" | 編譯錯誤或無效 | 同上 |
| 空視圖被 ListView 遮蓋 | ListView 背景不透明 | ListView 設 android:background="@null" 或調整層級 |
| Adapter 未設資料就判斷 | 初始化時閃現空視圖 | 在 setAdapter 後再設資料,或用 ViewStub 延遲載入 |
<LinearLayout
android:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="24dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/ic_empty_state" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="沒有找到相關內容"
android:textSize="16sp"
android:textColor="#666" />
<Button
android:id="@+id/btnRetry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="重新整理" />
</LinearLayout>
// Activity 中
Button btnRetry = findViewById(R.id.btnRetry);
btnRetry.setOnClickListener(v -> refreshData());
RecyclerView 無內建空視圖機制,需自行實作:
if (adapter.getItemCount() == 0) {
recyclerView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
} else {
recyclerView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
}
或使用 AdapterDataObserver 自動監聽:
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
updateEmptyView();
}
});
善用 ListView 內建空視圖機制,能以最少代碼實現完善的空狀態體驗。