ListView с пользовательским адаптером массива не будет обновляться должным образом после вызова onDestroy () и onCreate () - PullRequest
1 голос
/ 01 июля 2011

У меня есть список с пользовательским адаптером массива:

public class SmsMessageAdapter extends ArrayAdapter<ContactMessage> {

private ArrayList<ContactMessage> items;

public SmsMessageAdapter(Context context, int textViewResourceId, ArrayList<ContactMessage> items) {
    super(context, textViewResourceId, items);
    this.items = items;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if(v == null) {
        LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.message, null);
    }
    ContactMessage c = items.get(position);
    if(c != null) {
        String name = c.getContact();
        if(name.equals("Me")) v.setBackgroundResource(R.drawable.sms_history_outgoing_background_gradient);
        else v.setBackgroundResource(R.drawable.sms_history_incoming_background_gradient);
        TextView contactName = (TextView) v.findViewById(R.id.message_contact_name);
        TextView body = (TextView) v.findViewById(R.id.message_body);
        TextView date = (TextView) v.findViewById(R.id.message_date_time);
        if(contactName != null) {

            contactName.setText(name);
        }
        if(body != null) {
            body.setText(c.getBody());
        }
        if(date != null) {
            date.setText(c.getFormattedTimeString());
        }
    }
    return v;
}
}

У меня также есть метод в моей основной деятельности, который обновляет представление списка, добавляя элементы в список массивов, связанный с настраиваемым адаптером массива:

private void displayContactSmsHistory(String phoneNumber) {
    Contact c = new Contact();

    for(Contact contact : mContactsArrayList) {
        if(getOnlyNumerics(phoneNumber).equals(getOnlyNumerics(contact.getPhoneNumber()))) {
            c = contact;
        }
    }

    HashMap<String, Boolean> unreadPositions = mContactsAdapter.getUnreadMap();
    unreadPositions.put(getOnlyNumerics(phoneNumber), false);
    mContactsAdapter.setUnreadMap(unreadPositions);

    HashMap<String, Boolean> selectedPosition = mContactsAdapter.getSelectedMap();
    for(String key : selectedPosition.keySet()) {
        selectedPosition.put(key, false);
    }
    selectedPosition.put(getOnlyNumerics(phoneNumber), true);
    mContactsAdapter.setSelectedMap(selectedPosition);

    String contactName;

    if(c.hasName()) contactName = c.getName();
    else contactName = phoneNumber;

    mConversationArrayAdapter.clear();

    if(!db.isOpen()) db = db.open();
    Cursor smsHistory = db.getSmsForContact(phoneNumber);
    startManagingCursor(smsHistory);
    int bodyIndex = smsHistory.getColumnIndex(DBAdapter.KEY_BODY);
    int dateIndex = smsHistory.getColumnIndex(DBAdapter.KEY_DATE);
    int typeIndex = smsHistory.getColumnIndex(DBAdapter.KEY_TYPE);
    if(smsHistory.moveToFirst()) {
        while(!smsHistory.isAfterLast()) {
            String body = smsHistory.getString(bodyIndex);
            String dateString = smsHistory.getString(dateIndex);
            DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
            Date date;
            try {
                date = df.parse(dateString);
            } catch (ParseException e) {
                Log.e(TAG, "Error parsing date string while displaying contact info:", e);
                date = new Date(0);
            }

            if(smsHistory.getInt(typeIndex) == DBAdapter.RECEIVED) {
                smsHistoryArrayList.add(new ContactMessage(date, contactName, body));
            } else {
                smsHistoryArrayList.add(new ContactMessage(date, null, body));
            }

            smsHistory.moveToNext();
        }
    }
    stopManagingCursor(smsHistory);
    if(db.isOpen()) db.close();

}

Метод обновления может быть вызван из двух разных мест в моем коде; 1) если пользователь выбирает элемент из другого списка, и 2) если я вызываю метод напрямую в определенных ситуациях. Это все работает и находит, кроме случая, когда пользователь нажимает кнопку «назад» (которая инициирует вызов на onDestroy()), а затем возвращается в приложение (вызывая новый вызов на onCreate()). Если это произойдет, просмотр списка будет обновляться только из одного места в моем коде (если пользователь выбирает элемент в другом просмотре списка). Для других ситуаций, когда вызывается метод обновления, код выполняется, но просмотр списка не обновляется. Я пробежался по инструменту отладки, просматривая переменные внутри метода update, и я не вижу никакой причины, по которой listview не обновляется.

Также обратите внимание, что если пользователь нажимает кнопку «Домой» вместо кнопки «Назад», а затем возвращается в приложение, все работает нормально. В этой ситуации onDestroy() и onCreate() никогда не называются, только onStop() и onStart().

При необходимости я могу опубликовать свои onCreate() и onDestroy(), однако теперь я могу сказать, что в этих двух методах нет ничего, что, по моему мнению, вызывает ошибку (onCreate() просто загружает настройки и устанавливает макет, и onDestroy() закрывает базу данных).

Ответы [ 2 ]

0 голосов
/ 05 июля 2011

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

0 голосов
/ 01 июля 2011

Есть несколько способов добиться этого.

  1. Сделайте вашу ArrayList локальной переменной (объявить в побочной функции).
  2. Очистить ваш ArrayList переменная

Надеюсь, это полезно для вас

...