ListView not “refreshing” after item is deleted fr

2019-03-06 13:47发布

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);

}

6条回答
霸刀☆藐视天下
2楼-- · 2019-03-06 14:23

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();
查看更多
三岁会撩人
3楼-- · 2019-03-06 14:24

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.

查看更多
叛逆
4楼-- · 2019-03-06 14:28

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.

查看更多
Viruses.
5楼-- · 2019-03-06 14:33

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();
    }
}
查看更多
劳资没心,怎么记你
6楼-- · 2019-03-06 14:39

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

查看更多
我只想做你的唯一
7楼-- · 2019-03-06 14:48

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

mCollection.remove(position);
mListLayout.removeAllViews();
notifyDataSetChanged();
查看更多
登录 后发表回答