ArrayAdapter требует, чтобы ID был ошибкой TextView - PullRequest
3 голосов
/ 30 декабря 2011

Я пытаюсь создать хороший макет для своих элементов списка, но мой код работает только тогда, когда он упрощен, как это:

<?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>

Когда я добавляю немного больше, он компилируется и запускается, но онforce закрывается при запуске и выдает мне ошибку 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>

и

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();
            }
        });
    }

Я почти уверен, что делаю это правильно, я прошел через многочисленные урокии я обнаружил, что самый быстрый и эффективный способ - создать статический класс ViewHolder.В одном из учебных пособий я попытался получить прямой доступ к данным, что я и пытался сделать.Я все еще немного запутался в том, как это сделать.

    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;

    }
}

Ответы [ 4 ]

2 голосов
/ 30 декабря 2011

Вы, вероятно, используете что-то вроде этого ( здесь документ ):

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

в этом случае ваш макет должен быть простым макетом с TextView.

Если вы хотите использовать свой собственный макет, вам нужно написать собственный адаптер.

1 голос
/ 30 декабря 2011

Создайте свой собственный ArrayAdapter, тогда вы сможете настроить макет так, как вам нравится.

0 голосов
/ 14 сентября 2016

Вы, кажется, на правильных линиях.Я не уверен, что именно проблема с вашим кодом, поскольку я не сравнивал близко, но он работает в этом примере .

Полный учебник находится здесь: Учебник по Android дляначинающие - 97 - ListView с пользовательским макетом

Это позволяет избежать ошибки ArrayAdapter requires ID to be a TextView, которую я также получаю.

0 голосов
/ 16 июля 2013

ArrayAdapter требует, чтобы идентификатор ресурса был исключением TextView XML, что означает, что вы не предоставляете то, что ожидает ArrayAdapter. Когда вы используете этот конструктор:

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

R.Layout.a_layout_file должен быть идентификатором файла макета xml, содержащего только TextView (TextView не может быть обёрнут другим макетом, таким как LinearLayout, RelativeLayout и т. Д.), Что-то вроде этого:

<?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
/>

Если вы хотите, чтобы макет строки вашего списка был немного другим, тогда простой виджет TextView использует этот конструктор:

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

, где вы предоставляете идентификатор макета, который может содержать различные представления, но также должен содержать TextView с и id (третий параметр), который вы передаете в ArrayAdapter, чтобы он мог знать, куда поместить строки в макете строки .

...