Почему список Android иногда исчезает после вызова requery для базового курсора?

У меня есть довольно простое приложение, которое использует ListActivity для отображения ListView. Каждый элемент ListView имеет флажок, чтобы пользователь мог указать избранные элементы. Я использую класс, который расширяет SimpleCursorAdapter, чтобы я мог фиксировать как событие изменения CheckBox (для сохранения изменения в базе данных), так и событие щелчка элемента списка (для загрузки действия сведений об элементе).

После того, как реализация OnCheckChangedListener обновляет базу данных, я вызываю .requery() для курсора, чтобы, когда элемент прокручивается, а затем возвращался на экран, CheckBox имел правильное состояние.

Это все работает нормально. У меня возникают проблемы в другом действии, где я повторно использую один и тот же макет ListView и тот же адаптер курсора для отображения определенного подмножества элементов как части другого макета действия. Когда я использую макет, все в порядке, пока я не нажму CheckBox, после чего весь ListView исчезнет. База данных обновляется, но пока я не покину активность и не вернусь, ListView просто полностью исчезнет.

Если я не вызываю .requery() для курсора, все работает нормально; ListView не исчезает (но состояние CheckBox иногда будет неправильным, как описано выше).

Рабочий макет, event_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/RelativeLayout01"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView android:layout_width="wrap_content" android:text="@+id/eventsHeader"
        android:id="@+id/eventsHeader" android:gravity="center_vertical"
        android:layout_height="wrap_content" android:textSize="15sp" />
    <ListView android:id="@+id/android:list" android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:layout_below="@+id/showHistoricalEvents" />

    <CheckBox android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:id="@+id/showHistoricalEvents"
        android:layout_alignParentRight="true" android:layout_alignParentTop="true"
        android:text="Show Past Events" android:textSize="14sp" />
    <TextView android:id="@+id/android:empty" android:text="@string/no_events"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_below="@+id/showHistoricalEvents" />
</RelativeLayout>

Сломанный макет, track_details.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content" android:orientation="vertical"
    android:layout_width="fill_parent">
    <TextView android:layout_width="wrap_content" android:id="@+id/InterestLabel"
        android:layout_alignParentLeft="true" android:text="@string/interest_level"
        android:gravity="center_vertical" android:layout_height="fill_parent"
        android:layout_above="@+id/track_name" />
    <Spinner android:layout_height="wrap_content" android:id="@+id/InterestSpinner"
        android:entries="@array/priority" android:layout_alignParentTop="true"
        android:layout_toLeftOf="@+id/FavoriteCheckbox" android:layout_width="fill_parent"
        android:layout_toRightOf="@+id/InterestLabel" />
    <CheckBox android:layout_width="wrap_content" style="?android:attr/starStyle"
        android:id="@+id/FavoriteCheckbox" android:layout_alignParentTop="true"
        android:layout_alignParentRight="true" android:gravity="center_vertical"
        android:layout_height="fill_parent" android:layout_above="@+id/track_name" />
    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:id="@+id/track_name"
        android:text="@+id/track_name" android:textSize="25sp"
        android:layout_below="@+id/InterestSpinner" />

    <LinearLayout android:id="@+id/LinearLayout01"
        android:layout_below="@+id/track_name" android:orientation="vertical"
        android:layout_height="fill_parent" android:layout_width="fill_parent">
        <TextView android:text="@+id/track_description" android:id="@+id/track_description"
            android:scrollbars="vertical" android:layout_width="fill_parent"
            android:layout_height="0dip" android:layout_weight="1"
            android:paddingLeft="5dp" android:paddingTop="5dp" />
        <include layout="@layout/event_list" android:id="@+id/trackEventList"
            android:layout_width="fill_parent" android:layout_height="0dip"
            android:layout_weight="2.5" />
    </LinearLayout>
</RelativeLayout>

Моя единственная мысль сейчас заключается в том, что то, как я использую layout_weight во втором макете, вызывает некоторые странности. Однако мне не хочется это менять, поскольку мне потребовалось довольно много времени, чтобы макет работал так, как я хотел.

Еще одно замечание: когда я включаю первый макет во второй, я скрываю элементы управления TextView и CheckBox, потому что они не нужны.

Любые идеи, что я делаю неправильно здесь?


person Malachi    schedule 22.08.2010    source источник


Ответы (1)


У меня возникают проблемы в другом действии, где я повторно использую один и тот же макет ListView и тот же адаптер курсора для отображения определенного подмножества элементов как части другого макета действия.

Если вы имеете в виду тот же экземпляр SimpleCursorAdapter, это поэтому не очень хорошая идея. Пожалуйста, сделайте новый адаптер.

Когда я использую макет, все в порядке, пока я не нажму CheckBox, после чего весь ListView исчезнет. База данных обновляется, но пока я не покину активность и не вернусь, ListView просто полностью исчезнет.

Используйте hierarchyviewer, чтобы определить, не имеет ли ListView дочерних элементов (строк), не имеет высоты, является ли он невидимым/исчез с точки зрения видимости или действительно удален из иерархии представлений. Это даст вам лучшее представление о том, как действовать дальше.

Любые идеи, что я делаю неправильно здесь?

Помимо упомянутой выше проблемы с адаптером, вы используете CheckBox. Android имеет встроенную поддержку списков множественного выбора (например, android:choiceMode="multiple"), но для этого требуется CheckedTextView. Я бы стремился использовать встроенную логику множественного выбора Android, а не собственную.

person CommonsWare    schedule 22.08.2010
comment
Возможно, у меня неправильный жаргон, но я использую тот же класс на основе SimpleCursorAdapter, но это не тот же экземпляр класса. Когда я говорю, что использую его повторно, я имею в виду, что он просто использует один и тот же класс в обоих местах, а не один и тот же экземпляр в обоих местах. - person Malachi; 23.08.2010
comment
Спасибо за совет по просмотру иерархии. После запроса список почему-то имеет высоту 0. Хотя переход на CheckedTextView может быть лучшим вариантом, в этом выпуске у меня нет времени на преобразование моих немного сложных элементов списка. Однако я приму это во внимание в будущем. - person Malachi; 23.08.2010
comment
@Malachi: я использую тот же класс на основе SimpleCursorAdapter, но это не тот же экземпляр класса - а, хорошо, все в порядке. После запроса список почему-то имеет высоту 0. -- если высота равна 0 и в списке есть дочерние элементы (строки), то проблема в вашем макете, вероятно, связанном с этим android:layout_weight. - person CommonsWare; 23.08.2010
comment
На самом деле, я думаю, что смотрел не на тот элемент. Список по-прежнему имеет ту же высоту и все еще виден, но дочерние элементы исчезли. И я не имею в виду, что видимость ИСЧЕЗЛА, ее просто нет вообще. Я посмотрю, что я могу понять, отличается между ними. - person Malachi; 23.08.2010
comment
Хорошо, исходя из этого, я добавил несколько операторов отладки вокруг вызова requery. Курсор имеет 28 элементов до запроса и 0 после, так что, похоже, это моя проблема. Теперь бы понять, почему так... - person Malachi; 23.08.2010
comment
Хорошо, я понял это. По сути, я принял некоторые решения в прошлом, которые были слишком умными. В исходной версии активности я повторно использовал только отображаемые данные, поэтому я открыл, а затем закрыл свой dbadapter. Список, который работает правильно, сохраняет экземпляр dbadapter открытым во время его работы. Запрос с закрытым dbadapter всегда ничего не возвращает... угу. Спасибо за вашу помощь. - person Malachi; 23.08.2010