我使用ArrayAdapter创建了一个ListView。有用。但是我必须将项目布局的资源id放两次:在适配器定义和getView中,在View参数为null的情况下。
// --------------------------------------------here is the FIRST use
lvShows.setAdapter(new ArrayAdapter<TvShow>(this, R.layout.show_row, allKnownShows) {
@Override
public View getView(int position, final View rowView, ViewGroup parent) {
LinearLayout showView;
if (rowView == null) {
// --------------------------------- here is the SECOND use
showView = (LinearLayout) inflater.inflate(R.layout.show_row, parent, false);
}
else {
showView = (LinearLayout) rowView;
}
((TextView) showView.getChildAt(0)).setText(time));
((TextView) showView.getChildAt(1)).setText(name);
return showView;
}
});
当然,这种风格很恶心。请问,我是什么意思错了,我怎么能只使用一次资源呢?
如果创建一个新的ArrayAdapter我正在设置布局ID,它应该知道它并以某种方式使用。我怎么能达到它?或者更好,我希望Adapter能够自动创建项目视图。再次 - 我该如何使用它?
ArrayAdapter在创建新资源时对我们提供的资源做了什么?它的所有构造函数都使用项目资源,我们管理此资源并“手动”对其进行充气。这不是有效的方式。
答案 0 :(得分:2)
您可以覆盖ArrayAdapter构造函数并调用super:
public ArrayAdapter<T>(Context context, TheDataType data) {
super(context, R.layout.show_row, data);
}
将id存储在ArrayAdapter成员变量中。它避免适配器“user”知道适配器所需的视图。
或者您可以使用BaseAdapter。
答案 1 :(得分:2)
我查看了ArrayAdapter的源代码,它已经完成了有关视图创建的所有内容:
// citation from public class ArrayAdapter<T>
private View createViewFromResource(int position, View convertView, ViewGroup parent,
int resource) {
View view;
TextView text;
if (convertView == null) {
view = mInflater.inflate(resource, parent, false);
} else {
view = convertView;
}
所以,我们应该简单地使用它:
lvShows.setAdapter(new ArrayAdapter<TvShow>(this,
R.layout.show_row,
R.id.nameField,
allKnownShows){
public View getView(int position, final View convertView, ViewGroup parent) {
LinearLayout showView = (LinearLayout) super.getView(position, convertView, parent);
setAnythingForItem(showView);
return showView;
}
注意:我们已经更改了构造函数!
ArrayAdapter允许使用no-TextView项目布局。但是如果它不是TextView本身,它应该有一个,并且这个非常内部的TextView字段的id应该作为第三个参数提供给构造函数。 ArrayAdapter需要设置它,如果连接到它的数组具有String元素,则在那里写入字符串。
如果数组由对象而不是字符串组成,它总是希望TextView,即使它不需要它。另外,它检查项目布局是否为TextView,如果不是,则抛出错误。