2015-08-18 29 views
0

我試圖讓一個LinearLayout被添加到主Activity視圖時,按下按鈕。IllegalStateException當嘗試添加視圖()與複合視圖

注意之前試着用merge我用LinearLayout具有相同的結果。我讀了這post這使我的事情merge將幫助。我想添加的View的XML看起來像這樣。

<?xml version="1.0" encoding="utf-8"?> 
<merge xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="horizontal" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:id="@+id/grocery_list_row"> 

    <EditText 
     android:hint="Price" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

    <EditText 
     android:hint="Item" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 

    <CheckBox 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 
</merge> 

View化java看起來像這樣

package com.example.developer.grocerylist.impl; 

import android.content.Context; 
import android.util.AttributeSet; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.widget.LinearLayout; 

import com.example.developer.grocerylist.R; 

/** 
* Created by developer on 8/16/2015. 
*/ 
public class GroceryListTableRowImpl extends LinearLayout { 

    int mRows; 

    public GroceryListTableRowImpl(Context context) { 
     this(context, null); 
    } 

    public GroceryListTableRowImpl(Context context, AttributeSet attributeSet) { 
     super(context, attributeSet); 
    } 

    public GroceryListTableRowImpl(Context context, AttributeSet attributeSet, int defStyles) { 
     super(context, attributeSet, defStyles); 
    } 

    public void addRow(){ 
     mRows++; 
     removeAllViews(); 
     for(int i = 0; i < mRows; i++){ 
      addView(createRow()); 
     } 
    } 

    private View createRow() { 
     View v; 
     LayoutInflater inflater = LayoutInflater.from(getContext()); 
     v = inflater.inflate(R.layout.grocery_list_row,this,true); 
     return v; 
    } 
} 

主要Activity的XML看起來像這樣

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    tools:context=".GroceryList" 
    android:id="@+id/list_table"> 

    <com.example.developer.grocerylist.impl.GroceryListTableRowImpl 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/grocery_list"> 

    </com.example.developer.grocerylist.impl.GroceryListTableRowImpl> 


    <TableRow 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"> 
     <DigitalClock 
      android:textSize="20pt" 
      android:layout_height="wrap_content" 
      android:layout_width="fill_parent"/> 
    </TableRow> 

    <TableRow 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"> 
     <TextView 
      android:id="@+id/textview" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:minWidth="250px" 
      android:textSize="20pt" 
      android:paddingBottom="5px" 
      android:text="" 
      android:background="#777777" 
      android:textColor="#ff0000" /> 

     <Button 
      android:id="@+id/add" 
      android:text="add" /> 
    </TableRow> 
</TableLayout> 

最後主要Activity的Java

package com.example.developer.grocerylist.activities; 

import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TableLayout; 
import android.widget.TextView; 

import com.example.developer.grocerylist.R; 
import com.example.developer.grocerylist.api.GroceryListTableRow; 
import com.example.developer.grocerylist.impl.GroceryListTableRowImpl; 


public class GroceryList extends AppCompatActivity implements OnClickListener { 

    TextView textView = null; 
    GroceryListTableRowImpl groceryListTableRow = null; 
    Button add = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_grocery_list); 

     textView = (TextView)findViewById(R.id.textview); 
     groceryListTableRow = (GroceryListTableRowImpl)findViewById(R.id.grocery_list); 
     add = (Button)findViewById(R.id.add); 
     add.setOnClickListener(this); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_grocery_list, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onClick(View v) { 
     groceryListTableRow.addRow(); 
    } 
} 

當我啓動應用程序,並單擊該按鈕,我得到這個

Process: com.example.developer.grocerylist, PID: 2353 
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 
     at android.view.ViewGroup.addViewInner(ViewGroup.java:3936) 
     at android.view.ViewGroup.addView(ViewGroup.java:3786) 
     at android.view.ViewGroup.addView(ViewGroup.java:3727) 
     at android.view.ViewGroup.addView(ViewGroup.java:3700) 
     at com.example.developer.grocerylist.impl.GroceryListTableRowImpl.addRow(GroceryListTableRowImpl.java:34) 
     at com.example.developer.grocerylist.activities.GroceryList.onClick(GroceryList.java:61) 
     at android.view.View.performClick(View.java:4780) 
     at android.view.View$PerformClick.run(View.java:19866) 
     at android.os.Handler.handleCallback(Handler.java:739) 
     at android.os.Handler.dispatchMessage(Handler.java:95) 
     at android.os.Looper.loop(Looper.java:135) 
     at android.app.ActivityThread.main(ActivityThread.java:5257) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:372) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

我知道這是很多參加。我一直在抓我的頭就這一個。我以前從未做過複合視圖。這可能很明顯。任何幫助將不勝感激。提前致謝!

UPDATE調試時,當我到達​​行事情失敗。它似乎並沒有進入createRow()方法。

+0

'inflater.inflate'閱讀文檔。特別是布爾參數。 – njzk2

+0

查看文檔布爾值用於判斷是將新視圖連接到樹還是僅將父視圖用作佈局參數。我想將這個新行連接到'TableLayout',這就是爲什麼它是真實的。我錯過了什麼嗎? –

+1

然後您使用'addView'添加視圖,此時您會收到通知視圖已經有父視圖。使用'false'作爲參數,所以你可以自己在'addView'中添加它(在大多數情況下,這個參數是'false') – njzk2

回答

0

按我的觀察你的createRow()方法變化中,並嘗試這個東西

ViewGroup parent = (ViewGroup)v.Parent; 
return parent 

,因爲你已經使用合併有父ViewGroup中,所以要麼返回父視圖或刪除使用

parent.RemoveView(v); 
return v; 
0

感謝@ njkz2

什麼固定的這對我來說是改變我onCreate()方法。

private View createRow() { 
    View v; 
    LayoutInflater inflater = LayoutInflater.from(getContext()); 
    v = inflater.inflate(R.layout.grocery_list_row,this,false); 
    return v; 
} 

而且我改變類以擴展TableLayout而不是LinearLayout以獲得所需的效果。這是因爲我在我的GroceryListTableRowImpl中添加了複合視圖(這是一個LinearLayout)。所以GroceryListTableRowImpl需要是TableLayout

相關問題