dhroid - NetJSONAdapter 网络化的adapter
关于adapter 我想对于大家来说已经不陌生了,基本应用都会用的很多,不知道现在你是不是还是按一定的套路写很多代码去实现adapter
我想大多数人还是写个adapter继承自baseadapter 实现getView方法(我想大家还会用网络流行的viewholder模式吧),
如果数据来自网络用个网络访问工具访问数据,数据转换,然后add进adapter,如果有下拉刷新,加载更多代码会更多
问题
1.你在写很多重复代码
2.数据管理不是那么容易
3.网络缓存需要处理
如果你使用dhroid框架,这些问题可以很好的解决
先看下下面的代码
NetJSONAdapter adapter=new NetJSONAdapter("http://shishangquan.017788.com/mobile_ordermeal_jujiList", this, R.layout.adapter_item); //添加参数 adapter.addparam("key1", "key1"); //数据绑定 adapter.addField("username", R.id.name); adapter.addField("title", R.id.title); //数据绑定 进行文本修饰 adapter.addField("pubdate", R.id.time,"time"); //数据绑定 进行图片修饰 adapter.addField("user_faceimg", R.id.pic,"round"); //缓存策略 adapter.useCache(CachePolicy.POLICY_CACHE_AndRefresh); //刷新 adapter.refresh(); //绑定到listview中 listV.setAdapter(adapter); //这段代码进行了网络访问,生成视图,数据绑定,缓存策略等问题
会通过R.layout.adapter_item生成视图,这里生成的视图用了重用机制,和ViewHolder模式(居然我感觉ViewHolder用处不大)
假设网络返回的结果是
{ success:true, data:[{ username:'藤之内', title:'大家好', pubdate:1394707561, user_faceimg:'头像路径' },{ }] }
NetJSONAdapter 会自动进行解析数据
会将username绑定到id为R.id.name的textview上
会将pubdate绑定到id为R.id.time 的textview上,这里需要进行数据转化,获取到的值是1394707561,最后显示当然为2012-11-08 我们在最后一个参数写为time ,具体的转化是写到ValueFix接口的(下面在说)
会将user_faceimg获取到的图片路径绑定到R.id.pic的imageView,这里也做了个转化,是将图片截圆角, 我们在最后一个参数写为round,具体的转化是写到ValueFix接口的(下面在说)
adapter.useCache(CachePolicy.POLICY_CACHE_AndRefresh);可以进行缓存策略,具体的缓存策略大家看DhNet的文档吧
adapter.refresh();刷新
我们先说网络相关的
添加参数 adapter.addparam("key1", "key1");// 加载下一页 adapter.showNext(); 加载下一页有对话框 adapter.showNextInDialog(); 缓存策略(查看dhnet文档) adapter.useCache(CachePolicy.POLICY_CACHE_AndRefresh); 加载第一页时是否有对话康 adapter.showProgressOnFrist(true);
数据处理相关
拿哪个节点作为数据(支持点分割)
adapter.fromWhat("aaa.bbb"); //如果你的结果不是在某个节点而是需要处理后才有的 adapter.setDataBulider(new DataBulider() { @Override public JSONArray onDate(Response response) { return response.jSONArrayFrom("xxx"); } }); adapter.addField("title", R.id.title); //数据绑定 进行文本修饰 adapter.addField("pubdate", R.id.time,"time"); //数据绑定 进行图片修饰 adapter.addField("user_faceimg", R.id.pic,"round"); 如果你需要控制显示与隐藏等 adapter.addField(new FieldMap("activeaddress", R.id.content) { @Override public Object fix(View itemV, Integer po, Object o, Object jo) { JSONObject joo=(JSONObject) jo; //这里可以做一些额外的工作 itemV.findViewById(R.id.icon).setVisibility(JSONUtil.getInt(joo, "status")==1?View.VISIBLE:View.INVISIBLE); return o; } });
事件回调每次加载完成后在这处理
//加载成功后回调 adapter.setOnLoadSuccess(new LoadSuccessCallBack() { @Override public void callBack(Response response) { if(response.isSuccess()){ dialoger.showToastShort(getActivity(), "加载成功"); if(adapter.getPageNo()==1){ listV.setSelection(0); } } } }); 内部点击事件 //内部点击事件 adapter.setOnInViewClickListener(R.id.pic, new BeanAdapter.InViewClickListener() { @Override public void OnClickListener(View itemV, View v, Integer po, Object jo) { JSONObject joo=(JSONObject) jo; dialoger.showToastLong(getActivity(), JSONUtil.getString(joo, "username")); } });
adapter需要配置的常量(配置在application中)
//分页参数 Const.netadapter_page_no = "p"; //分页参数的长度 Const.netadapter_step = "step"; //默认分页长度 Const.netadapter_step_default = 7; //时间线参数(传入后台的key) Const.netadapter_timeline = "timeline"; //时间线取哪个字段 Const.netadapter_json_timeline="pubdate";
关于时间线指每次会将上次最后一条的哪个属性作为下次访问的参数
下面说说上面提到的数据修饰问题
数据修饰需要在ioc中配置实现了ValueFix接口的类
接口有下面方法
如果是textview和且子类调用
public abstract Object fix(Object obj, String s); 传入第一个参数是原值第二个参数类型 如实现为 @Override public Object fix(Object o, String type) { if (o == null) return null; if ("time".equals(type)) { return getStandardTime(Long.parseLong (o.toString()) * 1000, "yyyy-MM-dd"); } return o; } 传入的是1394707561和'time' 返回的是2014-11-08 如果是imageview public abstract DisplayImageOptions imageOptions(String s); 出入的是类型 round返回的是DisplayImageOptions DisplayImageOptions 是universalimageloader.jar中的我们使用的是图片加载就是它
我还要说明下NetJSONAdapter的继承关系
NetJSONAdapter继承了BeanAdapter类实现了INetAdapter接口
BeanAdapter 对数据进行了很好的管理和视图绑定实现时
public abstract void bindView(View view, int i, Object obj);
可以仿照NetJSONAdapter的bindView实现
INetAdapter定义了网络相关的方法
public String getTag(); public void refresh(); public void setOnLoadSuccess(LoadSuccessCallBack loadSuccessCallBack); public void removeOnLoadSuccess(LoadSuccessCallBack loadSuccessCallBack); public void setOnTempLoadSuccess(LoadSuccessCallBack loadSuccessCallBack); public Boolean hasMore(); public void showNext(); // public boolean isLoding(); public void showNextInDialog();
这样在实现的listview中可以根据adapter的类型进行网络操作
如果你的list的item特别特别复杂我想你最好是写一个MyAdapter 继承自NetJSONAdapter,重新实现getView方法