我正在构建一个动态打印值/项目列表的配置程序。有时您需要输出一项,例如姓名,但有时您可能需要输出多项,例如 IP 地址、用户名、密码等。
这个想法是根据输出的参数数量动态地建立一个列表。在小屏幕上,参数的数量可能是 2,但在横向模式或平板电脑上,参数的数量可能要高得多。
当我有一个带有 Android ID 的硬编码 XML 文件时,我有这个工作,即引用
android:id="@+id/item1
但我正在努力以编程方式执行此操作。在编辑之前,我用 ID 来做这件事,但根据建议,我现在宁愿用标签来尝试。
这里是代码的所有相关部分。如果输出多行参数列表,我们分支到 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);
}
这是构建布局:
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);
}
}
下面是我尝试引用 ID 的方式:
/**
* 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 中我添加了 TextView ,但在自定义数组适配器中,layoutinflator 找不到这些字段。我还更新了代码以尝试使用标签而不是 ID。
从 buildLayout 调试。注意四个 child ,两个固定在 XML 代码中,另外两个创建
从 ParamsAdapter 调试。请注意,在我实际尝试访问这些对象的这个阶段只有两个 child 。
最佳答案
如果您以编程方式创建项目,我建议您使用“tag”参数。它不如 id 快,但是您不必为此担心速度 - 只要您有父 View ,您就可以“findViewWithTag” - 参见 http://developer.android.com/reference/android/view/View.html - 向下滚动到 findViewWithTag
关于自定义列表适配器中动态创建的 TextView 上的 Android findViewById 似乎不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9352031/