ListView not “refreshing” after item is deleted from it

南笙酒味 提交于 2019-12-04 06:26:16

问题


I am trying to figure out how I "Refresh" the list view the user is on when an item from my listview is deleted. I have tried notifyDataSetChanged() but to no avail, which is puzzling to me because this works when I add an item.

P.S. I know the item is getting deleted because if I press the back button and get to my activity again, the item is removed from the listview visually.

    public void deleteButtonClicked(View view){
    dbHandler.deleteExerciseFromDatabase(exerciseClickedbyUser, workoutClicked);
    exerciseListView.setAdapter(edsAdapter);
    edsAdapter.notifyDataSetChanged();
    Toast.makeText(getBaseContext(),"Exercise Deleted", Toast.LENGTH_SHORT).show();

}

When I run this in the emulator, the Toast does appear.

public class CustomExerciseAdapter extends ArrayAdapter{

public CustomExerciseAdapter(Context context, ArrayList<String> workouts) {
    super(context, R.layout.exercise_custom_row, workouts);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = LayoutInflater.from(getContext());
    View customView = inflater.inflate(R.layout.exercise_custom_row, parent, false);

    String singleExerciseItem = getItem(position);
    TextView exerciseTV = (TextView) customView.findViewById(R.id.exerciseTV);
    exerciseTV.setText(singleExerciseItem);

    return customView;
}

Here is my class that contains deleteButtonClicked

public class ExercisesSection extends ActionBarActivity {

private EditText userWorkoutInput;
private Button addNewWorkoutButton;
private CustomExerciseAdapter edsAdapter;
private ArrayList<String> itemHold;
private MyDBHandler dbHandler;
private String workoutClicked;
private String exerciseClickedbyUser;
private ListView exerciseListView;

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

    initViews();
    handleIntentData();
    inputTextHandler();
    loadDataFromDatabase();


}
//This method initializes all the views
public void initViews(){
    userWorkoutInput = (EditText) findViewById(R.id.userWorkoutInput);
    addNewWorkoutButton = (Button) findViewById(R.id.addNewWorkoutButton);
    exerciseListView = (ListView) findViewById(R.id.exerciseListView);
    itemHold = new ArrayList<String>();
    dbHandler = new MyDBHandler(this,null,null,1);
}

//This method makes the "Add new workout Button" clickable or not depending on user input
public void inputTextHandler(){

    userWorkoutInput.addTextChangedListener(
            new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    boolean isEmpty = false;
                    if ((userWorkoutInput.getText().toString().trim()).equals("")) {
                        isEmpty = true;
                    }
                    addNewWorkoutButton.setEnabled(!isEmpty);
                }

                @Override
                public void afterTextChanged(Editable s) {

                }
            }
    );
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
THIS IS THE BUTTON LISTENER FOR @id+/addNewWorkoutButton
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
public void addWorkoutButtonClicked(View view){
    String input = (userWorkoutInput.getText().toString().trim());
    if (!input.equals("")){
        addItemToList(input);
        userWorkoutInput.setText("");   //Empties the edit text section
        saveDataToDatabase(input);
    }
}

public void saveDataToDatabase(String input){
    //GIVE THE EXERCISES OBJ VALUES!
    Exercises exercises = new Exercises(input, workoutClicked);
    dbHandler.addExerciseToDatabase(exercises);
}

public void loadDataFromDatabase(){

    String exerName = dbHandler.getExercisesForBodyParts(workoutClicked);

    //IF STATEMENT WEEDS OUT EMPTY DATA
    if(!(exerName.trim().equals(""))) {
        String delim = ",";
        String[] tokens = exerName.split(delim);
        for (int i = 0; i < tokens.length; i++) {
            addItemToList(tokens[i]);
        }
    }
}

public void addItemToList(String input){

    itemHold.add(input);
    edsAdapter = new CustomExerciseAdapter(this, itemHold);

    exerciseListView.setAdapter(edsAdapter);
    edsAdapter.notifyDataSetChanged();

    exerciseListView.setOnItemClickListener(
            new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    exerciseClickedbyUser = String.valueOf(parent.getItemAtPosition(position));
                    textClicked(view, exerciseClickedbyUser);  //starts intent and sends to Exercise Clicked Activity
                }
            }
    );

}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 This method is an onClick Method from exercise_custom_row.xml
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

public void deleteButtonClicked(View view){
    dbHandler.deleteExerciseFromDatabase(exerciseClickedbyUser, workoutClicked);
    itemHold.remove(exerciseClickedbyUser);

    edsAdapter.notifyDataSetChanged();

    Toast.makeText(getBaseContext(),"Exercise Deleted", Toast.LENGTH_SHORT).show();
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 This method gets the data (name of section clicked) from MainActivity
 and changes the textView in exercise_section accordingly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
public void handleIntentData(){

    Bundle workoutData = getIntent().getExtras();
    if (workoutData == null){
        return;
    }

    workoutClicked = workoutData.getString("exerciseChosen");
    TextView exerciseChosenText = (TextView) findViewById(R.id.exerciseChosenText);
    exerciseChosenText.setText(workoutClicked);
    exerciseChosenText.setTypeface(null, Typeface.BOLD);
}



public void textClicked(View view, String exercise){

    Intent i = new Intent(this, ExerciseClicked.class);
    i.putExtra("exerciseClicked", exercise);
    startActivity(i);

}

回答1:


In my app, I don't use notifyDataSetChanged at all. To refresh the ListView, I simply run the database query again and use CursorAdapter.changeCursor. It will automatically call notifyDataSetChanged as needed.




回答2:


Your item is being deleted from database but the listview is not updating visually.Setting adapter is a solution but it will reset the list from start which not make a good experience for user to scroll all the time again.You can do one thing when you removing item from database at the same time you can remove selected item from your list. I think your listview listener should look like this in your activity:

listview.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                deleteButtonClicked(postion);
            }
        });



public void deleteButtonClicked(int position){
           int count=dbHandler.deleteExerciseFromDatabase(exerciseClickedbyUser, workoutClicked);
    if(count>0){
        list.remove(position);

            edsAdapter.notifyDataSetChanged();
            Toast.makeText(getBaseContext(),"Exercise Deleted", Toast.LENGTH_SHORT).show();
    }
}



回答3:


You can perfectly remove item from adapter by using following code.

mCollection.remove(position);
mListLayout.removeAllViews();
notifyDataSetChanged();



回答4:


You seem no change in listview because your ArrayList or Array you assigned to the adapter has no changes. Please remove the item from the ArrayList or array too. And you just have to call notifyDataSetChanged() ., ie, there is no need of calling listview.setAdapter(adapter) again.

EDIT :

please replace your customArrayAdapter with the below shown code

   private  ArrayList<String> workouts;

    public CustomExerciseAdapter(Context context, ArrayList<String> workouts) {
        super(context, R.layout.exercise_custom_row, workouts);
        this.workouts = workouts;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        View customView = inflater.inflate(R.layout.exercise_custom_row, parent, false);
                /////here change to 
        String singleExerciseItem = (String)workouts.get(position);
        TextView exerciseTV = (TextView) customView.findViewById(R.id.exerciseTV);
        exerciseTV.setText(singleExerciseItem);

        return customView;
    }


    public void setList(ArrayList<String> workouts){

       this.workouts = workouts;
       notifyDatasetChanged();

    }
}

In your delete method, after updating database and your list, call adapter.setList(workouts),. it may do the trick for you.




回答5:


Thanks for all the help guys, but in the end the answer I came up with is quite different from yours. I ended up using his method [1]: http://jmsliu.com/2444/click-button-in-listview-and-get-item-position.html/ "here" which worked absolutely perfect for me. Anyways this was what did for those who might run into the same issue.

STICK THIS CODE IN THE GetView() method LOCATED IN .JAVA FILE INFLATES THE XML FILE.

Button deleteButton = (Button) customView.findViewById(R.id.deleteButton);
deleteButton.setTag(position);

Then add this into your button click listener/ onClick method

    int position = (Integer) view.getTag();
    list.remove(position);

    adapter.notifyDataSetChanged();



回答6:


after removing items always add the below two lines

            notifyDataSetChanged();
            notifyDataSetInvalidated();

notifydatasetchanged will see for any changes in the list and notifydatasetinvalidated will check if there is any item removed then it will update the list



来源:https://stackoverflow.com/questions/31671424/listview-not-refreshing-after-item-is-deleted-from-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!