如何使用 Viewholder 模式在 Listview 行中膨胀不同的布局
How to inflate different layout in Listview row using Viewholder pattern
为了学习 Android 编程,我正在尝试编写一个小型词典程序。
目前我正在尝试列出所有条目但没有成功:
一个条目可以有多个定义:
Entry 1
Definition 1.1
Entry 2
Definition 2.1
Definition 2.2
Definition 2.3
Entry 3
Definition 3.1
Definition 3.2
Entry 4
Definition 4.1
但是有一些不清楚的地方我要问一下:
我有三个 xml 文件(所有三个都是 LinearLayout 类型):
1) fragment_entries : it contains one ListView
android:id="@+id/list_view_entries"
2) fragment_entries_row : it contains one TextView
android:id="@+id/text_view_entries_word"
3) fragment_entries_definitions_row : it contains two TextViews
android:id="@+id/definitions_row_word_type"
android:id="@+id/definitions_row_meaning"
还有一个适配器:
EntriesAdapter extends ArrayAdapter<EntryVO>
事情变得混乱的 getView 方法:
@Override
public View getView(int position, View listViewEntriesRow, ViewGroup parent) {
ViewHolder viewHolder = null;
if (listViewEntriesRow == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
listViewEntriesRow = inflater.inflate(R.layout.fragment_entries_row, null);
viewHolder = new ViewHolder();
viewHolder.entriesWord = (TextView) listViewEntriesRow.findViewById(R.id.text_view_entries_word);
viewHolder.entriesDefinitions = inflater.inflate(R.layout.fragment_entries_definitions_row, null);
listViewEntriesRow.setTag(viewHolder);
} else
viewHolder = (ViewHolder) listViewEntriesRow.getTag();
EntryVO entryVO = getItem(position);
for (DefinitionVO definitionVO : entryVO.getDefinitions()) {
here : inflate 3rd xml in every loop ?
// definitionVO.getType()
// definitionVO.getMeaning()
}
return listViewEntriesRow;
}
最后 ViewHolder class 看起来像这样:
private static class ViewHolder {
TextView entriesWord; // of 2nd xml file
View entriesDefinitions; // 3rd xml file
}
我被卡住了,因为我必须在循环中膨胀第 3 个 xml 文件内容以将其附加到条目文本视图下,这看起来不正确(至少在性能方面)。
你能帮帮我吗?
提前致谢。
如果我没理解错的话...每个条目可以有多个定义。即一个条目可以有任意数量的定义......如果是这样的话。尝试将你的行 xml 设置成这样:
<Layout> //
<Entry/> // TextView for Entry
<ListView/> // Listview for Definitions... that can be populated depending upon the number of definitions for that entry/position
</Layout>
现在您可以通过按位置查询 Models/Data 来在适配器中实现您想要的。
我改用 RecyclerView 解决了这个问题。
<RelativeLayout>
<android.support.v7.widget.RecyclerView>
</RelativeLayout>
每个条目都是一个卡片视图:
<android.support.v7.widget.CardView>
在条目适配器中:
@Override
public void onBindViewHolder(EntryViewHolder vh, int position) {
final EntryVO entryVO = entries.get(position);
vh.cv.removeAllViewsInLayout();
vh.cv.addView(EntriesAdapter.createEntryCardViewTable(context, entryVO, new ReadListener(context)));
}
最后,在 createEntryCardViewTable 方法中,我以编程方式构建了一个 TableLayout,就像 HTML table 一样,其中包含条目及其定义的行。
尽管有 1000 多个条目(每个条目可能有多个定义),但性能还是很棒的。
为了学习 Android 编程,我正在尝试编写一个小型词典程序。 目前我正在尝试列出所有条目但没有成功:
一个条目可以有多个定义:
Entry 1
Definition 1.1
Entry 2
Definition 2.1
Definition 2.2
Definition 2.3
Entry 3
Definition 3.1
Definition 3.2
Entry 4
Definition 4.1
但是有一些不清楚的地方我要问一下:
我有三个 xml 文件(所有三个都是 LinearLayout 类型):
1) fragment_entries : it contains one ListView
android:id="@+id/list_view_entries"
2) fragment_entries_row : it contains one TextView
android:id="@+id/text_view_entries_word"
3) fragment_entries_definitions_row : it contains two TextViews
android:id="@+id/definitions_row_word_type"
android:id="@+id/definitions_row_meaning"
还有一个适配器:
EntriesAdapter extends ArrayAdapter<EntryVO>
事情变得混乱的 getView 方法:
@Override
public View getView(int position, View listViewEntriesRow, ViewGroup parent) {
ViewHolder viewHolder = null;
if (listViewEntriesRow == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
listViewEntriesRow = inflater.inflate(R.layout.fragment_entries_row, null);
viewHolder = new ViewHolder();
viewHolder.entriesWord = (TextView) listViewEntriesRow.findViewById(R.id.text_view_entries_word);
viewHolder.entriesDefinitions = inflater.inflate(R.layout.fragment_entries_definitions_row, null);
listViewEntriesRow.setTag(viewHolder);
} else
viewHolder = (ViewHolder) listViewEntriesRow.getTag();
EntryVO entryVO = getItem(position);
for (DefinitionVO definitionVO : entryVO.getDefinitions()) {
here : inflate 3rd xml in every loop ?
// definitionVO.getType()
// definitionVO.getMeaning()
}
return listViewEntriesRow;
}
最后 ViewHolder class 看起来像这样:
private static class ViewHolder {
TextView entriesWord; // of 2nd xml file
View entriesDefinitions; // 3rd xml file
}
我被卡住了,因为我必须在循环中膨胀第 3 个 xml 文件内容以将其附加到条目文本视图下,这看起来不正确(至少在性能方面)。
你能帮帮我吗?
提前致谢。
如果我没理解错的话...每个条目可以有多个定义。即一个条目可以有任意数量的定义......如果是这样的话。尝试将你的行 xml 设置成这样:
<Layout> //
<Entry/> // TextView for Entry
<ListView/> // Listview for Definitions... that can be populated depending upon the number of definitions for that entry/position
</Layout>
现在您可以通过按位置查询 Models/Data 来在适配器中实现您想要的。
我改用 RecyclerView 解决了这个问题。
<RelativeLayout>
<android.support.v7.widget.RecyclerView>
</RelativeLayout>
每个条目都是一个卡片视图:
<android.support.v7.widget.CardView>
在条目适配器中:
@Override
public void onBindViewHolder(EntryViewHolder vh, int position) {
final EntryVO entryVO = entries.get(position);
vh.cv.removeAllViewsInLayout();
vh.cv.addView(EntriesAdapter.createEntryCardViewTable(context, entryVO, new ReadListener(context)));
}
最后,在 createEntryCardViewTable 方法中,我以编程方式构建了一个 TableLayout,就像 HTML table 一样,其中包含条目及其定义的行。
尽管有 1000 多个条目(每个条目可能有多个定义),但性能还是很棒的。