Search code examples
androidlistactivityandroid-datepicker

setListAdapter sets the DatePicker list instead of my ListView in ListActivity


Inserting a <DatePicker> element into my layout XML is crashing my app:

java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to android.widget.CalendarView$WeekView

It is visible until my Cursors load, but is malformed and does not display the days in the month:

Malformed DateSelector

For the sake of demonstration, here is a sample layout XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <DatePicker
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <ListView
        android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

And here is some java to go with it:

public class TestDatePicker extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_date_picker);

        DatePickerAdapter myAdapter = new DatePickerAdapter();
        setListAdapter(myAdapter);
    }
}

class DatePickerAdapter extends BaseAdapter {
    @Override
    public int getCount() { return 0; }

    @Override
    public Object getItem(int i) { return null; }

    @Override
    public long getItemId(int i) { return 0; }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) { return null;}
}

I've figured out that in this simple example, my <DatePicker> is messed up because setListAdapter() is controlling the ListView used within the DatePicker instead of the ListView in my XML. Placing the DatePicker AFTER the ListView resolves the issue, but this seems fragile. I'm guessing DatePicker's list uses @android:id/list too?

Is this a bug? Am I using setListAdapter() incorrectly? Should I refrain from using a DatePicker within a ListActivity altogether?


Solution

  • Yes, it indeed looks like DatePicker uses a list with the same identifier. What the Android framework developers recommend is to host the DatePicker in it's own DialogFragment(http://developer.android.com/guide/topics/ui/controls/pickers.html). Since you do not need this in a DialogFragment, I would recommend having the DatePicker in it's own Fragment (if it is supposed to be part of the display and not a dialog) and have the ListView object be part of a ListFragment and have your activity display these two fragments. This way neither one of them would interact with each other and you would still get the expected behavior.

    Also on a side note, I usually use a ListActivity only when I have to display a list (and maybe a simple widget). When you have to use ViewGroups (as in DatePicker, TimePicker, etc.), it would pobably be a better idea to refrain from using the ListActivity specifically for the reason you mentioned - the inned lists of these widgets may already be using the same identifier.