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);
}
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.
Then add this into your button click listener/ onClick method
In my app, I don't use
notifyDataSetChanged
at all. To refresh the ListView, I simply run the database query again and useCursorAdapter.changeCursor
. It will automatically callnotifyDataSetChanged
as needed.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
In your delete method, after updating database and your list, call adapter.setList(workouts),. it may do the trick for you.
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:
after removing items always add the below two lines
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
You can perfectly remove item from adapter by using following code.