views:

104

answers:

1

I have a fairly simple application that uses a ListActivity to display a ListView. Each ListView item has a CheckBox so that the user can specify favorite items. I am using a class that extends SimpleCursorAdapter so that I can capture both the CheckBox changed event (to save the change to the database) and the list item clicked event (to load an item details activity).

After the OnCheckChangedListener implementation updates the database, I call .requery() on the cursor so that when an item scrolls off and then back on to the screen, the CheckBox has the proper state.

That all works fine. Where I am having problems is in another activity where I am reusing the same ListView layout and the same cursor adapter to display a specific subset of items as part of a different activity's layout. When I use the layout there, everything is fine until I tap the CheckBox, at which point the entire ListView disappears. The database is updated, but until I leave the activity and come back, the ListView is just totally gone.

If I don't call .requery() on the cursor, everything works fine; the ListView does not disappear (but the CheckBox state will be wrong some of the time, as described above).

Working layout, 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"&gt;

    <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>

Broken layout, 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>

My only thought right now is that the way I am using layout_weight in the second layout is causing some weirdness. I am loath to change that, however, since it took me quite some time to get the layout to work the way I wanted it to in the first place.

One other note, when I am including the first layout in the second, I am hiding the TextView and CheckBox controls because they are unnecessary.

Any ideas what I am doing wrong here?

A: 

Where I am having problems is in another activity where I am reusing the same ListView layout and the same cursor adapter to display a specific subset of items as part of a different activity's layout.

If you mean the same instance of SimpleCursorAdapter, that is so not a good idea. Please make a new adapter.

When I use the layout there, everything is fine until I tap the CheckBox, at which point the entire ListView disappears. The database is updated, but until I leave the activity and come back, the ListView is just totally gone.

Use hierarchyviewer to determine if the ListView has no children (rows), has no height, is invisible/gone from a visibility standpoint, or is truly removed from the view hierarchy. That will give you better ideas of how to proceed.

Any ideas what I am doing wrong here?

Besides the adapter problem mentioned above, you're using CheckBox. Android has built-in support for multiple-select lists (e.g., android:choiceMode="multiple"), but that needs a CheckedTextView. I would aim to use Android's built-in multiple-selection logic rather than rolling your own.

CommonsWare
I may not have the lingo right, but I'm using the same class based on SimpleCursorAdapter, but it's not the same instance of the class. When I say I'm reusing it, I mean that it's just using the same class in both places, not the same instance in both places.
Malachi
Thanks for the hierarchyviewer tip. After the requery, the list has a height of 0 for some reason. While changing to a CheckedTextView may be a better option, I don't have time in this release to convert my slightly complicated list items. I will take that into consideration in the future, however.
Malachi
@Malachi: "I'm using the same class based on SimpleCursorAdapter, but it's not the same instance of the class" -- ah, OK, that is fine. "After the requery, the list has a height of 0 for some reason." -- if the height is `0` and the list does have children (rows), then the problem is in your layout, probably related to that `android:layout_weight`.
CommonsWare
Actually, I think I was looking at the wrong element. The list still has the same height and is still visible, but the children are gone. And I don't mean visibility GONE, they just aren't there at all. I'll see what I can figure out is different between the two.
Malachi
Okay, based on that, I added some debug statements around the requery call. The cursor has 28 items before the requery and 0 after, so that seems to be my problem. Now to figure out why that is the case...
Malachi
Okay, I figured it out. Basically I made some decisions in the past that were too clever. The original version of the activity I reused only displayed data, so I opened then closed my dbadapter. The list that works correctly keeps an instance of the dbadapter open while it is running. The requery with the closed dbadapter always brings back nothing... duh. Thanks for your help.
Malachi