Joe Yearsley Joe Yearsley - 23 days ago 4
Android Question

Android App telling me to to remove my child view from parent, I'm not adding it to another view though

06-11 15:55:30.911 935-935/com.example.myfirstapp E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myfirstapp/com.example.myfirstapp.DbQueries}: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: 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:3339)
at android.view.ViewGroup.addView(ViewGroup.java:3210)
at android.view.ViewGroup.addView(ViewGroup.java:3155)
at android.view.ViewGroup.addView(ViewGroup.java:3131)
at com.example.myfirstapp.DbQueries$PlanetFragment.onCreateView(DbQueries.java:256)
at android.app.Fragment.performCreateView(Fragment.java:1695)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
at android.app.BackStackRecord.run(BackStackRecord.java:682)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
at android.app.Activity.performStart(Activity.java:5113)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2153)


Above is the log cat, Below is the code in question (not entire code) :

public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_planet, container, false);
int i = getArguments().getInt(ARG_PLANET_NUMBER);
// get a reference for the TableLayout

TableLayout layout = (TableLayout) rootView.findViewById(R.id.table);

// create a new TableRow
TableRow row = new TableRow(getActivity());
// create a new TextView for showing xml data
TextView t = new TextView(getActivity());
TextView n = new TextView(getActivity());
// set the text to "text xx"
// DataBaseHelper R = new DataBaseHelper(getActivity());
//R.createDataBase();
//int x = R.getRecordsCount();
DatabaseHandler db = new DatabaseHandler(getBaseContext());

/**
* CRUD Operations
* */
// Inserting Contacts
Log.d("Insert: ", "Inserting ..");
db.addContact(new Contact(94020, "I","L/PNRD TORSKFILE MSC",25956,"I2368540",23));

// Reading all contacts
Log.d("Reading: ", "Reading all contacts..");
List<Contact> contacts = db.getAllContacts();

//for (Contact cn : contacts) {
// String log = "Id: "+cn.getID()+" ,Name: " + cn.getID() + " ,Phone: " + cn.getPC();
// Writing Contacts to log
// Log.d("Name: ", log);
//}

if (i == 0){
for (Contact cn : contacts) {
String s = String.valueOf(cn.getID());
t.setText("s");
t.setPadding(10,10,10,10);
n.setText("d");
n.setPadding(10,10,10,10);

// add the TextView to the new TableRow
row.addView(t);
row.addView(n);}}
else{
t.setText("!(Query 1)");
t.setPadding(10,10,10,10);
n.setText("Bye");
n.setPadding(10,10,10,10);
// add the TextView to the new TableRow
row.addView(t);
row.addView(n);}


// add the TableRow to the TableLayout

layout.addView(row,new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT));


getActivity().setTitle("DataBase View Area");
return rootView;
}


And the Handler :

package com.example.myfirstapp;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.util.ArrayList;
import java.util.List;

/**
* Created by josephyearsley on 11/06/2013.
*/
public class DatabaseHandler extends SQLiteOpenHelper {

// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;

// Database Name
private static final String DATABASE_NAME = "contactsManager";

// Contacts table name
private static final String TABLE_CONTACTS = "contacts";

// Contacts Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_PID = "pallet_id";
private static final String KEY_DESC = "description";
private static final String KEY_FREEQTY = "free_qty";
private static final String KEY_PRODCODE = "product_code";
private static final String KEY_ACCOUNT = "account";
private static final String KEY_DEPOT = "depot";


public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_ACCOUNT + " INTEGER,"
+ KEY_DEPOT + " TEXT," + KEY_DESC + " TEXT,"
+ KEY_PRODCODE + " INTEGER," + KEY_PID + " TEXT,"
+ KEY_FREEQTY + " INTEGER" +
")";
db.execSQL(CREATE_CONTACTS_TABLE);
}

// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);

// Create tables again
onCreate(db);
}

/**
* All CRUD(Create, Read, Update, Delete) Operations
*/

// Adding new contact
void addContact(Contact contact) {
SQLiteDatabase db = this.getWritableDatabase();

ContentValues values = new ContentValues();
values.put(KEY_ACCOUNT, contact.getAccount()); // Contact Name
values.put(KEY_DEPOT, contact.getDep());
values.put(KEY_DESC, contact.getDesc());
values.put(KEY_PRODCODE, contact.getPC());
values.put(KEY_PID, contact.getpID());
values.put(KEY_FREEQTY, contact.getFreeQTY());
// Inserting Row
db.insert(TABLE_CONTACTS, null, values);
db.close(); // Closing database connection
}

// Getting single contact
Contact getContact(int id) {
SQLiteDatabase db = this.getReadableDatabase();

Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
KEY_DEPOT, KEY_ACCOUNT, KEY_PRODCODE, KEY_DESC, KEY_FREEQTY, KEY_PID }, KEY_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();

Contact contact = new Contact(Integer.parseInt(cursor.getString(0)),
Integer.parseInt(cursor.getString(1)),cursor.getString(2), cursor.getString(3),
Integer.parseInt(cursor.getString(4)),cursor.getString(5),Integer.parseInt(cursor.getString(6)));
// return contact
return contact;
}

// Getting All Contacts
public List<Contact> getAllContacts() {
List<Contact> contactList = new ArrayList<Contact>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_CONTACTS;

SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);

// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Contact contact = new Contact();
contact.setID(Integer.parseInt(cursor.getString(0)));
contact.setAccount(Integer.parseInt(cursor.getString(1)));
contact.setDep(cursor.getString(2));
contact.setDesc(cursor.getString(3));
contact.setPC(Integer.parseInt(cursor.getString(4)));
contact.setPID(cursor.getString(5));
contact.setFreeQTY(Integer.parseInt(cursor.getString(6)));

// Adding contact to list
contactList.add(contact);
} while (cursor.moveToNext());
}

// return contact list
return contactList;
}

// Updating single contact
public int updateContact(Contact contact) {
SQLiteDatabase db = this.getWritableDatabase();

ContentValues values = new ContentValues();
values.put(KEY_ACCOUNT, contact.getAccount());
values.put(KEY_DEPOT, contact.getDep());
values.put(KEY_DESC, contact.getDesc());
values.put(KEY_PRODCODE, contact.getPC());
values.put(KEY_PID, contact.getpID());
values.put(KEY_FREEQTY, contact.getFreeQTY());

// updating row
return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",
new String[] { String.valueOf(contact.getID()) });
}

// Deleting single contact
public void deleteContact(Contact contact) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_CONTACTS, KEY_ID + " = ?",
new String[] { String.valueOf(contact.getID()) });
db.close();
}


// Getting contacts Count
public int getContactsCount() {
String countQuery = "SELECT * FROM " + TABLE_CONTACTS;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
cursor.close();

// return count
return cursor.getCount();
}

}


And the CRUD:

package com.example.myfirstapp;

/**
* Created by josephyearsley on 11/06/2013.
*/
public class Contact {

//private variables
int _id;
String _palletID;
int _freeQty;
String _description;
int _product_code;
int _account;
String _depot;


// Empty constructor
public Contact(){

}
// constructor
public Contact(int id,int account,String depot, String description,int pc,String pID,int freeQty ){
this._account = account;
this._palletID = pID;
this._freeQty = freeQty;
this._description=description;
this._product_code = pc;
this._depot = depot;
this._id = id;

}

// constructor
public Contact(int account,String depot, String description,int pc,String pID,int freeQty ){
this._account = account;
this._palletID = pID;
this._freeQty = freeQty;
this._description=description;
this._product_code = pc;
this._depot = depot;

}
// getting ID
public int getID(){
return this._id;
}

// setting id
public void setID(int id){
this._id = id;
}

// getting name
public int getPC(){
return this._product_code;
}

// setting name
public void setPC(int pc){
this._product_code = pc;
}
// getting name
public int getAccount(){
return this._account;
}

// setting name
public void setAccount(int account){
this._account = account;
}

// getting name
public String getpID(){
return this._palletID;
}

// setting name
public void setPID(String Pallet){
this._palletID = Pallet;
}

// getting name
public int getFreeQTY(){
return this._freeQty;
}

// setting name
public void setFreeQTY(int freeQTY){
this._freeQty = freeQTY;
}
// getting phone number
public String getDesc(){
return this._description;
}

// setting phone number
public void setDesc(String Desc){
this._description = Desc;
}
// getting phone number
public String getDep(){
return this._depot;
}

// setting phone number
public void setDep(String Dep){
this._depot = Dep;
}
}


Basically, I'm confused as to why it's telling me to remove the view from its parent as I'm trying to loop round the returned list inserting the values from the lines into a table.
Can someone please explain why my code isn't working and either how to fix it or a better standard of doing it, as I'm new to android programming.

Answer

Can someone please explain why my code isn't working

You create the n and t TextView widgets outside the loop, then repeatedly call addView() to add them to the row inside the loop. Hence, on the second pass of the loop, the children already have a parent (from the addView() calls in the first pass of the loop), and you get your exception.

Assuming the loop itself is otherwise correct (and that's more tied to your desired UI and business logic), you need to create fresh TextView widgets on each pass of the loop.