Reputation: 1897
I'm trying to implement a feature in my app where the user can add buttons to the screen and then delete them with a long press.
I was able to do the first part where the user can add the buttons and the user can delete the most recently added button. However if you try to delete any of the other buttons it gives a NullPointerException.
Here is my method which creates a new button:
public Button makeButton(Context context, String label, final GestureDetector gdt, int buttonId) {
btn = new Button(context);
v = new TextView(context);
v.setText("");
v.setHeight(10);
ScrollView s = (ScrollView) homeView.findViewById(R.id.mainScroll);
s.setVerticalScrollBarEnabled(false);
btn.setText(label);
btn.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
btn.setHeight(70);
btn.setId(buttonId);
btn.setBackgroundColor(Color.GREEN);
btn.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
id = btn.getId();
gdt.onTouchEvent(event);
switch(event.getAction()) {
case(MotionEvent.ACTION_DOWN):
ColorDrawable color = (ColorDrawable) btn.getBackground();
int backgroundColor = color.getColor();
if(backgroundColor == Color.GREEN) {
btn.setBackgroundColor(Color.YELLOW);
showToast("Running late??");
}
}
return true;
}
});
Ll.addView(btn);
Ll.addView(v);
return btn;
}
Here is the onClickListener() for the button which is used to create new buttons:
addButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
factory.inflate(R.layout.eventadd, null);
final View addEvent = factory.inflate(R.layout.eventadd, null);
final EditText eventTime = (EditText) addEvent.findViewById(R.id.editText1);
AlertDialog.Builder createEvent = new AlertDialog.Builder(context);
createEvent.setTitle("Add new event");
createEvent.setView(addEvent);
(createEvent).setPositiveButton("Add Event", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
String getTxt = eventTime.getText().toString();
makeButton(context, getTxt, gestureDetector, id);
id++;
}
});
createEvent.show();
}
});
And finally this is my GestureListener:
private class GestureListener extends SimpleOnGestureListener {
@Override
public void onLongPress(MotionEvent event) {
showToast("Button " + btn.getId() + " deleted");
btn.setVisibility(View.GONE);
((LinearLayout)btn.getParent()).removeViewAt(id);
((LinearLayout)v.getParent()).removeView(v);
}
}
I'm pretty sure the error is something to do with id's of the buttons and how they are deleted in the GestureListener. Of course I'm more than likely wrong.Thanks for all the help :)
Upvotes: 2
Views: 2226
Reputation: 430
use a stack of buttons ids. when ever you create button, save its id in that stack and when you press delete button get the last present id from stack and remove button -> then remove its id from stack as well.
Upvotes: 0
Reputation: 2414
The issue is in your GestureListener.
You're doing ((LinearLayout)btn.getParent()).removeViewAt(id);
This removes a view at a specific index. I believe you want
View view = ((LinearLayout)btn.getParent()).findViewById(id)
to return you a view, which you should then pass that view to
((LinearLayout)btn.getParent()).removeView(view)
;
EDIT
It looks like you're keeping a private class variable for your Button
. This means that the button there will ALWAYS be the last button you made. In your onTouch()
method, you reference that btn
variable, which is the last button you made. If you change the first line in your onTouch()
method to id = v.getId()
, it should give you the right button.
Upvotes: 4