Android: failed to setContentView when switching to ListActivity

16,948

Solution 1

I think you misunderstood the other posts I showed you in the previous question. They were explaining how to use a custom layout for each row in your list, not how to define the entire layout file for the activity. You need something like this:

(main.xml)
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:cacheColorHint="#00000000"
    android:id="@android:id/list">
</ListView>

Note the very important line android:id="@android:id/list". You must have that in your ListView as that's what tells Android where your list is. The cacheColorHint is useful if your background isn't black - see this post for more details about that.

With the above lines you can give your activity a list that will be recognised properly. Here's a basic example:

public class TestProject extends ListActivity {

    final static String[] ITEMS = {"blah", "floop", "gnarlp", "stuff"};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                R.layout.listrow, R.id.textview, ITEMS);
        setListAdapter(adapter);
    }
}

Then the listrow layout is just this:

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

    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textview"/>
</LinearLayout>

This is a really simple layout. If you want to get something more complicated, changes are you'll have to use a BaseAdapter, as that gives you calls getView(...) before each row. In that you can use different layouts depending on the contents of each row. However, BaseAdapter looks scary when you first try it, so be warned! :)

Solution 2

Yes, if you are using a ListActivity, you need to have a ListView who's id is android.R.list in your layout file.

If you aren't using a ListView in your layout, and I don't see one in there, then switch to using a regular Activity.

Share:
16,948
Yang
Author by

Yang

Updated on June 04, 2022

Comments

  • Yang
    Yang almost 2 years

    [update] I got the error, which says "Your content must have a ListView whose id attribute is 'android.R.id.list'". Appearently nothing in my xml is ListView. But is that required?

    This is an follow-up issue on my previous question android: which view should I use for showing text and image?

    I read the article about creating ListView for LinearLayout. However, my following code failed at the setContentView() function when I changed "extends Activity" to "extends ListActivity", any idea why?

    private TextView mSelection;
    //private ImageView mImages;
    static final String[] keywords = new String[]{"China", "Japan", "USA", "Canada"};
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        setContentView(R.layout.contactLayout);
    
        mSelection = (TextView)findViewById(R.id.ContactNames);
        ArrayAdapter adapter = new ArrayAdapter<String>(this, R.layout.contactlayout, R.id.ContactNames,keywords);
        setListAdapter(adapter);
        }
    

    My Layout is from this article: http://www.curious-creature.org/2009/02/22/android-layout-tricks-1/

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    
    android:padding="6dip">
    
    <ImageView
        android:id="@+id/icon"
    
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginRight="6dip"
    
        android:src="@drawable/icon" />
    
    <LinearLayout
        android:orientation="vertical"
    
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="fill_parent">
    
        <TextView
            android:id="@+id/ContactNames"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
    
            android:gravity="center_vertical"
            android:text="My Application" />
    
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1" 
    
            android:singleLine="true"
            android:ellipsize="marquee"
            android:text="Simple application that shows how to use RelativeLayout" />
    
    </LinearLayout>
    

  • Yang
    Yang about 14 years
    If I set back to Activity, how should I call setListAdapter for a list of new items?
  • hackbod
    hackbod about 14 years
    If you don't have a list view, it makes no sense to want to call setListAdapter() -- there is no list view to display whatever adapter you give it!
  • Yang
    Yang about 14 years
    then basically you are saying this classic article is wrong? androidguys.com/2008/07/14/fancy-listviews-part-one I'm trying to create a list view of items that contain both icon and text for each of them.
  • synic
    synic about 14 years
    I don't know how you can read that article. The formatting is terrible. Either way, you can't have a list of items using a ListActivity without a ListView being in your layout xml file, and you are definitely missing that.
  • Yang
    Yang about 14 years
    I do see lots of similar posts around, and ppl are definitely using ListActivity without a ListView: stackoverflow.com/questions/2451744/…
  • synic
    synic about 14 years
    I think what you're trying to do is define a single row in your list, however, you still need a container layout for your ListView, and that's what you should be using for setContentView() in your activity, not the layout for a single row. That will be used later in your ListAdapter
  • Yang
    Yang about 14 years
    Thanks I tried it out and it did give a list of items. However, why the text are all empty in this case?
  • Steve Haley
    Steve Haley about 14 years
    They weren't empty for me... Could you update the code you've got posted above? It's probably an error with your ArrayAdapter adapter = new ArrayAdapter<String>(this, R.layout.contactlayout, R.id.ContactNames,keywords); line if you're still using that. What I used worked fine - I made sure to test it before posting it online.
  • Yang
    Yang about 14 years
    interesting! Using your layout the text is not empty. But my layout listed above becomes empty! Any idea why?
  • Steve Haley
    Steve Haley about 14 years
    The layout given in your question is still a layout for a custom row in a list, not the list as a whole. If you mean that you used that as a row, then the problem is probably that the R.id.... of the TextViews aren't the same.
  • Yang
    Yang about 14 years
    [update] {you know what just happened? I changed RelativeLayout to LinearLayout and it worked..hmm..... } I made sure the R.id I set in the adapter is indeed the one in XML file. don't know what's going on there... Do you think I should extend the adapter (which one?) and write my own getview() function?
  • Steve Haley
    Steve Haley about 14 years
    For more interesting lists, you should extend BaseAdapter. But as I wrote above, that requires a lot more code. It's not actually all that complicated once you understand what it's doing, but it does take a bit of patience, and a lot of trial and error to get it right. Certainly don't try it until you fully understand what's happening with this simple list. That would probably just confuse you...
  • Steve Haley
    Steve Haley about 14 years
    Here's another tutorial for lists that looks a bit easier to read than the one I originally gave you: softwarepassion.com/…