Android 图文混排 异步加载图片

学习老罗课程的练习实例

1.原始json数据来自图灵机器人,URL为:http://www.tuling123.com/openapi/api?key=36082454b270b90d0900d25172097c98&info=%E9%85%92%E5%BA%97%E8%A5%BF%E5%AE%89。

json数据内容:

{"code":309000,"text":"亲,已帮您找到相关酒店","list":[{"name":"科逸连锁酒店西安东五路店","price":"¥ 94 起","icon":"http://himg.qunarzz.com/imgs/201311/21/NNNN2dcn2eNDs4qZN76.jpg","satisfaction":"经济型  4.0分/86评论 夜销","detailurl":""},{"name":"西安秦逸轩酒店","price":"¥ 141 起","icon":"http://himg.qunarzz.com/imgs/201311/01/GBUui7a0CnBXJ_p-776.jpg","satisfaction":"三星及舒适  4.5分/349评论 团 夜销","detailurl":""},{"name":"7天连锁酒店西安北大街地铁站莲湖...","price":"¥ 115 起","icon":"http://himg.qunarzz.com/imgs/201408/09/C.vl_s-HrNagwRlvMOb76.jpg","satisfaction":"经济型  4.3分/35评论 夜销","detailurl":""},{"name":"西安天域凯莱大饭店","price":"¥ 373 起","icon":"http://himg.qunarzz.com/imgs/201311/20/JhS1_thYpqAzJGq3J76.jpg","satisfaction":"五星级酒店  4.2分/376评论 夜销","detailurl":""},{"name":"西安左右客酒店","price":"¥ 432 起","icon":"http://himg.qunarzz.com/imgs/201410/10/Z7-ECTZWD9VeDR0UZ76.jpg","satisfaction":"高档(同四星)  4.4分/165评论 夜销","detailurl":""},{"name":"全季酒店西安北大街西五路店","price":"¥ 209 起","icon":"http://himg.qunarzz.com/imgs/201312/19/hFg6ita7XPcOSumyt76.jpg","satisfaction":"三星及舒适  4.6分/207评论 夜销","detailurl":""},{"name":"如家快捷西安钟楼东大街万达广场店","price":"¥ 95 起","icon":"http://himg.qunarzz.com/imgs/201105/14/88urcV8OW7zEFIek876.jpg","satisfaction":"经济型  4.3分/891评论 团 夜销","detailurl":""},{"name":"西安美桐年华酒店","price":"¥ 170 起","icon":"http://himg.qunarzz.com/imgs/201306/18/JhS1_tJdRiTaE_7QJ76.jpg","satisfaction":"二星及其他  4.5分/108评论 夜销","detailurl":""},{"name":"西安未来城好家商务酒店","price":"¥ 106 起","icon":"http://himg.qunarzz.com/imgs/201212/12/nz078uvDK4gMYrmEv76.jpg","satisfaction":"三星及舒适  4.0分/143评论 夜销","detailurl":""},{"name":"银座佳驿连锁酒店西安文艺北路店","price":"¥ 98 起","icon":"http://himg.qunarzz.com/imgs/201305/28/NNNN2dNl-61nwbNVN76.jpg","satisfaction":"经济型  4.2分/199评论 夜销","detailurl":""},{"name":"锦江之星西安大雁塔店","price":"¥ 149 起","icon":"http://himg.qunarzz.com/imgs/201306/25/x-bNpIC1E3PXt7jeC76.jpg","satisfaction":"经济型  4.5分/328评论 夜销","detailurl":""},{"name":"陕西晶顿酒店","price":"¥ 89 起","icon":"http://himg.qunarzz.com/imgs/201312/16/JhS1_thzpTZNh8jaJ76.jpg","satisfaction":"三星及舒适  4.4分/114评论 团 夜销","detailurl":""},{"name":"全季酒店西安钟楼新城广场店","price":"¥ 209 起","icon":"http://himg.qunarzz.com/imgs/201409/05/JhS1_tJMREmGkx0fJ76.jpg","satisfaction":"高档(同四星)  4.4分/35评论 团 夜销","detailurl":""},{"name":"西安新润水晶岛酒店","price":"¥ 318 起","icon":"http://himg.qunarzz.com/imgs/201203/12/Z7-ECTk6nr2kNI1kZ76.jpg","satisfaction":"高档(同四星)  4.3分/132评论 夜销","detailurl":""},{"name":"西安苹果之歌温泉酒店","price":"¥ 259 起","icon":"http://himg.qunarzz.com/imgs/201309/29/JhS1_thXpjy5bU3WJ76.jpg","satisfaction":"高档(同四星)  4.7分/175评论 夜销","detailurl":""}]}
2.activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textView_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="14dp"
        android:layout_marginTop="25dp"
        android:text="TextView" />

    <TextView
        android:id="@+id/textView_price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView_name"
        android:layout_below="@+id/textView_name"
        android:layout_marginTop="14dp"
        android:text="TextView" />

    <ImageView
        android:id="@+id/imageView_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@+id/textView_name"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>

3.Hotel类

package com.kelly.handler_product.bean;

public class Hotel {

	private String name;
	private String price;
	private String icon_path;

	public Hotel() {

	}

	public Hotel(String name, String price, String icon_path) {

		this.name = name;
		this.price = price;
		this.icon_path = icon_path;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPrice() {
		return price;
	}

	public void setPrice(String price) {
		this.price = price;
	}

	public String getIcon_path() {
		return icon_path;
	}

	public void setIcon_path(String icon_path) {
		this.icon_path = icon_path;
	}

}

4.适配器MyAdapter


package com.kelly.handler_product;

import java.util.List;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.kelly.handler_product.LoadNetPic.ImageCallback;
import com.kelly.handler_product.bean.Hotel;

public class MyAdapter extends BaseAdapter {

	private Context context;
	private LayoutInflater inflater;
	private List<Hotel> list = null;

	public MyAdapter() {
		// TODO Auto-generated constructor stub
	}

	public MyAdapter(Context context) {
		this.context = context;
		this.inflater = inflater.from(context);
	}

	public void setData(List<Hotel> list) {
		this.list = list;
	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return list.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return list.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		ViewHolder viewHolder = null;
		if (convertView == null) {
			convertView = inflater.inflate(R.layout.item, null);

			viewHolder = new ViewHolder();
			viewHolder.textView_name = (TextView) convertView
					.findViewById(R.id.textView_name);
			viewHolder.textView_price = (TextView) convertView
					.findViewById(R.id.textView_price);
			viewHolder.imageView_icon = (ImageView) convertView
					.findViewById(R.id.imageView_icon);

			convertView.setTag(viewHolder);

		} else {

			viewHolder = (ViewHolder) convertView.getTag();

		}
		viewHolder.textView_name.setText(list.get(position).getName());
		viewHolder.textView_price.setText(list.get(position).getPrice());
		// 这句是不得已啊,因为匿名内部类中要求必须是final 类型
		final ImageView imageView = viewHolder.imageView_icon;
		String image_path = list.get(position).getIcon_path();
		// 如何加载网络图片
		LoadNetPic loadNetPic = new LoadNetPic(image_path);
		loadNetPic.loadImage(new ImageCallback() {

			@Override
			public void getDrawable(Drawable drawable) {

				imageView.setImageDrawable(drawable);

			}
		});

		return convertView;
	}

	private static class ViewHolder {
		public TextView textView_name;
		public TextView textView_price;
		public ImageView imageView_icon;

	}

}


5.LoadNetPic.java下载网络图片 (接口回调)


package com.kelly.handler_product;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;

public class LoadNetPic {

	private String image_path;

	public LoadNetPic(String image_path) {

		this.image_path = image_path;
	}

	// 接口的回调
	public interface ImageCallback {

		public void getDrawable(Drawable drawable);
	}

	public void loadImage(final ImageCallback callback) {
		final Handler handler = new Handler() {

			@Override
			public void handleMessage(Message msg) {

				super.handleMessage(msg);

				callback.getDrawable((Drawable) msg.obj);
			}
		};

		new Thread(new Runnable() {

			@Override
			public void run() {

				try {
					Drawable drawable = Drawable.createFromStream(new URL(
							image_path).openStream(), "");
					Message message = Message.obtain();
					message.obj = drawable;
					handler.sendMessage(message);

				} catch (MalformedURLException e) {

					e.printStackTrace();
				} catch (IOException e) {

					e.printStackTrace();
				}

			}
		}).start();

	}

}


6.MainActivity.java

package com.kelly.handler_product;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.kelly.handler_product.bean.CommonUrl;
import com.kelly.handler_product.bean.Hotel;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ListView;

public class MainActivity extends Activity {

	private ListView listView;
	private MyAdapter adapter;
	private MyTask myTask;
	private List<Hotel> hotellist;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		listView = (ListView) findViewById(R.id.listview);
		adapter = new MyAdapter(this);
		String url = CommonUrl.url;
		new MyTask().execute(url);

	}

	public class MyTask extends AsyncTask<String, Integer, List<Hotel>> {

		@Override
		protected void onPreExecute() {

			hotellist = new ArrayList<Hotel>();
			super.onPreExecute();
		}

		@Override
		protected List<Hotel> doInBackground(String... params) {
			// TODO Auto-generated method stub
			// 连接网络获取json数据并进行解析

			try {
				HttpClient client = new DefaultHttpClient();
				HttpPost get = new HttpPost(params[0]);
				HttpResponse response = client.execute(get);

				int code = response.getStatusLine().getStatusCode();
				if (code == 200) {
					HttpEntity entity = response.getEntity();
					String jsonString = EntityUtils.toString(entity, "UTF-8");
					JSONObject root = new JSONObject(jsonString);
					JSONArray jsonArray = root.getJSONArray("list");
					for (int i = 0; i < jsonArray.length(); i++) {
						Hotel hotel = new Hotel();
						JSONObject object = jsonArray.getJSONObject(i);
						String name = object.getString("name");
						String price = object.getString("price");
						String icon_path = object.getString("icon");
						hotel.setName(name);
						hotel.setPrice(price);
						hotel.setIcon_path(icon_path);
						hotellist.add(hotel);
					}

				}

			} catch (ClientProtocolException e) {

				e.printStackTrace();
			} catch (IOException e) {

				e.printStackTrace();
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			return hotellist;
		}

		@Override
		protected void onPostExecute(List<Hotel> result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			adapter.setData(result);
			listView.setAdapter(adapter);
			adapter.notifyDataSetChanged();// 不要忘了这句
		}

	}

}


其中还有很多可以优化的地方,例如缓存图片等


代码下载地址:点击打开链接





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值