数据准备
本案例中的服务端数据以Json的形式传递,在服务端使用.Net开发一个一般处理程序,序列化一个产品对象,里面包含名称、价格、图片名称, 最后序列化成JSON格式的数据返回给客户端。
数据如下
1 [{"imageName":"image1.png","name":"苹果","price":12},
2 {"imageName":"image2.png","name":"闹钟","price":56},
3 {"imageName":"image3.png","name":"蛋糕","price":24},
4 {"imageName":"image4.png","name":"零钱包","price":8},
5 {"imageName":"image5.png","name":"书本","price":42},
6 {"imageName":"image6.png","name":"糖果","price":16},
7 {"imageName":"image7.png","name":"西瓜","price":2}]
本案例的URL地址均使用一个CommonUri类进行管理:
1 package com.example.handlerimageortext;
2
3 public class CommonUri {
4// 访问服务器数据的链接
5public static final String PRODUCT_URL = "http://192.168.1.102:1231/json/returnCommondityJson.ashx";
6// 图片的连接
7public static final String PRODUCT_IMG="http://192.168.1.102:1231/json/img/";
8 }
使用AsyncTask获取Json数据
在UI线程中,使用AsyncTask的方式访问网络获取JSON数据,并对其进行解析
1public class MyTask extends AsyncTask<String, Void, List<Map<String,Object>>>{
2@Override
3protected void onPreExecute() {
4super.onPreExecute();
5// 显示对话框
6dialog.show();
7}
8
9@Override
10protected List<Map<String, Object>> doInBackground(String... params) {
11List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
12try {
13// 获取网络JSON格式数据
14HttpClient httpClient=new DefaultHttpClient();
15HttpPost httpPost=new HttpPost(params[0]);
16HttpResponse httpResponse=httpClient.execute(httpPost);
17if(httpResponse.getStatusLine().getStatusCode()==200){
18String jsonString=EntityUtils.toString(httpResponse.getEntity(),"utf-8");
19// 解析Json格式数据,并使用一个List<Map>存放
20JSONArray jsonArray=new JSONArray(jsonString);
21for(int i=0;i<jsonArray.length();i++){
22JSONObject jsonObject=jsonArray.getJSONObject(i);
23Map<String,Object> map=new HashMap<String, Object>();
24map.put("name",jsonObject.get("name"));
25map.put("price",jsonObject.get("price"));
26map.put("imageName",jsonObject.get("imageName"));
27list.add(map);
28}
29}
30} catch (Exception e) {
31e.printStackTrace();
32}
33return list;
34}
35@Override
36protected void onPostExecute(List<Map<String, Object>> result) {
37super.onPostExecute(result);
38// 把查询到的数据传递给适配器
39adapter.setData(result);
40// 为ListView设定适配器
41listview.setAdapter(adapter);
42adapter.notifyDataSetChanged();
43// 隐藏对话框
44dialog.dismiss();
45}
46}
下载图片信息
上面的方法中,使用AsyncTask访问网络获取到产品的信息,其中有图片的名称,可以通过这个地址下载图片到本地。
新创建一个类,用于下载图片,但是需要在主线程中访问图片的信息,可以使用接口回调的方式在Handler中处理子线程发送过来的消息。注释比 较全,这里就不再累述了。
1 package com.example.handlerimageortext;
2
3 import java.io.IOException;
4 import java.net.MalformedURLException;
5 import java.net.URL;
6 import android.graphics.drawable.Drawable;
7 import android.os.Handler;
8 import android.os.Message;
9
10 public class DownLoadImage {
11private String image_path;
12
13public DownLoadImage(String image_path) {
14// 保存图片的下载地址
15this.image_path = image_path;
16}
17
18public void loadImage(final ImageCallback callback) {
19final Handler handler = new Handler() {
20@Override
21public void handleMessage(Message msg) {
22super.handleMessage(msg);
23// 接受到消息后,调用接口回调的方法
24callback.getDrawable((Drawable) msg.obj);
25}
26};
27// 开启一个新线程用于访问图片数据
28new Thread(new Runnable() {
29
30@Override
31public void run() {
32try {
33// 下载图片为Drawable对象
34Drawable drawable = Drawable.createFromStream(new URL(
35image_path).openStream(), "");
36// 把图片对象包装成一个消息发送给Handler
37Message message = Message.obtain();
38message.what = 1;
39message.obj = drawable;
40handler.sendMessage(message);
41} catch (MalformedURLException e) {
42e.printStackTrace();
43} catch (IOException e) {
44e.printStackTrace();
45}
46}
47}).start();
48}
49
50// 定义一个公开的接口,用于执行回调操作
51public interface ImageCallback {
52public void getDrawable(Drawable draw);
53}
54 }
数据的适配器
上面已经获取到Json数据中产品的数据,和产品的图片,现在声明一个Adapter类,继承自BaseAdapter,使用一个布局XML资 源文件,用于填充数据。
1public class MyAdapter extends BaseAdapter{
2private Context context;
3private LayoutInflater layoutInflater;
4private List<Map<String,Object>> list=null;
5public MyAdapter(Context context){
6this.context=context;
7layoutInflater=LayoutInflater.from(context);
8}
9
10public void setData(List<Map<String,Object>> list){
11this.list=list;
12}
13
14@Override
15public int getCount() {
16return list.size();
17}
18
19@Override
20public Object getItem(int position) {
21return list.get(position);
22}
23
24@Override
25public long getItemId(int position) {
26return position;
27}
28
29@Override
30public View getView(int position, View convertView, ViewGroup parent) {
31View view=null;
32if(convertView==null){
33// 如果View为空,则以布局XML资源文件填充View
34view=layoutInflater.inflate(R.layout.item,null);
35}else{
36view=convertView;
37}
38TextView name=(TextView)view.findViewById(R.id.textView1);
39TextView price=(TextView)view.findViewById(R.id.textView2);
40// 因为需要在回调接口中访问这个ImageView控件,所以需要声明为final
41final ImageView imageview=(ImageView)view.findViewById(R.id.imageView1);
42name.setText(list.get(position).get("name").toString());
43price.setText(list.get(position).get("price").toString());
44
45// 使用DownLoadImage,下载地址代表的图片
46DownLoadImage downLoadImage=new DownLoadImage
(CommonUri.PRODUCT_IMG+list.get(position).get("imageName").toString());
47// 使用回调接口,设置ImageView的图片
48downLoadImage.loadImage(new ImageCallback() {
49@Override
50public void getDrawable(Drawable draw) {
51imageview.setImageDrawable(draw);
52}
53});
54return view;
55}
56}
效果展示: