Android findViewById для динамически создаваемых текстовых представлений в адаптере пользовательских списков не работает - PullRequest
1 голос
/ 19 февраля 2012

Я строю программу конфигурации, которая распечатывает списки значений / элементов динамически.Иногда у вас будет один элемент для вывода, например, имя, но в других случаях у вас может быть несколько элементов, которые вы хотите вывести, например, IP-адрес, имя пользователя, пароль и т. Д.

Идея состоит в том,строить список динамически в зависимости от количества выводимых параметров.На маленьком экране количество параметров может быть 2, но в ландшафтном режиме или на планшете количество параметров может быть намного выше.

У меня это работает, когда у меня есть жестко запрограммированный XML-файл с идентификаторами Androidто есть ссылаясь на

android:id="@+id/item1

, но я борюсь с этим программно.До редактирования я делал это с идентификаторами, но по совету я сейчас скорее пробую это с тегами.

Вот все соответствующие части кода.Если выводится многострочный список параметров, мы разветвляемся на buildLayout для создания пользовательского макета:

public void processAsyncTask(String result) {       
        ConfigList list = getConfigList(result);
        ArrayList<ConfigCollection> mParamsList = list.getAllItems();
        // Once we have a list of parameters we build the layout according to size
        buildLayout(mParamsList.size());
        mMultiRowAdapter = new ParamsAdapter(this, R.layout.multi_row_config, mParamsList);         
        mCollectionListView.setAdapter(mMultiRowAdapter);           
        }

Вот buildLayout:

private void buildLayout(int size) {                
    TableRow tr = (TableRow)findViewById(R.id.row_multi_row);                       
    for (int i = 0; i < size - 1; i++) {
        TextView tv = new TextView(this);
        tv.setId(i);
        tv.setTag("id" + String.valueOf(i));
        tv.setTextAppearance(this, android.R.style.TextAppearance_Large);
        tv.setText("id" + String.valueOf(i));
        tr.addView(tv);
    }               
}

А вот как я пытаюсьчтобы сослаться на идентификаторы:

/**
     * Custom Array Adapter with a view that displays multi-line item/value pairs 
     */
    private class ParamsAdapter extends ArrayAdapter<ConfigCollection> {

        private ArrayList<ConfigCollection> objectList;

        public ParamsAdapter(Context context, int textViewResourceId, ArrayList<ConfigCollection> objectList) {
            super(context, textViewResourceId, objectList);
            this.objectList = objectList;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;

            LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.multi_row_config, null);             

            // It works with hard coded IDs, e.g.:
            TextView tv1 = (TextView) v.findViewById(R.id.item1);
            TextView tv2 = (TextView) v.findViewById(R.id.item2);

            // BELOW DOES NOT, tv1 and tv2 is null after assignment
            TextView tv1 = (TextView) v.findViewWithTag("id0");
        TextView tv2 = (TextView) v.findViewWithTag("id1");

Вот XML-файл, который я использую для тестирования:

<?xml version="1.0" encoding="utf-8"?>

<TableLayout    
    android:id="@+id/table_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

     <ListView
        android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"        
    />

    <TableRow
    android:id="@+id/row_multi_row"
    >

    <TextView
        android:id="@+id/item1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"                
        android:textAppearance="?android:attr/textAppearanceLarge"              
        android:text="item1"    
        android:padding="3dip"
    />

    <TextView
        android:id="@+id/item2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"                
        android:textAppearance="?android:attr/textAppearanceLarge"              
        android:text="item2"
        android:padding="3dip"  
    />  

    </TableRow>

</TableLayout>

РЕДАКТИРОВАТЬ: я выделил проблему, более заметную здесь со скриншотами,Кажется, в buildLayout я добавляю textviews, но в адаптере пользовательского массива layoutinflator не находит эти поля.Я также обновил код, чтобы попытаться работать с тегами вместо идентификаторов.

Отладка из buildLayout.Обратите внимание на четырех дочерних элементов, два из которых зафиксированы в XML-коде, а два созданы

Debug from buildLayout. Notice four children, the two fixed in the XML code and two created

Отладка из ParamsAdapter.Обратите внимание, что на этом этапе только два ребенка пытаются получить доступ к этим объектам.

Debug from ParamsAdapter. Notice only two children at this stage

1 Ответ

1 голос
/ 19 февраля 2012

Если вы создаете элементы программно, я бы посоветовал использовать параметр "tag".Это не так быстро, как id, но вы не беспокоитесь о скорости - пока у вас есть родительское представление, вы можете "findViewWithTag" - см. http://developer.android.com/reference/android/view/View.html - прокрутить вниз до findViewWithTag

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...