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

Android 動態新增 RadioButton 導致「Child already has a parent」異常解決

     編輯:程式設計綜合問答

在 Android 程式碼中動態建立 RadioButton 並加入 RadioGroup 時,若錯誤地重複添加已存在於佈局中的 RadioGroup,會拋出「The specified child already has a parent」異常。

錯誤代碼分析

// XML 中已定義 RadioGroup
<RadioGroup android:id="@+id/rgc" ... ></RadioGroup>

// Java 代碼錯誤示範
RadioGroup rg = (RadioGroup) findViewById(R.id.rgc); // 獲取 XML 中已存在的 RadioGroup
// ... 建立 RadioButton 並加入 rg ...
LinearLayout l1 = (LinearLayout) findViewById(R.id.sl);
l1.addView(rg); // 錯誤:rg 已經有父視圖(XML 佈局),不能再次添加

錯誤原因

findViewById() 返回的是 XML 佈局中已實例化並掛載到視圖樹的 View 物件。這個 RadioGroup 已經有父容器(LinearLayout),再次調用 parent.addView(child) 會導致衝突。

解決方案

方案一:完全動態建立(推薦)

// 不在 XML 中定義 RadioGroup,完全由代碼建立
LinearLayout l1 = (LinearLayout) findViewById(R.id.sl);
RadioGroup rg = new RadioGroup(this); // 新建實例
rg.setOrientation(RadioGroup.VERTICAL);

RadioButton[] rb = new RadioButton[4];
for (int i = 0; i < 4; i++) {
    rb[i] = new RadioButton(this);
    rb[i].setLayoutParams(new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.WRAP_CONTENT, 
        LinearLayout.LayoutParams.WRAP_CONTENT));
    rb[i].setText(i + " 選項");
    rg.addView(rb[i]);
}

l1.addView(rg); // 只有這時才添加到父容器

方案二:XML 定義 RadioGroup,代碼只添加 RadioButton

// XML 保留 RadioGroup
// Java 代碼
RadioGroup rg = (RadioGroup) findViewById(R.id.rgc); // 直接使用,不要再 addView(rg)

for (int i = 0; i < 4; i++) {
    RadioButton rb = new RadioButton(this);
    rb.setText(i + " 選項");
    rg.addView(rb); // 只添加 RadioButton 到現有 RadioGroup
}
// 移除 l1.addView(rg) 這行

核心原則

  • 一個 View 同一時間只能有一個父容器
  • findViewById() 獲取的 View 已經在視圖樹中,不可再次添加
  • 動態建立 View 時,使用 new View(context) 創建新實例
  • 佈局參數 (LayoutParams) 必須匹配父容器類型

進階提示

若需動態移除並重新添加 View,必須先調用 parent.removeView(child) 再添加到新容器。

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