代碼中動態創建 RelativeLayout 和 ImageView,設置圖片資源並添加關係,但在模擬器運行後介面空白,圖片未顯示。
RelativeLayout relativeLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.freshface_mmm);
relativeLayout.addView(iv, lp);
// 缺少將 relativeLayout 添加到 Activity 視圖層級的代碼
RelativeLayout 並添加了 ImageView 作為其子 View,但未將 RelativeLayout 本身添加到任何父容器(如 setContentView() 的根 View、FrameLayout、或其他已掛載的 ViewGroup)。DecorView 開始遍歷視圖樹,未掛載的 View 及其子樹完全不會被測量、佈局、繪製。// 在 onCreate 中
RelativeLayout relativeLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, // 建議 MATCH_PARENT 填滿
RelativeLayout.LayoutParams.MATCH_PARENT
);
ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.freshface_mmm);
// 設置 ImageView 在 RelativeLayout 中居中
RelativeLayout.LayoutParams ivLp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
ivLp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
relativeLayout.addView(iv, ivLp);
// 關鍵:將 relativeLayout 設置為 Activity 的內容視圖
setContentView(relativeLayout, lp);
XML 佈局 activity_main.xml:
<FrameLayout
xmlns:android="https://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
// 在 onCreate 中
setContentView(R.layout.activity_main);
FrameLayout container = findViewById(R.id.container);
RelativeLayout relativeLayout = new RelativeLayout(this);
FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
);
ImageView iv = new ImageView(this);
iv.setImageResource(R.drawable.freshface_mmm);
RelativeLayout.LayoutParams ivLp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
ivLp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
relativeLayout.addView(iv, ivLp);
// 關鍵:添加到已掛載的容器中
container.addView(relativeLayout, flp);
addContentView(relativeLayout, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
));
注意:addContentView() 將 View 直接添加到 DecorView(根視圖),位於 setContentView() 設置的視圖之上,常用於對話框、彈窗等覆蓋層,不適合作為主介面容器。
| 方法 | 適用場景 | 注意事項 |
|---|---|---|
setContentView(View, LayoutParams) | 純代碼構建整個介面 | 會替換掉 XML 設置的視圖 |
container.addView(View, LayoutParams) | 動態添加到 XML 定義的容器 | 需確保 container 已掛載、ID 正確 |
addContentView(View, LayoutParams) | 添加全局覆蓋層(對話框、浮層) | 層級最高,不受 setContentView 影響 |
WRAP_CONTENT 可能導致顯示異常。ViewBinding 或 findViewById 獲取容器引用,避免硬編碼視圖層級。RecyclerView + Adapter 或 Fragment 管理子視圖生命週期。總結:動態創建的 View 必須顯式添加到已掛載的視圖樹中(通過 setContentView、container.addView 或 addContentView)才會顯示。缺少這一步是導致「代碼無錯但介面空白」的最常見原因。