Вызов метода notifyDataSetChanged() BaseAdapter внутри CustomAdapter без обновления ListView

Я имею ArrayList<MyObject> data который заселен на ListView используя CustomAdapter,

Я реализовал View.OnClickListener в CustomAdapter класс и нажав кнопку удаляет конкретную строку. После удаления строки, как из базы данных, так и из data использование объекта data.remove(i) внутри пользовательского адаптера я звоню notifyDataSetChanged(),

Проблема в том, что он не обновляет ListView,

Я использую активность с вкладками с фрагментом. Поэтому, когда вы переходите на какую-то отдаленную вкладку и возвращаетесь на эту вкладку, она обновляет ListView и удаленный элемент больше не отображается.

Почему ListView не обновляется сразу, когда я звоню notifyDataSetChanged() но меняется, когда я перехожу на другой фрагмент и обратно?

мой CustomAdapter Класс выглядит следующим образом:

public class CustomAdapter extends BaseAdapter implements View.OnClickListener {

    private LayoutInflater mInflater;
    Context context;
    private ArrayList<MyObject> data;

    public CustomAdapter(Context context, ArrayList<MyObject> data) {
        mInflater = LayoutInflater.from(context);
        this.data = data;
        this.context = context;
    }
    .....
    .....
    .....
    .....
    .....

    @Override
    public void onClick(View v) {
        DataBaseHelper db = new DataBaseHelper(context);
        int id = data.get((Integer) v.getTag()).id;
        //use getTag() to get the position, set position in tag before adding listener.
        switch (v.getId()){
            case R.id.txtName:
                Toast.makeText(context, "Show Details" + v.getTag(), Toast.LENGTH_SHORT).show();
                break;
            case R.id.btnRemove:
                db.removePaper(id); // works fine
                data.remove(v.getTag()); // works fine
                notifyDataSetChanged(); // PROBLEM HERE: Does not refresh listview
                break;
            case R.id.btnFavorite:
                Toast.makeText(context, "Favorite" + v.getTag(), Toast.LENGTH_SHORT).show();
                break;

        }

    }
}

1 ответ

Решение

У меня была похожая проблема некоторое время назад, я исправил ее расширение ArrayAdapter<MyObject> вместо BaseAdapter и переопределение некоторых методов:

public class CustomAdapter extends ArrayAdapter<MyObject> {

private List<MyObject> list = new ArrayList<MyObject>();

public CustomAdapter(Context context, int resource) {
    super(context, resource);
}

 @Override
 public void add(MyObject obj) {
     this.list.add(obj);
     super.add(obj);
 }

 @Override
 public void remove(MyObject obj) {
     int i = getPosition(obj);
     if(i >= 0)
         list.remove(i);
     super.remove(obj);
 }

 @Override
 public void clear() {
     this.list.clear();
     super.clear();
 }

 @Override
 public MyObject getItem(int position) {
     return this.list.get(position);
 }

 @Override
 public int getPosition(MyObject obj) {
     for(int i = 0; i < list.size(); i++) {
         if(list.get(i).equals(obj))
             return i;
     }
     return -1;
 }}

Затем вызовите эти методы вместо прямого вызова методов вашего Списка.

Другие вопросы по тегам