首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android addView 自定義 View 不顯示:onCreate 添加、onWindowFocusChanged 測量寬高

     編輯:程式設計疑難解答

現象

  • onCreate 中 addView(customView) → 正常顯示。
  • onWindowFocusChanged 中 addView(customView) → 不顯示(寬高為 0)。

原因

onWindowFocusChanged 回調時,View 根佈局可能尚未完成佈局傳遞,customView 的 LayoutParams 未被正確解析,導致寬高為 0。

正確模式:分離「添加」與「測量」


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // 1. 先添加到容器
    container.addView(customView); // container 是 LinearLayout/FrameLayout 等
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        // 2. 此時 View 樹已佈局完成,可安全獲取寬高並設置
        int w = container.getWidth();
        int h = container.getHeight();
        customView.setLayoutParams(new ViewGroup.LayoutParams(w, h));
        // 或 customView.measure(...); customView.layout(...);
        customView.requestLayout(); // 觸發重繪
    }
}

關鍵點

  1. onCreate 添加:確保 View 進入 View 树,參與後續佈局流程。
  2. onWindowFocusChanged 只做尺寸調整:此時 getWidth()/getHeight() 已有效。
  3. 若自定義 View 內部依賴寬高(如 onSizeChanged 畫圖),必須在尺寸確定後調用 requestLayout() 或 invalidate()。

替代方案:onGlobalLayoutListener


viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        container.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        // 此處安全獲取寬高並設置 customView
    }
});

比 onWindowFocusChanged 更精準,不依賴焦點變化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved