layout.xml
<RelativeLayout 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: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="match_parent" android:layout_height="wrap_content" ></ListView> </RelativeLayout>
listview_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=""/> </LinearLayout>
parserJson.java
package com.example.parserJson; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.example.android_listview_baseadapter_downloadimg.Result; public class ParserJson { public static List<Result> parserJson(String path){ try { JSONObject jsonObject = new JSONObject(path); JSONArray jsonArray = jsonObject.getJSONArray("results"); List<Result> list = new ArrayList<Result>(); Result result; for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject2 = jsonArray.getJSONObject(i); result= new Result(); result.setNamecn(jsonObject2.getString("namecn")); result.setTitleimg(jsonObject2.getString("titleimg")); list.add(result); } return list; } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
HttpUtils.java
package com.example.HttpUtils; import java.io.IOException; import java.io.StringReader; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import android.graphics.Bitmap; import android.graphics.BitmapFactory; public class HttpUtils { //从网络下载json数据 public static String getJsonDataByIntetnet(String path){ byte[] buffer= getByteArrayByIntetnet(path); if(buffer != null && buffer.length != 0){ return new String(buffer); } return path; } //从网络获取字节数组 public static byte[] getByteArrayByIntetnet(String path){ try { DefaultHttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(path); HttpResponse httpResponse = client.execute(httpGet); if(200 == httpResponse.getStatusLine().getStatusCode()){ HttpEntity entity = httpResponse.getEntity(); return EntityUtils.toByteArray(entity); } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }return null; } //从网络上获取Bitmap对象 public static Bitmap getBitmapByIntetnet(byte[] byteArray){ if(byteArray != null && byteArray.length != 0){ return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); } return null; } }
UpdataNewView.java
package com.example.android_listview_baseadapter_downloadimg; import java.util.List; interface UpdateNewVIew { public abstract void updataNewView(List<Result>list); }
UpdateImgView.java
package com.example.android_listview_baseadapter_downloadimg; import android.graphics.Bitmap; public interface UpdateImgView { public void updateImgView(Bitmap bitmap); }
Result.java
package com.example.android_listview_baseadapter_downloadimg; public class Result { private String namecn; private String titleimg; public String getNamecn() { return namecn; } public void setNamecn(String namecn) { this.namecn = namecn; } public String getTitleimg() { return titleimg; } public void setTitleimg(String titleimg) { this.titleimg = titleimg; } }
MyAsyncTask.java
package com.example.android_listview_baseadapter_downloadimg; import java.util.List; import com.example.HttpUtils.HttpUtils; import com.example.parserJson.ParserJson; import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; public class MyAsyncTask extends AsyncTask<String, Integer, List<Result>>{ private UpdateNewVIew updateNewVIew; public MyAsyncTask(UpdateNewVIew updateNewVIew) { super(); this.updateNewVIew = updateNewVIew; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected List<Result> doInBackground(String... params) { String json = HttpUtils.getJsonDataByIntetnet(params[0]); List<Result> dataList = ParserJson.parserJson(json); return dataList; } @Override protected void onPostExecute(List<Result> result) { super.onPostExecute(result); if(result != null && result.size() != 0){ updateNewVIew.updataNewView(result); }else{ Log.i("MainActivity-MyAsyncTask", "网络错误"); } } }
MyAsyncTask1.java
package com.example.android_listview_baseadapter_downloadimg; import com.example.HttpUtils.HttpUtils; import android.content.Context; import android.graphics.Bitmap; import android.os.AsyncTask; public class MyAsyncTask1 extends AsyncTask<String, Integer, Bitmap>{ private UpdateImgView updateImgView; private Context context; public MyAsyncTask1(Context context,UpdateImgView updateImgView) { super(); this.updateImgView = updateImgView; this.context = context; } @Override protected void onPreExecute() { super.onPreExecute(); } //子线程下载图片 @Override protected Bitmap doInBackground(String... params) { //将传过来的图片下载存到字节数组中 byte[] byteArray = HttpUtils.getByteArrayByIntetnet(params[0]); //将字节数组转为Bitmap 类型,并传回给主线程 return HttpUtils.getBitmapByIntetnet(byteArray); } //主线程更新UI @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); if(result != null ){ //将参数回传给接口的实例化方法 updateImgView.updateImgView(result); } } }
main.java
package com.example.android_listview_baseadapter_downloadimg; import java.util.List; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.view.Menu; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView;
0.问题:
图片错位--例如:当我们首先显示item1时,会发送网络请求异步下载图片,当图片还没有下载完时,用户滑动了屏幕item1从屏幕中消失,新的摸个itmex会复用item1,而itemx的控件的引用时复用的item1,这时item1图片下载完成,设置图片的时候,会设置到itemx上,就错位了 图片闪烁--在错位的基础上,itemx显示item1图片的的时候,此时itemx本身的图片也下载完成,会再次将自己的图片设置给itemx,就闪烁了 1.解决:给每个图片控件设置一个tag,根据tag找到对应的控件,再设置图片
/*异步为listView的每个view下载图片-- * --网络请求json数据,将名字与图片显示在listview控件上 * 1.初始化控件 * 2.准备数据 * 2.1下载json数据 * 1)创建一个异步任务类下载(MyAsyncTask) * 2)解析json数据,将解析后的数据存到list(doInBackground()) * 3)将结果给主线程,然后显示(通过接口回调)(onPostExecute()) * 1)需实现baseAdapter的getView方法(MyAdapter) * 2)填充基本的数据类型 * 3)填充图片 * 1)创建一个异步任务通过图片地址从网络下载图片 (MyAsyncTask1) * 2)将下载后的图片以Bitmap对象形式存储(doInBackGround) * 3)将Bitmap数据返回给主线程(通过接口回调)(onPostExecute) * 4)image通过setBitmap()设置要显示的图片 * 3.在接口实现类的实现方法中创建适配器对象(UpdateNewView) * 4.设置适配器 * * */ public class MainActivity extends Activity { private ListView listView; private static final String path="http://openapi.db.39.net/app/GetDrugCompany?sign=9DFAAD5404FCB6168EA6840DCDFF39E5&app_key=app"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化控件 listView = (ListView) findViewById(R.id.listView); //准备数据 // 2.1下载json数据 // 1)创建一个异步任务类下载 new MyAsyncTask(new UpdateNewVIew() { @Override public void updataNewView(List<Result> list) { //创建适配器 MyAdapter myAdapter = new MyAdapter(list,MainActivity.this); //设置适配器 listView.setAdapter(myAdapter); } }).execute(path); } //自定义适配器 class MyAdapter extends BaseAdapter{ private List<Result>list; private Context context; public MyAdapter(List<Result> list,Context context) { super(); this.list = list; this.context = context; } /** * 通常返回数据源的长度,当返回0时没有显示 * 必须实现 */ @Override public int getCount() { return list.size(); } /** * position表示的是item对应的索引 * 通常根据索引来获得对应的数据,并返回 * 不是必须实现 */ @Override public Object getItem(int position) { return list.get(position); } /** * position表示的是item对应的索引 * 通常直接返回position作为item的id * 不是必须实现 */ @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; final ViewHolder viewHolder; if(view == null){ view = View.inflate(context, R.layout.listview_item, null); viewHolder = new ViewHolder(); viewHolder.text = (TextView) view.findViewById(R.id.text); viewHolder.image = (ImageView) view.findViewById(R.id.image); view.setTag(viewHolder); }else{ viewHolder = (ViewHolder) view.getTag(); } Result result = list.get(position); //设置文本资源 viewHolder.text.setText(result.getNamecn()); //设置图片资源 //创建异步任务,下载图片 String picPath = result.getTitleimg();
//解决错位问题
//给图片控件设置一个tag标记
viewHolder.image.setTag(picpath); new MyAsyncTask1(MainActivity.this,new UpdateImgView() { //设置图片资源 @Override public void updateImgView(Bitmap bitmap) {
//通过tag去找到对应的控件
ImageView img = (ImageView)parent.findViewWithTag(picPath);
if(img != null)
//设置图片
viewHolder.image.setImageBitmap(bitmap); } }).execute(picPath); return view; } class ViewHolder{ private TextView text; private ImageView image; } } }