对于每个具有差异行布局模板的列表视图,我必须创建每个自定义适配器,它们执行相同的操作:加载xml行布局,通过id获取控件(TextView,ImageView等),显示数据...像这样的东西:
public class CommentAdapter extends BaseAdapter {
protected Activity activity;
protected static LayoutInflater layoutInflater = null;
protected List<Comment> lst;
public CommentAdapter(Activity activity, List<Comment> lst){
this.activity = activity;
this.lst = lst;
layoutInflater = (LayoutInflater)this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return lst.size();
}
public Object getItem(int position) {
return lst.get(position);
}
public long getItemId(int position) {
return position;
}
public static class ViewHolder{
public TextView textName;
public TextView textComment;
public ImageView image;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder viewHolder;
if (v == null) {
v = layoutInflater.inflate(R.layout.listitem, null);
viewHolder = new ViewHolder();
viewHolder.textName = (TextView) v.findViewById(R.id.txtName);
viewHolder.image = (ImageView) v.findViewById(R.id.icon);
viewHolder.textComment = (TextView)v.findViewById(R.id.txtComment);
v.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) v.getTag();
}
Static.overrideFonts(v);
viewHolder.image.setBackgroundResource(lst.get(position).Icon);
viewHolder.textName.setText(lst.get(position).Name);
viewHolder.textComment.setText(lst.get(position).Comment);
return v;
}
}
使用多种列表视图(差异行布局模板),我必须创建许多适配器。
所以,问题是我想创建一个模板适配器,它可以是动态加载行xml,基于它的id的地图视图控件(也许使用反射)。行xml布局,控件ID,视图控件将在其他地方定义
是否有design pattern
,example
或framework
可以实现此目标?
答案 0 :(得分:8)
这样的事似乎可行。我根本没有测试过这个,但理论上你可以用这样的东西来逃避:
public interface Adaptable {
//Interface that any object you make that should be put in a listview
//should implement
public View buildView(View v, LayoutInflater inflater);
public int getLayoutId();
}
public class MyObject implements Adaptable
//Just hardcode your layout for this type of object
public int getLayoutId() {
return R.layout.myLayout;
}
//getView() will pass the recycled view to this method
//which will handle building the view per this object
public View buildView(View v, LayoutInflater inflater) {
if(v == null) {
v = inflater.inflate(getLayoutId());
//Other initialization
} //other initialization
return v;
}
}
//Then make the generic adapter that handles anything that implements
//the Adaptable interface
public GenericAdapter implements ListAdapter {
private LayoutInflater inflater;
private List<Adaptable> items;
public GenericAdapter(List<Adaptable> items, Context c) {
this.items = items;
inflater = LayoutInflater.from(c);
}
//Now, using polymorphism, it should return a correctly built
//view for whatever object type you've passed in.
@Override
public View getView(int pos, View convertView, ViewGroup parent) {
return items.get(pos).buildView(convertView, inflater);
}
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
List<MyObject> objects = new ArrayList<MyObject>();
//Fill your list however.
//get your ListView, then...
listView.setAdapter(new GenericAdapter(object, this));
}
我可能完全忽略了一些不起作用的原因 - 我在五分钟内输入了这个。从理论上讲,我认为它会起作用。
答案 1 :(得分:2)
我尝试了 kcoppock 的方式,但我做的更复杂一些。
首先,我创建一个ViewHolder,它可以使用注释与视图id进行映射。
public class MobileViewHolder {
@InvokeView(viewId = R.id.label)
public TextView text;
@InvokeView(viewId = R.id.logo)
public ImageView image;
}
然后,我可以使用reflect:
在ViewHolder中使用view id映射字段 Field fs[] = viewHolder.getClass().getFields();
for (Field f : fs) {
InvokeView a = (InvokeView)f.getAnnotation(InvokeView.class);
int id = a.viewId();
f.set(viewHolder, v.findViewById(id));
}
之后,我只是将实体中的数据绑定到ViewHolder。
public void mappingData(MobileViewHolder viewHolder, Mobile entity) {
viewHolder.text.setText(entity.name);
viewHolder.image.setBackgroundResource(entity.image);
}
结论:这样,对于多种列表视图哪个区别行布局模板,我只需要4件事:
以下是我测试的source code样本:)