必須呼叫 setLayoutParams() 才會觸發佈局更新。直接修改 getLayoutParams() 回傳物件的屬性 (如 width) 僅改變記憶體中的參數物件,**不會** 通知 ViewGroup 重新測量/佈局。
// ❌ 錯誤:修改後未 set,螢幕不會變
ViewGroup.LayoutParams params = view.getLayoutParams();
params.width = 300;
// ✅ 正確:修改後必須 set 回去
ViewGroup.LayoutParams params = view.getLayoutParams();
params.width = 300;
view.setLayoutParams(params); // 觸發 requestLayout()
public void setLayoutParams(ViewGroup.LayoutParams params) {
if (params == null) throw new IllegalArgumentException("LayoutParams cannot be null");
mLayoutParams = params; // 替換參考
resolveLayoutParams(); // 解析 Margin 等
requestLayout(); // 【關鍵】標記自身需重新佈局
invalidate(); // 觸發重繪
}
LinearLayout 時,必須用 LinearLayout.LayoutParams;用 ViewGroup.LayoutParams 會丟失 weight、gravity 等屬性。wrap_content / match_parent:需用 LayoutParams.WRAP_CONTENT / MATCH_PARENT 常數,不可寫死像素值。onCreate、按鈕點擊) 操作。public static void updateViewWidth(View view, int newWidthPx) {
ViewGroup.LayoutParams lp = view.getLayoutParams();
if (lp == null) return;
lp.width = newWidthPx;
view.setLayoutParams(lp);
}
public static void updateViewMarginLeft(View view, int marginPx) {
if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
mlp.leftMargin = marginPx;
view.setLayoutParams(mlp);
}
}
記住:**獲取 → 修改 → setLayoutParams()** 三步缺一不可。