3

I am trying to create a nice layout for my list items, but my code only works when it is simplified like this:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="16sp" >
</TextView>

When I add a little bit more it compiles and runs but it force closes on start and gives me the error ArrayAdapter requires ID to be a TextView:

<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/icon1"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentBottom="true"
        android:layout_alignParentTop="true"
        android:layout_marginRight="6dip"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/secondLine"
        android:layout_width="fill_parent"
        android:layout_height="26dip"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@id/icon1"
        android:ellipsize="marquee"
        android:singleLine="true"
        android:text="Some more information" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/secondLine"
        android:layout_alignParentTop="true"
        android:layout_alignWithParentIfMissing="true"
        android:layout_toRightOf="@id/icon1"
        android:gravity="center_vertical"
        android:text="Some Information" />

    <ImageView
        android:id="@+id/icon2"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginRight="6dip"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>

and

public class FirstLoginActivity extends ListActivity {

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

        String[] testcontacts = getResources().getStringArray(
                R.array.testcontacts_array);
        setListAdapter(new ArrayAdapter<String>(this, R.layout.list_items,
                testcontacts));

        ListView lv = getListView();
        lv.setTextFilterEnabled(true);

        lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // When clicked, show a toast with the TextView text
                Toast.makeText(getApplicationContext(),
                        ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
            }
        });
    }

I am pretty sure I'm doing this right, I've been through numerous tutorials and I've found that the fastest and most efficient way is to create a static ViewHolder class. One of the tutorials tried accessing the data directly which is what I was trying to do. I'm still a little confused on how to do so.

    public class FirstLoginActivity extends ListActivity {
    Context mContext;
    List mList;

    String[] testcontacts = getResources().getStringArray(
            R.array.testcontacts_array);

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

        setListAdapter(new ArrayAdapter<String>(this, R.layout.list_items,
                testcontacts));

        ListView lv = getListView();
        lv.setTextFilterEnabled(true);

        lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                // When clicked, show a toast with the TextView text
                Toast.makeText(getApplicationContext(),
                        ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
            }
        });
    }



    public View getView(int position, View convertview, ViewGroup parent) {
        ViewHolder holder;
        View v = convertview;
        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) LayoutInflater
                    .from(mContext);
            v = inflater.inflate(R.layout.list_items, null);
            holder = new ViewHolder();
            holder.firstLine = (TextView) v.findViewById(R.id.firstLine);
            holder.secondLine = (TextView) v.findViewById(R.id.secondLine);
            holder.icon1 = (ImageView) v.findViewById(R.id.icon1);
            holder.icon2 = (ImageView) v.findViewById(R.id.icon2);
            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
        }
        holder.firstLine.setText(testcontacts[position]);
        holder.secondLine.setText(testcontacts[position]);
        // holder.icon1.setImageBitmap((position & 1) == 1 ? mIcon1: mIcon2);
        //call the images directly?
        return v;
    }

    static class ViewHolder {
        TextView firstLine;
        TextView secondLine;
        ImageView icon1;
        ImageView icon2;

    }
}
SharpC
  • 6,974
  • 4
  • 45
  • 40
The Tokenizer
  • 1,564
  • 3
  • 29
  • 46
  • follow the first answer from the below link [http://stackoverflow.com/questions/9280965/arrayadapter-requires-the-resource-id-to-be-a-textview-xml-problems][1] [1]: http://stackoverflow.com/questions/9280965/arrayadapter-requires-the-resource-id-to-be-a-textview-xml-problems – User10001 Aug 15 '13 at 20:34

4 Answers4

2

You are probably using something like this (here the doc):

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.layout_1, values);

in that case your layout must be a simple layout with a TextView.

If you wanna use your own layout you need to write a custom adapter.

gwvatieri
  • 5,133
  • 1
  • 29
  • 29
1

Build your own ArrayAdapter, then you can make the layout work however you would like.

Ashterothi
  • 3,282
  • 1
  • 21
  • 35
  • 1
    Also, ArrayAdapter has another constructor which takes any resource as an input and you can specify TextView id used for populating http://developer.android.com/reference/android/widget/ArrayAdapter.html#ArrayAdapter(android.content.Context, int, int, T[]) . – harism Dec 29 '11 at 21:54
  • Can you direct me to a good tutorial that could teach me how to create my own listAdapter? – The Tokenizer Dec 30 '11 at 00:55
  • 1
    http://www.youtube.com/watch?v=wDBM6wVEO70 Is the developers explaining how listviews work, and how to make them work right. – Ashterothi Dec 30 '11 at 00:56
  • Thanks that Video really helped alot, but now i'm stuck at accessing my information directly to show in my listview. – The Tokenizer Dec 30 '11 at 05:14
0

The ArrayAdapter requires the resource ID to be a TextView XML exception means you don't supply what the ArrayAdapter expects. When you use this constructor:

new ArrayAdapter<String>(this, R.layout.a_layout_file, this.file)

R.Layout.a_layout_file must be the id of a xml layout file containing only a TextView(the TextView can't be wrapped by another layout, like a LinearLayout, RelativeLayout etc!), something like this:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" 
    // other attributes of the TextView
/>

If you want your list row layout to be something a little different then a simple TextView widget use this constructor:

new ArrayAdapter<String>(this, R.layout.a_layout_file, 
   R.id.the_id_of_a_textview_from_the_layout, this.file)

where you supply the id of a layout that can contain various views, but also must contain a TextView with and id(the third parameter) that you pass to your ArrayAdapter so it can know where to put the Strings in the row layout.

Sathish
  • 1,455
  • 1
  • 16
  • 22
  • What if my ArrayAdapter uses cell which is custom layout and have many text views in the cell? – NinjaCoder Apr 04 '14 at 22:27
  • It wont be a problem. Instead of single button or textview, You can use multiple views in the arrayadapter. @NinjaCoder – Sathish Apr 08 '14 at 09:38
0

You seem to be on the right lines. I'm not sure the exact issue with your code as I've not compared closely, but it works in this example.

The full tutorial is here: Android tutorial for beginners - 97 - ListView with Custom Layout

This avoids the error ArrayAdapter requires ID to be a TextView which I was also getting.

SharpC
  • 6,974
  • 4
  • 45
  • 40