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>
Add this include to your list layout:
<include layout="@android:layout/list_content" />
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white" />
This worked for me....
Documentation on android site: http://developer.android.com/reference/android/app/ListFragment.html
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
Added in API level 11 Provide default implementation to return a simple list view. Subclasses can override to replace with their own layout. If doing so, the returned view hierarchy must have a ListView whose id is android.R.id.list and can optionally have a sibling view id android.R.id.empty that is to be shown when the list is empty.
If you are overriding this method with your own custom content, consider including the standard layout list_content in your layout file, so that you continue to retain all of the standard behavior of ListFragment. In particular, this is currently the only way to have the built-in indeterminant progress state be shown.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With