Reputation: 39
I'm creating a small app in which you can add or delete a table row by button click. Whenever I click the "add line" button, the button adds a table row to the layout and does what it's supposed to do. However, the "delete line" doesn't remove the the newly added table row, but it does decrement (int count) like it's supposed to. I've worked and searched on it for about 4 to 5 hours now and I'm having no luck. Here's the code:
int count = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonAdd = (Button) findViewById(R.id.button1);
Button buttonDel = (Button) findViewById(R.id.button2);
buttonAdd.setOnClickListener(this);
buttonDel.setOnClickListener(this);
}
public void onClick(View v) {
TableLayout tableLayout1;
EditText editText1;
EditText editText2;
TableRow tempRow;
EditText tempText1;
EditText tempText2;
TableRow tableRow1;
tableLayout1 = (TableLayout) findViewById(R.id.tableLayout1);
editText1 = (EditText) findViewById(R.id.editText1);
editText2 = (EditText) findViewById(R.id.editText2);
tempRow = new TableRow(MainActivity.this);
tempText1 = new EditText(MainActivity.this);
tempText2 = new EditText(MainActivity.this);
tempText1.setInputType(InputType.TYPE_CLASS_TEXT);
tempText2.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
tableRow1 = (TableRow) findViewById(R.id.tableRow1);
tempRow.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
tempText1.setLayoutParams(editText1.getLayoutParams());
tempText2.setLayoutParams(editText2.getLayoutParams());
switch(v.getId()){
case R.id.button1:
if(count != 9){
count++;
tempRow.addView(tempText1);
tempRow.addView(tempText2);
tableLayout1.addView(tempRow);
} else {
final AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create(); //Read Update
alertDialog.setTitle("Error");
alertDialog.setMessage("You can only have 10 rows!");
alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
}
});
alertDialog.show();
}
break;
case R.id.button2:
if(count != 0){
count--;
tempRow.removeView(tempText1);
tempRow.removeView(tempText2);
tableLayout1.removeView(tempRow);
//tableLayout1.invalidate();
} else {
final AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create(); //Read Update
alertDialog.setTitle("Error");
alertDialog.setMessage("You must have at least one row!");
alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
}
});
alertDialog.show();
}
break;
default:
//Do something;
}
}
.
10-30 21:22:23.379: E/AndroidRuntime(3970): FATAL EXCEPTION: main
10-30 21:22:23.379: E/AndroidRuntime(3970): java.lang.NullPointerException
10-30 21:22:23.379: E/AndroidRuntime(3970): at com.android.hopegpacalc.MainActivity.onClick(MainActivity.java:57)
10-30 21:22:23.379: E/AndroidRuntime(3970): at android.view.View.performClick(View.java:3511)
10-30 21:22:23.379: E/AndroidRuntime(3970): at android.view.View$PerformClick.run(View.java:14105)
10-30 21:22:23.379: E/AndroidRuntime(3970): at android.os.Handler.handleCallback(Handler.java:605)
10-30 21:22:23.379: E/AndroidRuntime(3970): at android.os.Handler.dispatchMessage(Handler.java:92)
10-30 21:22:23.379: E/AndroidRuntime(3970): at android.os.Looper.loop(Looper.java:137)
10-30 21:22:23.379: E/AndroidRuntime(3970): at android.app.ActivityThread.main(ActivityThread.java:4424)
10-30 21:22:23.379: E/AndroidRuntime(3970): at java.lang.reflect.Method.invokeNative(Native Method)
10-30 21:22:23.379: E/AndroidRuntime(3970): at java.lang.reflect.Method.invoke(Method.java:511)
10-30 21:22:23.379: E/AndroidRuntime(3970): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-30 21:22:23.379: E/AndroidRuntime(3970): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-30 21:22:23.379: E/AndroidRuntime(3970): at dalvik.system.NativeStart.main(Native Method)
Upvotes: 1
Views: 502
Reputation: 86948
It is a matter of organization, try this:
public void onClick(View v) {
// These should be class variables, like count, you don't need to re-find it on every click
TableLayout tableLayout1 = (TableLayout) findViewById(R.id.tableLayout1);
EditText editText1 = (EditText) findViewById(R.id.editText1);
EditText editText2 = (EditText) findViewById(R.id.editText2);
switch(v.getId()){
case R.id.button1:
if(count != 9){
count++;
// Create the row only when the add button is clicked
TableRow tempRow = new TableRow(MainActivity.this);
EditText tempText1 = new EditText(MainActivity.this);
EditText tempText2 = new EditText(MainActivity.this);
tempText1.setInputType(InputType.TYPE_CLASS_TEXT);
tempText2.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
tempRow.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
tempText1.setLayoutParams(editText1.getLayoutParams());
tempText2.setLayoutParams(editText2.getLayoutParams());
tempRow.addView(tempText1);
tempRow.addView(tempText2);
tableLayout1.addView(tempRow);
} else {
// Consider using Activity's showDialog() method, to reuse this "error" dialog rather than create a new one every time
final AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create(); //Read Update
alertDialog.setTitle("Error");
alertDialog.setMessage("You can only have 10 rows!");
alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
}
});
alertDialog.show();
}
break;
case R.id.button2:
if(count != 0){
// Remove the last row at count or use "tableLayout1.getChildCount() - 1"
tableLayout1.removeView(tableLayout1.getChildAt(count));
count--;
} else {
// Consider reusing the other "error" Dialog and simply changing the message
final AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create(); //Read Update
alertDialog.setTitle("Error");
alertDialog.setMessage("You must have at least one row!");
alertDialog.setButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
}
});
alertDialog.show();
}
break;
default:
//Do something;
}
}
Upvotes: 2
Reputation: 4641
Your removal code is "removing" temporary views (eg tempText1
) that aren't actually in the table - they were made on the fly inside the onClick
method. Instead of instantiating all of those objects as soon as you get into onClick
, do so in the body of each switch statement case. For the adding button, just copy and paste. For the removal one, set the objects equal to the row you want to remove.
It doesn't seem like you have a way of selecting which row to remove, but assuming you do this somewhere else you can use TableLayout.removeViewAt(int index)
to select which one. There's also TableLayout.removeView(View view)
if you have the view itself and not the index.
Upvotes: 0
Reputation: 8518
Your code makes a new TableRow
every time onClick is executed. You should only do this when you want to add a row. When you want to delete one, you'll have to find the row to delete in the existing view by using findViewById( id )
, then run removeView
on that object.
case R.id.button2:
if ( count != 0 ) {
count--;
tempRow = (TableRow)findViewById( idoftablerowtodelete );
tableLayout1.removeView( tempRow );
This does mean that you'll have to set an id on each table row when you create it, using setId
, and keep track of it.
Upvotes: 0