`
guanhuaing
  • 浏览: 1196416 次
文章分类
社区版块
存档分类
最新评论

ListView显示网络图片的方法

 
阅读更多

今天在网上找了一整天如何实现ListView显示网络图片的方法

1:显示的图片比较小(1-2张)。这样我觉得不需要使用异步来加载,直接使用位图显示就OK

2:显示的图片比较多,可以使用异步加载。但存在BUG:单显示的条目很多。ListView需要往下拉的时候。图片不能显示,但是使用1的方法却能全部显示出来

参考资料:http://hulefei29.iteye.com/blog/616262

例子:

1、定义主界面,在界面里面添加一个ListView控件

main.xml

Xml代码
1.<?xml version="1.0" encoding="utf-8"?>
2.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:orientation="vertical"
4. android:layout_width="wrap_content"
5. android:layout_height="fill_parent">
6.<TextView
7. android:id="@+id/indexTitle"
8. android:layout_width="fill_parent"
9. android:gravity="center"
10. android:layout_height="wrap_content"
11. android:text="使用ListView显示图片"/>
12.<ListView
13. android:id="@+id/searchList"
14. android:layout_width="fill_parent"
15. android:layout_height="wrap_content"
16. android:choiceMode="singleChoice" />
17.</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent">
<TextView
android:id="@+id/indexTitle"
android:layout_width="fill_parent"
android:gravity="center"
android:layout_height="wrap_content"
android:text="使用ListView显示图片"/>
<ListView
android:id="@+id/searchList"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:choiceMode="singleChoice" />
</LinearLayout>

2、定义Item页面

search_list.xml

Xml代码
1.<?xml version="1.0" encoding="utf-8"?>
2.<LinearLayout
3.xmlns:android="http://schemas.android.com/apk/res/android"
4.android:layout_width="wrap_content"
5.android:layout_height="wrap_content">
6.
7. <ImageView android:id="@+id/stationImg"
8. android:layout_width="wrap_content"
9. android:layout_height="wrap_content"
10. android:minWidth="80px"
11. android:maxWidth="80px"
12. android:minHeight="45px"
13. android:maxHeight="45px"
14. android:scaleType="fitXY"
15. android:src="@drawable/icon"
16. android:layout_margin="5px"/>
17. <LinearLayout android:orientation="vertical"
18. android:layout_width="wrap_content"
19. android:layout_height="wrap_content">
20.
21. <TextView android:id="@+id/stationTitle"
22. android:layout_width="wrap_content"
23. android:layout_height="wrap_content"
24. android:textColor="#FFFFFFFF"
25. android:textSize="22px"
26. />
27.
28. <TextView
29. android:id="@+id/stationInfo"
30. android:layout_width="wrap_content"
31. android:layout_height="wrap_content"
32. android:textColor="#FFFFFFFF"
33. android:textSize="13px" />
34. </LinearLayout>
35.
36.</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<ImageView android:id="@+id/stationImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="80px"
android:maxWidth="80px"
android:minHeight="45px"
android:maxHeight="45px"
android:scaleType="fitXY"
android:src="@drawable/icon"
android:layout_margin="5px"/>
<LinearLayout android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<TextView android:id="@+id/stationTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="22px"
/>

<TextView
android:id="@+id/stationInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="13px" />
</LinearLayout>

</LinearLayout>

三、定义MainActivity

MainActivity.java

Java代码
1.package lee.listviewimage;
2.
3.import java.util.ArrayList;
4.import java.util.HashMap;
5.import java.util.List;
6.import java.util.Map;
7.import lee.listviewimage.R;
8.import android.app.Activity;
9.import android.os.Bundle;
10.import android.widget.ListView;
11.
12.
13.public class MainActivity extends Activity {
14.// private List<Map<String, Object>> generateData(List<XXXX> xxxxs) {
15.// List<Map<String, Object>> resList = new ArrayList<Map<String, Object>>();
16.// for (Iterator<XXXX> iterator = xxxxs.iterator(); iterator
17.// .hasNext();) {
18.// XXXX xxxx= (XXXX) iterator.next();
19.// Map<String, Object> resMap = new HashMap<String, Object>();
20.// resMap.put("title", xxxx.getTitle());
21.// resMap.put("info", xxxx.getInfo());
22.// resMap.put("img", xxxx.getImageUrl());
23.// resList.add(resMap);
24.// }
25.// return resList;
26.// }
27.
28. ListView view;
29. List<Map<String, Object>> resList;
30. @Override
31. public void onCreate(Bundle savedInstanceState) {
32. super.onCreate(savedInstanceState);
33. setContentView(R.layout.main);
34. view = (ListView) findViewById(R.id.searchList);
35. resList = new ArrayList<Map<String, Object>>();
36.
37. Map<String, Object> resMap = new HashMap<String, Object>();
38. resMap.put("title", "title111");
39. resMap.put("info", "111111");
40. resMap.put("img", "http://tb.himg.baidu.com/sys/portrait/item/d71e5a30323837797979d300");
41. resList.add(resMap);
42.
43. resMap = new HashMap<String, Object>();
44. resMap.put("title", "title222");
45. resMap.put("info", "222222");
46. resMap.put("img", "http://img.baidu.com/img/post-jg.gif");
47. resList.add(resMap);
48.
49.
50. SearchAdapter adapter = new SearchAdapter(
51. this,resList, R.layout.search_list,
52. new String[] {"title", "info", "img" },
53. new int[] {R.id.stationTitle, R.id.stationInfo,R.id.stationImg
54. });
55.
56. view.setAdapter(adapter);
57. }
58.}
package lee.listviewimage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lee.listviewimage.R;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;


public class MainActivity extends Activity {
//private List<Map<String, Object>> generateData(List<XXXX> xxxxs) {
// List<Map<String, Object>> resList = new ArrayList<Map<String, Object>>();
// for (Iterator<XXXX> iterator = xxxxs.iterator(); iterator
// .hasNext();) {
// XXXX xxxx= (XXXX) iterator.next();
// Map<String, Object> resMap = new HashMap<String, Object>();
// resMap.put("title", xxxx.getTitle());
// resMap.put("info", xxxx.getInfo());
// resMap.put("img", xxxx.getImageUrl());
// resList.add(resMap);
// }
// return resList;
// }

ListView view;
List<Map<String, Object>> resList;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
view = (ListView) findViewById(R.id.searchList);
resList = new ArrayList<Map<String, Object>>();

Map<String, Object> resMap = new HashMap<String, Object>();
resMap.put("title", "title111");
resMap.put("info", "111111");
resMap.put("img", "http://tb.himg.baidu.com/sys/portrait/item/d71e5a30323837797979d300");
resList.add(resMap);

resMap = new HashMap<String, Object>();
resMap.put("title", "title222");
resMap.put("info", "222222");
resMap.put("img", "http://img.baidu.com/img/post-jg.gif");
resList.add(resMap);

SearchAdapter adapter = new SearchAdapter(
this,resList, R.layout.search_list,
new String[] {"title", "info", "img" },
new int[] {R.id.stationTitle, R.id.stationInfo,R.id.stationImg
});

view.setAdapter(adapter);
}
}

四、定义通过图片url返回图片Bitmap的工具类"(如果不需要异步,直接调用这个方法)

WebImageBuilder.java

Java代码
1.package lee.listviewimage;
2.
3.import java.io.IOException;
4.import java.io.InputStream;
5.import java.net.HttpURLConnection;
6.import java.net.MalformedURLException;
7.import java.net.URL;
8.
9.import android.graphics.Bitmap;
10.import android.graphics.BitmapFactory;
11.
12.public class WebImageBuilder {
13.
14. /**
15. * 通过图片url返回图片Bitmap
16. * @param url
17. * @return
18. */
19. public static Bitmap returnBitMap(String path) {
20. URL url = null;
21. Bitmap bitmap = null;
22. try {
23. url = new URL(path);
24. } catch (MalformedURLException e) {
25. e.printStackTrace();
26. }
27. try {
28. HttpURLConnection conn = (HttpURLConnection) url.openConnection();//利用HttpURLConnection对象,我们可以从网络中获取网页数据.
29. conn.setDoInput(true);
30. conn.connect();
31. InputStream is = conn.getInputStream(); //得到网络返回的输入流
32. bitmap = BitmapFactory.decodeStream(is);
33. is.close();
34. } catch (IOException e) {
35. e.printStackTrace();
36. }
37. return bitmap;
38. }
39.}
package lee.listviewimage;

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

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class WebImageBuilder {

/**
* 通过图片url返回图片Bitmap
* @param url
* @return
*/
public static Bitmap returnBitMap(String path) {
URL url = null;
Bitmap bitmap = null;
try {
url = new URL(path);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();//利用HttpURLConnection对象,我们可以从网络中获取网页数据.
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();//得到网络返回的输入流
bitmap = BitmapFactory.decodeStream(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
}

五、定义异步加载图片的工具类

AsyncImageLoader.java

Java代码
1.package lee.listviewimage;
2.import java.lang.ref.SoftReference;
3.import java.net.URL;
4.import java.util.HashMap;
5.import java.util.Map;
6.import android.graphics.drawable.Drawable;
7.import android.os.Handler;
8.import android.os.Message;
9.
10.public class AsyncImageLoader {
11. private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
12.
13. public Drawable loadDrawable(final String imageUrl,final ImageCallback callback) {
14.
15. if (imageCache.containsKey(imageUrl)) {
16. SoftReference<Drawable> softReference = imageCache.get(imageUrl);
17. if (softReference.get() != null) {
18. return softReference.get();
19. }
20. }
21. final Handler handler = new Handler() {
22. @Override
23. public void handleMessage(Message msg) {
24. callback.imageLoaded((Drawable) msg.obj, imageUrl);
25. }
26. };
27. //load data
28. new Thread() {
29. public void run() {
30. Drawable drawable = loadImageFromUrl(imageUrl);
31. imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
32. handler.sendMessage(handler.obtainMessage(0, drawable));
33. };
34. }.start();
35.
36. return null;
37. }
38.
39. protected Drawable loadImageFromUrl(String imageUrl) {
40. try {
41. return Drawable.createFromStream(new URL(imageUrl).openStream(),
42. "src");
43. } catch (Exception e) {
44. throw new RuntimeException(e);
45. }
46. }
47.
48. //call back interface
49. public interface ImageCallback {
50. public void imageLoaded(Drawable imageDrawable, String imageUrl);
51. }
52.
53.}
package lee.listviewimage;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;

public class AsyncImageLoader {
private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();

public Drawable loadDrawable(final String imageUrl,final ImageCallback callback) {

if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
if (softReference.get() != null) {
return softReference.get();
}
}
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
callback.imageLoaded((Drawable) msg.obj, imageUrl);
}
};
//load data
new Thread() {
public void run() {
Drawable drawable = loadImageFromUrl(imageUrl);
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
handler.sendMessage(handler.obtainMessage(0, drawable));
};
}.start();

return null;
}

protected Drawable loadImageFromUrl(String imageUrl) {
try {
return Drawable.createFromStream(new URL(imageUrl).openStream(),
"src");
} catch (Exception e) {
throw new RuntimeException(e);
}
}

//call back interface
public interface ImageCallback {
public void imageLoaded(Drawable imageDrawable, String imageUrl);
}

}

六、定义异步加载图片的方法

PS:原文章说只有 public SearchAdapter构造方法和 public void setViewImage(final ImageView v, String url)有用,其他都是源代码。理论上可以去掉不写,但去掉后确不能正常显示图片,有全部都是同一张图片,或者只显示1条数据,但去掉的方法却可以不在异步的显示图片中测试成功。(看第七点)

SearchAdapter.java

Java代码
1.package lee.listviewimage;
2.import java.util.HashMap;
3.import java.util.List;
4.import java.util.Map;
5.import android.content.Context;
6.import android.graphics.Bitmap;
7.import android.graphics.drawable.Drawable;
8.import android.view.LayoutInflater;
9.import android.view.View;
10.import android.view.ViewGroup;
11.import android.widget.Checkable;
12.import android.widget.ImageView;
13.import android.widget.SimpleAdapter;
14.import android.widget.TextView;
15.
16.public class SearchAdapter extends SimpleAdapter {
17.
18. private AsyncImageLoader imageLoader = new AsyncImageLoader();
19. private Map<Integer, View> viewMap = new HashMap<Integer, View>();
20. private ViewBinder mViewBinder;
21. private List<? extends Map<String, ?>> mData; //List列表存放的数据
22. private int mResource; //绑定的页面 ,例如:R.layout.search_item,
23. private LayoutInflater mInflater;
24. private String[] mFrom; //绑定控件对应的数组里面的值名称
25. private int[] mTo; //绑定控件的ID
26.
27. //构造器
28. public SearchAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to) {
29. super(context, data, resource, from, to);
30. mData = data;
31. mResource = resource;
32. mFrom = from;
33. mTo = to;
34. // 布局泵(LayoutInflater)根据XML布局文件来绘制视图(View)对象。这个类无法直接创建实例,要通过context对象的getLayoutInflater()或getSystemService(String)方法来获得实例,这样获得的布局泵实例符合设备的环境配置。
35. mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
36. }
37.
38.
39. /*
40. SimpleAdapter基类显示每个Item都是通过这个方法生成的
41. 在getView(int position, View convertView, ViewGroup parent)中又调用了SimpleAdapter的私有方法createViewFromResource
42. 来组装View,在createViewFromResource中对SimpleAdapter的参数String[] from 和int[] to进行了组装
43. */
44. public View getView(int position, View convertView, ViewGroup parent) {
45. return createViewFromResource(position, convertView, parent, mResource); //调用下面方法
46. }
47.
48.
49. //在createViewFromResource方法中又有一个bindView(position, v)方法对item中的各个View进行了组装,bindView(position, v)
50. private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) {
51. View rowView = this.viewMap.get(position);
52.
53. if (rowView == null) {
54. rowView = mInflater.inflate(resource, null);
55.
56. final int[] to = mTo;
57. final int count = to.length;
58. final View[] holder = new View[count];
59.
60. for (int i = 0; i < count; i++) {
61.
62.
63. holder[i] = rowView.findViewById(to[i]);
64. }
65. rowView.setTag(holder);
66. bindView(position, rowView); //调用下面方法对Item中的
67. viewMap.put(position, rowView);
68. }
69. return rowView;
70. }
71.
72. //对ViewImage进行组装的代码了“else if (v instanceof ImageView)”
73. @SuppressWarnings("unchecked")
74. private void bindView(int position, View view) {
75. final Map dataSet = mData.get(position);
76. if (dataSet == null) {
77. return;
78. }
79.
80. final ViewBinder binder = mViewBinder;
81. final View[] holder = (View[]) view.getTag();
82. final String[] from = mFrom;
83. final int[] to = mTo;
84. final int count = to.length;
85.
86. for (int i = 0; i < count; i++) {
87. final View v = holder[i];
88. if (v != null) {
89. final Object data = dataSet.get(from[i]);
90. String urlText = null;
91.
92. if (data == null) {
93. urlText = "";
94. } else {
95. urlText = data.toString();
96. }
97.
98. boolean bound = false;
99. if (binder != null) {
100. bound = binder.setViewValue(v, data, urlText);
101. }
102.
103. if (!bound) {
104. if (v instanceof Checkable) {
105. if (data instanceof Boolean) {
106. ((Checkable) v).setChecked((Boolean) data);
107. } else {
108. throw new IllegalStateException(v.getClass()
109. .getName()
110. + " should be bound to a Boolean, not a "
111. + data.getClass());
112. }
113. } else if (v instanceof TextView) {
114. setViewText((TextView) v, urlText);
115. } else if (v instanceof ImageView) {
116. if (data instanceof Integer) {
117. setViewImage((ImageView) v, (Integer) data);
118. } else {
119. setViewImage((ImageView) v, urlText);
120. }
121. } else {
122. throw new IllegalStateException(
123. v.getClass().getName()
124. + " is not a "
125. + " view that can be bounds by this SimpleAdapter");
126. }
127. }
128. }
129. }
130. }
131.
132.
133. public void setViewImage(ImageView v, int value) {
134. v.setImageResource(value);
135. }
136.
137. public void setViewImage(final ImageView v, String url) {
138. //如果只是单纯的把图片显示,而不进行缓存。直接用下面的方法拿到URL的Bitmap就行显示就OK
139.// Bitmap bitmap = WebImageBuilder.returnBitMap(url);
140.// ((ImageView) v).setImageBitmap(bitmap);
141.
142. imageLoader.loadDrawable(url, new AsyncImageLoader.ImageCallback() {
143. public void imageLoaded(Drawable imageDrawable, String imageUrl) {
144. if(imageDrawable!=null && imageDrawable.getIntrinsicWidth()>0 ) {
145. v.setImageDrawable(imageDrawable);
146. }
147. }
148. });
149. }
150.
151. }
package lee.listviewimage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class SearchAdapter extends SimpleAdapter {

private AsyncImageLoader imageLoader = new AsyncImageLoader();
private Map<Integer, View> viewMap = new HashMap<Integer, View>();
private ViewBinder mViewBinder;
private List<? extends Map<String, ?>> mData;//List列表存放的数据
private int mResource;//绑定的页面 ,例如:R.layout.search_item,
private LayoutInflater mInflater;
private String[] mFrom;//绑定控件对应的数组里面的值名称
private int[] mTo;//绑定控件的ID

//构造器
public SearchAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
mData = data;
mResource = resource;
mFrom = from;
mTo = to;
// 布局泵(LayoutInflater)根据XML布局文件来绘制视图(View)对象。这个类无法直接创建实例,要通过context对象的getLayoutInflater()或getSystemService(String)方法来获得实例,这样获得的布局泵实例符合设备的环境配置。
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}


/*
SimpleAdapter基类显示每个Item都是通过这个方法生成的
在getView(int position, View convertView, ViewGroup parent)中又调用了SimpleAdapter的私有方法createViewFromResource
来组装View,在createViewFromResource中对SimpleAdapter的参数String[] from 和int[] to进行了组装
*/
public View getView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(position, convertView, parent, mResource);//调用下面方法
}


//在createViewFromResource方法中又有一个bindView(position, v)方法对item中的各个View进行了组装,bindView(position, v)
private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) {
View rowView = this.viewMap.get(position);

if (rowView == null) {
rowView = mInflater.inflate(resource, null);

final int[] to = mTo;
final int count = to.length;
final View[] holder = new View[count];

for (int i = 0; i < count; i++) {


holder[i] = rowView.findViewById(to[i]);
}
rowView.setTag(holder);
bindView(position, rowView);//调用下面方法对Item中的
viewMap.put(position, rowView);
}
return rowView;
}

//对ViewImage进行组装的代码了“else if (v instanceof ImageView)”
@SuppressWarnings("unchecked")
private void bindView(int position, View view) {
final Map dataSet = mData.get(position);
if (dataSet == null) {
return;
}

final ViewBinder binder = mViewBinder;
final View[] holder = (View[]) view.getTag();
final String[] from = mFrom;
final int[] to = mTo;
final int count = to.length;

for (int i = 0; i < count; i++) {
final View v = holder[i];
if (v != null) {
final Object data = dataSet.get(from[i]);
String urlText = null;

if (data == null) {
urlText = "";
} else {
urlText = data.toString();
}

boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, urlText);
}

if (!bound) {
if (v instanceof Checkable) {
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
} else {
throw new IllegalStateException(v.getClass()
.getName()
+ " should be bound to a Boolean, not a "
+ data.getClass());
}
} else if (v instanceof TextView) {
setViewText((TextView) v, urlText);
} else if (v instanceof ImageView) {
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else {
setViewImage((ImageView) v, urlText);
}
} else {
throw new IllegalStateException(
v.getClass().getName()
+ " is not a "
+ " view that can be bounds by this SimpleAdapter");
}
}
}
}
}


public void setViewImage(ImageView v, int value) {
v.setImageResource(value);
}

public void setViewImage(final ImageView v, String url) {
//如果只是单纯的把图片显示,而不进行缓存。直接用下面的方法拿到URL的Bitmap就行显示就OK
// Bitmap bitmap = WebImageBuilder.returnBitMap(url);
// ((ImageView) v).setImageBitmap(bitmap);

imageLoader.loadDrawable(url, new AsyncImageLoader.ImageCallback() {
public void imageLoaded(Drawable imageDrawable, String imageUrl) {
if(imageDrawable!=null && imageDrawable.getIntrinsicWidth()>0 ) {
v.setImageDrawable(imageDrawable);
}
}
});
}

}

七、如果不需要异步加载,可以修改上面的SearchAdapter方法

(1):可以在上面的基础上修改public void setViewImage(final ImageView v, String url)方法

Java代码
1.public void setViewImage(final ImageView v, String url) {
2. Bitmap bitmap = WebImageBuilder.returnBitMap(url);
3. ((ImageView) v).setImageBitmap(bitmap);
4.}
public void setViewImage(final ImageView v, String url) {
Bitmap bitmap = WebImageBuilder.returnBitMap(url);
((ImageView) v).setImageBitmap(bitmap);
}

(2)可以只剩下public SearchAdapter构造方法和 public void setViewImage(final ImageView v, String url)2个方法,其他方法都去掉

Java代码
1.package lee.listviewimage;
2.import java.util.List;
3.import java.util.Map;
4.import android.content.Context;
5.import android.graphics.Bitmap;
6.import android.widget.ImageView;
7.import android.widget.SimpleAdapter;
8.
9.public class SearchAdapter extends SimpleAdapter {
10.
11. //构造器
12. public SearchAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to) {
13. super(context, data, resource, from, to);
14. }
15.
16. public void setViewImage(final ImageView v, String url) {
17. Bitmap bitmap = WebImageBuilder.returnBitMap(url);
18. ((ImageView) v).setImageBitmap(bitmap);
19.
20. }
21. }
package lee.listviewimage;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.graphics.Bitmap;
import android.widget.ImageView;
import android.widget.SimpleAdapter;

public class SearchAdapter extends SimpleAdapter {

//构造器
public SearchAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
}

public void setViewImage(final ImageView v, String url) {
Bitmap bitmap = WebImageBuilder.returnBitMap(url);
((ImageView) v).setImageBitmap(bitmap);

}
}
如果只是打开单个图片可以使用这个方法

PS:异步方法应该也可以精简到上面那样只剩下2个方法,但测试不成功。,有待修改

问题1:

今天测试的时候又发现了问题:单图片的地址错误或者无法连接时,使用异步的方法虽然能正常显示其他图片,但单连接错误的图片超时后。系统会自动跳出提示错误信息。原来源文件没有处理这种情况,所以需要对异步的AsyncImageLoader.java文件的loadImageFromUrl方法进行修改

Java代码
1.//定义方法链接URL获取输入流,然后转换成Drawable
2.protected Drawable loadImageFromUrl(String imageUrl) {
3. try {
4. return Drawable.createFromStream(new URL(imageUrl).openStream(),"src");//当URL不正确或者链接不上。new URL(imageUrl).openStream()会抛错。所以需要在抛错的时候返回NULL。
5. } catch (Exception e) {
6.
7. // throw new RuntimeException(e);
8. return Drawable.createFromStream(null,"src");
9.
10. }
11.}:
//定义方法链接URL获取输入流,然后转换成Drawable
protected Drawable loadImageFromUrl(String imageUrl) {
try {
return Drawable.createFromStream(new URL(imageUrl).openStream(),"src");//当URL不正确或者链接不上。new URL(imageUrl).openStream()会抛错。所以需要在抛错的时候返回NULL。
} catch (Exception e) {

// throw new RuntimeException(e);
return Drawable.createFromStream(null,"src");

}
}:

问题2:

单显示的条目很多。需要Listview往下拉,这样当翻页的图片如果是第一页相同的图片。会出现不能显示的问题,这样就导致了没有缓冲的同能。

原因:

主要是因为

Java代码
1.if (imageCache.containsKey(imageUrl)) {
2. SoftReference<Drawable> softReference = imageCache.get(imageUrl);
3. if (softReference.get() != null) {
4. return softReference.get();
5. }
6.}
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
if (softReference.get() != null) {
return softReference.get();
}
}
这段代码没有起作用。因为他只是直接返回softReference.get();结果。并没有对他进行显示


解决:

把上面的代码放到线程里面去。同时优化了一下。加了线程池管理线程启动的个数

Java代码
1.try {
2. threadPool.execute(new Runnable() {
3.
4. @Override
5. public void run() {
6.
7. if (imageCache.containsKey(imageUrl)) { //检查缓冲imageCache是否存在对应的KEY
8. SoftReference<Drawable> softReference = imageCache.get(imageUrl); //存在就获取对应的值
9. Log.i("abc", "1:"+softReference.get().toString());
10. if (softReference.get() != null) {
11. Log.i("abc", "2:"+softReference.get().toString());
12. Message message = handler.obtainMessage(0, softReference.get());
13. handler.sendMessage(message);
14.
15. }
16. }else{
17.
18. Drawable drawable = loadImageFromUrl(imageUrl); //使用下面的方法获取Drawable
19. imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); //把图片放到HasMap中
20. Log.i("abc", "0:"+drawable);
21. Message message = handler.obtainMessage(0, drawable);
22. handler.sendMessage(message);
23. }
24. }
25. });
26.} catch (Exception e) {
27. e.printStackTrace();
28.}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics