Search code examples
androidandroid-listfragment

ListFragment gives ListView whose id attribute is 'android.R.id.list'


I'm trying to implement a simple list/detail view as in figure 1 here but I'm getting a "Your content must have a ListView whose id attribute is 'android.R.id.list'" runtime exception. This error seems to have been discussed at length if the amount of results is anything to go by, but most of the answers seem to be about extending ListActivity whereas I'm extending ListFragment. So far I've had no luck in getting it fixed. The base activity is:

SpeciesListActivity.java

public class SpeciesListActivity extends MenuItemActivity {

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

        // Check if the species_detail view is available. If it is
        // we're running both fragments together.
        if (findViewById(R.id.species_detail) != null) {
        }
    }
}

The fragments are included via its layout file:

activity_species_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:baselineAligned="false"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment android:name="com.example.fragments.SpeciesListFragment"
            android:id="@+id/species_list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="net.gamebreeder.fragments.SpeciesDetailFragment"
            android:id="@+id/species_detail"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>

This is the two pane layout, the single pane one is the same except for the second fragment (id species_detail) not being included.

The fragment in question:

SpeciesListFragment.java

public class SpeciesListFragment extends ListFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_species_list, container, false);
    }
}

And the fragment's layout:

fragment_species_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="8dp"
    android:paddingRight="8dp">

    <ListView android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:drawSelectorOnTop="false"/>

    <TextView android:id="@id/android:empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/empty_string"/>

</LinearLayout>

I've tried changing SpeciesListFragment to not override onCreateView() to force it to use the defaults, since according to the docs:

Note: If your fragment is a subclass of ListFragment, the default implementation returns a ListView from onCreateView(), so you don't need to implement it.

But I still get: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'

One question I found suggested I ensure that I'm extending FragmentActivity in the main activity and that's exactly what MenuItemActivity is:

public class MenuItemActivity extends FragmentActivity {

It's basically just a wrapper so I don't have to manually create the menu in every activity.

Any help would be appreciated - I'm hoping I'm just missing something simple.

Edit 2013-06-27

I've tried formatting the id in the fragment_species_list.xml as both @id/android:list and @android:id/list but neither work. The docs say to use @id/android:list but the other questions I've read seem to suggest that both should work but I get the error with both. I've tried with @+id/list as well.

I've also changed the following based on the answers below:

activity_species_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:baselineAligned="false"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment class="com.example.fragments.SpeciesListFragment"
            android:id="@+id/species_list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment class="net.gamebreeder.fragments.SpeciesDetailFragment"
            android:id="@+id/species_detail"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>

Solution

  • I'm not sure what exactly caused this but I managed to solve it by deleting all the old fragment, activity and layout files which were originally created with an ADT eclipse template.

    I basically re-wrote everything from scratch, one piece at a time to ensure everything is getting called correctly. I suspect that this was simply due to all references not being updated in the compiled code despite cleaning out all the compiled code numerous times (both manually and with the eclipse project clean tool).