Как использовать notifyDataSetChanged в CustomAdapter?

в моем приложении для Android у меня есть ExpandableListView и BaseExpandableListAdapter, BaseExpandableListAdapter находится в отдельном классе. В списке у меня есть кнопка удаления внутри дочерней строки списка. Кнопка удаляет текущую строку, но список остается прежним и не показывает его в режиме реального времени. Я получаю данные адаптеру через свой DbHandler в HashMap. Я пытался использовать notifyDataSetChanged(), но безрезультатно, иначе я снова запускаю onCreate. Как я могу это решить?


person Matt    schedule 23.08.2014    source источник
comment
Пожалуйста, опубликуйте код, в котором нажатие кнопки удаляет текущую строку.   -  person Simas    schedule 24.08.2014
comment
Вы вызываете notifyDataSetChanged из потока пользовательского интерфейса?   -  person ajw    schedule 24.08.2014
comment
Если вы имеете в виду от MainActivity? так да   -  person Matt    schedule 24.08.2014
comment
и переходник из другого класса   -  person Matt    schedule 24.08.2014
comment
Это будет работать, но не уверен, что это лучший способ сделать, после того как вы удалите строку, обновите свою хэш-карту и снова вызовите setadapter с обновленными значениями, а после этого вызовите notifyDataSetChanged().   -  person Psypher    schedule 24.08.2014
comment
Я знаю, но метод удаления находится в классе адаптера, и я устанавливаю адаптер в потоке пользовательского интерфейса.   -  person Matt    schedule 24.08.2014


Ответы (2)


Допустим, вы инициализировали свой ExpandableListView с двумя списками ArrayList: первый содержит группы, а второй — дочерние элементы для этих групп. Это будет выглядеть так:

private ArrayList<E> mListGroups;
private ArrayList<ArrayList<E>> mGroupsItems;

Ниже приведен пример расширения пользовательского макета для дочерних элементов только с одним TextView в нем.

@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild,
                         View convertView, ViewGroup parent) {
    ItemViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item_drawer, null);
        holder = new ItemViewHolder();
        holder.tv = (TextView)convertView.findViewById(R.id.text1);
        convertView.setTag(holder);
    } else holder = (ItemViewHolder)convertView.getTag();
    holder.tv.setText(getChild(groupPosition, childPosition).getName());
    holder.tv.setClickable(true);
    holder.tv.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mGroupsItems.get(groupPosition).remove(childPosition);
            notifyDataSetChanged();
        }
    });
    return convertView;
}

Чтобы удалить щелкнутый элемент, вы устанавливаете OnClickListener в этом представлении и удаляете элемент из списка. В вашей реализации вы установите OnClickListener для ImageView. Вот и все.

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

person Alexander Zhak    schedule 23.08.2014
comment
спасибо, но для обновления через MainActivity я знаю, как это сделать. мой вопрос заключался в том, как обновлять класс адаптера в режиме реального времени, потому что моя кнопка находится внутри списка - person Matt; 24.08.2014
comment
У вас есть идеи, пожалуйста? - person Matt; 24.08.2014
comment
@Matt отредактировал мой неправильный ответ. Пожалуйста, взгляните - person Alexander Zhak; 24.08.2014
comment
Я использую hashMap‹ArrayList‹Model›, ArrayList‹Model››; ваш вопрос не работает для меня, приложение вылетает - person Matt; 25.08.2014

notifyDataSetChanged сообщает ListView`у перестроить все его элементы из-за изменений в базовых данных.

Итак, в основном, что вы обычно делаете, это:

  • Найти ListView из макета
  • Создать экземпляр адаптера
  • Подключить ListView и адаптер
  • Установите некоторые данные в адаптере
  • Вызовите notifyDataSetChanged(), чтобы сообщить ListView о создании своих элементов (путем вызова адаптера getCount(), getView() и т. д.

Когда базовые данные изменяются позже (как в вашем случае с помощью кнопки «Удалить»), вы удаляете этот элемент из данных в адаптере, но список не узнает об этом, пока вы не уведомите ListView об измененных данных через вызов до notifyDataSetChangedd().

person Ridcully    schedule 24.08.2014
comment
Я знаю, как создать listView с помощью адаптера. посмотрите на мой вопрос, я просто хочу обновить список после того, как удалил строку с помощью кнопки в строках - person Matt; 25.08.2014
comment
Если вы фактически удалите элемент из данных адаптера, notifyDataSetChanged заставит удаленный элемент исчезнуть из списка. Если он не исчез, что-то не так с удалением данных. Было бы полезно, если бы вы могли опубликовать соответствующий код. - person Ridcully; 25.08.2014