使用反射+注解实现ORM关系映射,类似hmb,Spring等。
老规矩,先看一下使用效果:
调用:
ListBinder.With(mRecyclerView).setLtnImpl(this).bind(news)
Pojo类
@ListDataSrc(R.layout.list_item_card_main)
public class NewsListPojo implements Serializable{
@BindText(R.id.title)
private String title;
@BindText(R.id.content)
private String content;
@BindText(R.id.date)
private String date;
@BindAsyncImgUrl(R.id.cover)
private String coverurl;
@BindText(R.id.subcounts)
private String subscriptCounts;
@OnBtClick(R.id.subbt)
private String subscriptButton;
public NewsListPojo() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getCoverurl() {
return coverurl;
}
public void setCoverurl(String coverurl) {
this.coverurl = coverurl;
}
public String getSubscriptButton() {
return subscriptButton;
}
public void setSubscriptButton(String subscriptButton) {
this.subscriptButton = subscriptButton;
}
public String getSubscriptCounts() {
return subscriptCounts;
}
public void setSubscriptCounts(String subscriptCounts) {
this.subscriptCounts = subscriptCounts;
}
}
怎么样 很方便吧?
先讲一下大体的实现思路:
0x0:首先从宏观思考一下怎样把ViewId与数据Value联系起来。
0x00:反射获取类上(Type)的注解以获取Item的layoutId;
0x01:反射便利pojo类中的成员(field)并获取其上的注解,从注解中获取对应的itemViewID;
0x02:把上边这些信息存入某个Entity中;
0x03:想办法抽象出一个通用的Adapter和ViewHolder,抽象出类似 public void adapterCall(ViewHolder holder, int position); 的callback
0x04:在抽象出的adapterCall中invoke 0x02中Entity的信息
下面就来聊一下具体的。
1.首先应该想到每一对ORM映射对象应该都有一个实体类保存信息。而这些信息需要用到反射解析,所以考虑到性能,并且List每个Item一般类型都是相同的,所以应该在Adapter外解析完毕后再交由Adapter调用。首先是实体类
public class BinderTarget{
private Class type;
private Method method;
private Field field;
private Object ltnImpl;
private Method ltnMethod;
private Class ltnType;
public BinderTarget(Class type, Field field, Method method) {
this.type = type;
this.field = field;
this.method = method;
}
public BinderTarget(Object ltnImpl, Method ltnMethod, Class ltnType) {
this.ltnImpl = ltnImpl;
this.ltnMethod = ltnMethod;
this.ltnType = ltnType;
}
public Class getType() {
return type;
}
public void setType(Class type) {
this.type = type;
}
public Field getField() {
return field;
}
public void setField(Field field) {
this.field = field;
}
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public Object getLtnImpl() {
return ltnImpl;
}
public void setLtnImpl(Object ltnImpl) {
this.ltnImpl = ltnImpl;
}
public Method getLtnMethod() {
return ltnMethod;
}
public void setLtnMethod(Method ltnMethod) {
this.ltnMethod = ltnMethod;
}
public Class getLtnType() {
return ltnType;
}
public void setLtnType(Class ltnType) {
this.ltnType = ltnType;
}
}
可以看到存储的变量就分为两个部分,一是普通的控件负值类似textview.setText(str);,二是为控件添加监听,也是view.setListener(lsn);
即要存储的是1.Methed(对应setText与setListener)
2.Field(每个item对应list元素中的成员变量,就是str对应的Filed)
3.Class(参数的类型,Invoke需要用到)
private SparseArray<BinderTarget> bindlist;
第一篇的结尾 ,相信大家已经对实现方式有一些头绪了,那么就第二篇再做分解了 源码集成在我的小框架里GitHub