Я строю программу конфигурации, которая распечатывает списки значений / элементов динамически.Иногда у вас будет один элемент для вывода, например, имя, но в других случаях у вас может быть несколько элементов, которые вы хотите вывести, например, 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-коде, а два созданы
Отладка из ParamsAdapter.Обратите внимание, что на этом этапе только два ребенка пытаются получить доступ к этим объектам.