Я создал собственный класс BaseAdapter для отображения регистрационных ключей в ListView. Всякий раз, когда я добавляю еще один ключ в список и вызываю notifyDataSetChanged()
, обновления ListView визуально просто прекрасны. Моя структура данных - это просто ArrayList простых структур, содержащих несколько строк и int. Однако, когда я пытаюсь очистить список ключей и позвонить notifyDataSetChanged()
, ничего не происходит визуально. Когда я закрываю и снова открываю приложение, список пуст, как и должно быть. Перед вызовом notifyDataSetChanged()
Теперь я звоню notifyDataSetInvalidated()
. Это позволяет корректно обновлять изображения, как только я удаляю ключи, но Google documentation предупреждает об использовании этого метода, если вы не полностью используете этот адаптер. Когда я регистрирую больше ключей после их очистки, они все еще отображаются в ListView, что делает его похожим на то, что notifyDataSetInvalidated()
является рабочим решением. Есть ли какая-либо опасность, связанная с этим методом, если я буду использовать один и тот же BaseAdapter и ArrayList для ListView? Есть ли лучшее решение? Вот мой заказ реализация BaseAdapter:BaseAdapter неправильно удаляет элементы из представления?
class KeyAdapter extends BaseAdapter implements Database.KeyRegistrationListener {
private ArrayList<Database.KeyDetails> keyInfo;
public KeyAdapter(ArrayList<Database.KeyDetails> keyInfo) {
this.keyInfo = keyInfo;
}
@Override
public int getCount() {
return keyInfo.size();
}
@Override
public Database.KeyDetails getItem(int position) {
return keyInfo.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int pos, View convertView, ViewGroup parent) {
TextView userID;
TextView appName;
TextView date;
TextView time;
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.registration_item, parent, false);
userID = (TextView) convertView.findViewById(R.id.user_id);
appName = (TextView) convertView.findViewById(R.id.app_name);
date = (TextView) convertView.findViewById(R.id.date_used);
time = (TextView) convertView.findViewById(R.id.time_used);
convertView.setTag(R.id.user_id, userID);
convertView.setTag(R.id.app_name, appName);
convertView.setTag(R.id.date_used, date);
convertView.setTag(R.id.time_used, time);
} else {
userID = (TextView) convertView.getTag(R.id.user_id);
appName = (TextView) convertView.getTag(R.id.app_name);
date = (TextView) convertView.getTag(R.id.date_used);
time = (TextView) convertView.getTag(R.id.time_used);
}
Database.KeyDetails key = getItem(pos);
userID.setText(key.userID);
appName.setText(key.appName);
date.setText(key.date);
time.setText(key.time);
return convertView;
}
@Override
public void notifyKeysUpdated(Database.KeyDetails newKeyDesc) {
if (newKeyDesc == null) {
keyInfo.clear();
notifyDataSetInvalidated();
notifyDataSetChanged();
} else{
keyInfo.add(newKeyDesc);
notifyDataSetChanged();
}
}
}
Метод notifyKeysUpdated()
называется мой класс-оболочку для базы данных SQLite всякий раз, когда я добавить ключ в базу данных. Если мой объект базы данных подает прослушиватель null
, это означает, что все ключи в базе данных были очищены, а ListView должен быть визуально пустым.
EDIT: Так как я начал использовать notifyDataSetInvalidated()
, то ListView больше не отображает ничего, в том числе, когда я зарегистрировать новые ключи.
Во всех других реализациях BaseAdapter, которые я видел, пользовательский подкласс просто сохранил собственную структуру данных и реализовал несколько методов, которые я сделал. Список определенно обновляется, это просто потому, что по какой-то причине представление обновляется только после добавления в список, но не при удалении элементов. Я думаю, что я могу вместо этого перейти на CursorAdapter, учитывая, что ключи, зарегистрированные в моем приложении, изначально хранятся в базе данных SQLite. Спасибо за усилия, хотя! –