views:

1423

answers:

3

[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 http://stackoverflow.com/questions/2548304/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>

+1  A: 

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.

synic
If I set back to Activity, how should I call setListAdapter for a list of new items?
Yang
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!
hackbod
then basically you are saying this classic article is wrong? http://www.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.
Yang
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.
synic
I do see lots of similar posts around, and ppl are definitely using ListActivity without a ListView: http://stackoverflow.com/questions/2451744/how-do-i-vertically-align-an-item-within-a-list-using-relative-layout
Yang
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
synic
+2  A: 

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! :)

Steve H
Thanks I tried it out and it did give a list of items. However, why the text are all empty in this case?
Yang
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.
Steve H
interesting! Using your layout the text is not empty. But my layout listed above becomes empty! Any idea why?
Yang
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.
Steve H
[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?
Yang
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 H
Here's another tutorial for lists that looks a bit easier to read than the one I originally gave you: http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/
Steve H
A: 

Actually, your (custom) layout doesn't need a ListView when using a list activity. The easy way to solve this is just remove the setContentView() line altogether. In simple terms, when you do it, Android "assumes" the layout you're using to contain a single full-screen ListView, and provides it for you.

If you want a different (richer) interface for the Activity though, you must code the XML and use the informed ID for Android to know how to show the list implied by the activity being a ListActivity after all. Note that the layout for an item isn't the same as the list, and although I haven't tried that, I assume you can have a custom item layout without having an explicit ListView in the activity layout.

Rafael Almeida