Kate Kate - 9 months ago 33
Java Question

Replacing values in ArrayList of custom objects

I have a custom class Distraction and an ArrayList of Distractions being shown using an ArrayAdapter. Upon clicking on individual items in the list a popup menu appears with the options Edit and Remove. When Edit is pressed an alert dialog appears with two EditText's that take user input for name and priority. I then want to compare the user input to the previously stored value and update if different. However, the code currently changes the name to blank no matter what I input in any of the fields.

Screenshot of pop up menu when clicking list item

CODE:

Distraction class

public class Distraction {


//Distraction properties
private String distraction_name;
private String distraction_priority;
private String distraction_occurance;

//Constructor of Distraction type
public Distraction (String distraction_name, String distraction_priority, String distraction_occurance)

this.distraction_name = distraction_name;
this.distraction_priority = distraction_priority;
this.distraction_occurance = distraction_occurance;
}


//Getter methods

public String getDistraction_name(){return distraction_name;}
public String getDistraction_priority(){return distraction_priority;}
public String getDistraction_occurance(){return distraction_occurance;}

public void setDistraction_name(String distraction_name){
this.distraction_name = distraction_name;
}

public void setDistraction_priority(String distraction_priority){
this.distraction_priority = distraction_priority;
}

public void setDistraction_occurance(String distraction_occurance) {
this.distraction_occurance = distraction_occurance;
}
}


Code from activity

//Declare an Array List of Distractions
final ArrayList<Distraction> distractionsArray = new ArrayList<>();

//Creation of first sample data
distractionsArray.add(new Distraction("Example: Text from Alice", "3", "1"));

//Initialise the custom array adapter (nested ArrayAdapter class at the end of this activity)
final ArrayAdapter<Distraction> adapter = new distractionArrayAdapter(DistractionsActivity.this, 0, distractionsArray );

//Bind list view with the custom adapter
distractions_list.setAdapter(adapter);

//Adapter onclickable function
distractions_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {

//Popup menu for distraction (EDIT, REMOVE)
PopupMenu popup2 = new PopupMenu(DistractionsActivity.this, view);
popup2.inflate(R.menu.distraction_menu);
popup2.show();

popup2.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {

//WHEN USER PRESSES EDIT
if (item.getItemId() == R.id.Edit) {

LayoutInflater dialog = LayoutInflater.from(DistractionsActivity.this);
final View edit_distraction_dialog_view = dialog.inflate(R.layout.edit_distractions, null);

//Create and initialise an AlertBuilder to open a pop-up where
//the user will be able to give some info about the distraction
final AlertDialog.Builder builder = new AlertDialog.Builder(DistractionsActivity.this);
builder.setTitle("Edit Distraction").setView(edit_distraction_dialog_view);

builder.setView(R.layout.edit_distractions);


//Set positive OK button for alert dialog
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {

final EditText input_name = (EditText) edit_distraction_dialog_view.findViewById(R.id.edit_distraction_name_edittext);
final EditText input_priority = (EditText) edit_distraction_dialog_view.findViewById(R.id.edit_distraction_priority_edittext);

final String new_name = input_name.getText().toString();
final String new_priority = input_priority.getText().toString();

final String old_name = distractionsArray.get(position).getDistraction_name();
final String old_priority = distractionsArray.get(position).getDistraction_priority();

if (!(new_name.equals(old_name))){
distractionsArray.get(position).setDistraction_name(new_name);
}
else
{
Toast.makeText(DistractionsActivity.this, "No input!", Toast.LENGTH_SHORT);
}
adapter.notifyDataSetChanged();
}
});

//Set negative CANCEL button for the alert dialog
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Close alert dialog
dialog.cancel();
}
});
builder.show();
}
//WHEN USER PRESSES REMOVE
if (item.getItemId() == R.id.Remove) {
adapter.remove(distractionsArray.get(position));
adapter.notifyDataSetChanged();
}
return false;
}
});

}
});


It also doesn't print the Toast in the else statement.

Screenshot of output after pressing OK on the alert dialog

Can someone explain why my input isn't passing through and how I can fix it?

Answer Source

So, this code itself should work fine assuming the views are loading correctly.

final EditText input_name = (EditText) edit_distraction_dialog_view.findViewById(R.id.edit_distraction_name_edittext);
final EditText input_priority = (EditText) edit_distraction_dialog_view.findViewById(R.id.edit_distraction_priority_edittext);

// You can debug and set breakpoints on these, though
final String new_name = input_name.getText().toString();
final String new_priority = input_priority.getText().toString();

If you get empty strings, then a few possibilities

1) You typed nothing. But, I doubt that

2) The call to getText().toString() is not waiting for you to click a button. But you are doing that on the positive click action.

3) You loaded a new View over the top of the other Dialog.

Seems like this is the case

// An inflater
LayoutInflater inflater = LayoutInflater.from(DistractionsActivity.this);
// An inflated View    
final View edit_distraction_dialog_view = inflater.inflate(R.layout.edit_distractions, null);

// A dialog
final AlertDialog.Builder builder = new AlertDialog.Builder(DistractionsActivity.this);
builder
    .setTitle("Edit Distraction")
    .setView(edit_distraction_dialog_view); // You already called setView!

// Don't need to call it again!
// builder.setView(R.layout.edit_distractions);

And you can move the findViewById outside the onClick

builder.show(); // Need to call this first

final EditText input_name = (EditText) edit_distraction_dialog_view.findViewById(R.id.edit_distraction_name_edittext);
final EditText input_priority = (EditText) edit_distraction_dialog_view.findViewById(R.id.edit_distraction_priority_edittext);

//Set positive OK button for alert dialog
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String new_name = input_name.getText().toString();
                String new_priority = input_priority.getText().toString();