android listview网络图片,Android ListView从网络获取图片及文字显示
上一篇文章说的是ListView展示本地的图片以及文本,这一篇说一下如何从网络获取图片以及文本来显示。事实上,一般是先获取Josn或sml数据,然后解释显示。我们先从网上获取xml,然后对其进行解析,最后显示在ListView上。具体步骤:
客户端发出请求,获取xml
客户端异步解析xml
ListView将解析完的数据显示
(1)xml布局文件
mainxml,就是一个ListView。
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#b5b5b5"
android:dividerHeight="1dp"
android:listSelector="@drawable/list_selector" />
ListView的每一行的布局,list_raw.xml,看一下结构图:
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip" >
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dip"
android:layout_alignParentLeft="true"
android:background="@drawable/image_bg"
android:layout_marginRight="5dip">
android:id="@+id/list_image"
android:layout_width="50dip"
android:layout_height="50dip"
android:src="@drawable/rihanna"/>
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/thumbnail"
android:layout_toRightOf="@+id/thumbnail"
android:text="Rihanna Love the way lie"
android:textColor="#040404"
android:typeface="sans"
android:textSize="15dip"
android:textStyle="bold"/>
android:id="@+id/artist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:textColor="#343434"
android:textSize="10dip"
android:layout_marginTop="1dip"
android:layout_toRightOf="@+id/thumbnail"
android:text="Just gona stand there and ..." />
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="@id/title"
android:gravity="right"
android:text="5:45"
android:layout_marginRight="5dip"
android:textSize="10dip"
android:textColor="#10bcc9"
android:textStyle="bold"/>
android:layout_height="wrap_content"
android:src="@drawable/arrow"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
另外我们打算使用几个特效,一个是当点击列表项目的时候,项目背景色改变,其实就是一个selector;另一个就是用shape美化视觉效果,具体看xml代码:
1.list_selector.xml
android:state_selected="false"
android:state_pressed="false"
android:drawable="@drawable/gradient_bg" />
android:drawable="@drawable/gradient_bg_hover" />
android:state_pressed="false"
android:drawable="@drawable/gradient_bg_hover" />
2.gradient_bg.xml,是默认背景梯度风格
android:shape="rectangle">
android:startColor="#f1f1f2"
android:centerColor="#e7e7e8"
android:endColor="#cfcfcf"
android:angle="270" />
3.gradient_bg_hover.xml梯度风格在悬停状态
android:shape="rectangle">
android:startColor="#18d7e5"
android:centerColor="#16cedb"
android:endColor="#09adb9"
android:angle="270" />
4.image_bg.xml在图片周围的白色边条
android:shape="rectangle">
以上效果基本上都用到了shape,对此不了解的可以去查看相关资料。上面就是全部的xml布局文件,下面将开始写代码。
(2)主要代码
代码部分主要涉及到一下几个功能,重写ListView的适配器(BaseAdapter),从网络获取图片,图片缓存的处理,xml的解析。
①重写ListView的适配器,这部分可以参考上一篇文章,LazyAdapter.Java
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class LazyAdapter extends BaseAdapter {
private Activity activity;
private ArrayList> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader; //用来下载图片的类,后面有介绍
public LazyAdapter(Activity a, ArrayList> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.list_row, null);
TextView title = (TextView)vi.findViewById(R.id.title); // 标题
TextView artist = (TextView)vi.findViewById(R.id.artist); // 歌手名
TextView duration = (TextView)vi.findViewById(R.id.duration); // 时长
ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image); // 缩略图
HashMap song = new HashMap();
song = data.get(position);
// 设置ListView的相关值
title.setText(song.get(CustomizedListView.KEY_TITLE));
artist.setText(song.get(CustomizedListView.KEY_ARTIST));
duration.setText(song.get(CustomizedListView.KEY_DURATION));
imageLoader.DisplayImage(song.get(CustomizedListView.KEY_THUMB_URL), thumb_image);
return vi;
}
}
②网络获取图片的类,ImageLoader.java:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
public class ImageLoader {
MemoryCache memoryCache=new MemoryCache();
FileCache fileCache;
private Map imageViews=Collections.synchronizedMap(new WeakHashMap());
ExecutorService executorService;
public ImageLoader(Context context){
fileCache=new FileCache(context);
executorService=Executors.newFixedThreadPool(5);
}
final int stub_id = R.drawable.no_image;
public void DisplayImage(String url, ImageView imageView)
{
imageViews.put(imageView, url);
Bitmap bitmap=memoryCache.get(url);
if(bitmap!=null)
imageView.setImageBitmap(bitmap);
else
{
queuePhoto(url, imageView);
imageView.setImageResource(stub_id);
}
}
private void queuePhoto(String url, ImageView imageView)
{
PhotoToLoad p=new PhotoToLoad(url, imageView);
executorService.submit(new PhotosLoader(p));
}
private Bitmap getBitmap(String url)
{
File f=fileCache.getFile(url);
//从sd卡
Bitmap b = decodeFile(f);
if(b!=null)
return b;
//从网络
try {
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is=conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
bitmap = decodeFile(f);
return bitmap;
} catch (Exception ex){
ex.printStackTrace();
return null;
}
}
//解码图像用来减少内存消耗
private Bitmap decodeFile(File f){
try {
//解码图像大小
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//找到正确的刻度值,它应该是2的幂。
final int REQUIRED_SIZE=70;
int width_tmp=o.outWidth, height_tmp=o.outHeight;
int scale=1;
while(true){
if(width_tmp/2
break;
width_tmp/=2;
height_tmp/=2;
scale*=2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}
/任务队列
private class PhotoToLoad
{
public String url;
public ImageView imageView;
public PhotoToLoad(String u, ImageView i){
url=u;
imageView=i;
}
}
class PhotosLoader implements Runnable {
PhotoToLoad photoToLoad;
PhotosLoader(PhotoToLoad photoToLoad){
this.photoToLoad=photoToLoad;
}
@Override
public void run() {
if(imageViewReused(photoToLoad))
return;
Bitmap bmp=getBitmap(photoToLoad.url);
memoryCache.put(photoToLoad.url, bmp);
if(imageViewReused(photoToLoad))
return;
BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
Activity a=(Activity)photoToLoad.imageView.getContext();
a.runOnUiThread(bd);
}
}
boolean imageViewReused(PhotoToLoad photoToLoad){
String tag=imageViews.get(photoToLoad.imageView);
if(tag==null || !tag.equals(photoToLoad.url))
return true;
return false;
}
//用于显示位图在UI线程
class BitmapDisplayer implements Runnable
{
Bitmap bitmap;
PhotoToLoad photoToLoad;
public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
public void run()
{
if(imageViewReused(photoToLoad))
return;
if(bitmap!=null)
photoToLoad.imageView.setImageBitmap(bitmap);
else
photoToLoad.imageView.setImageResource(stub_id);
}
}
public void clearCache() {
memoryCache.clear();
fileCache.clear();
}
} ③xml解析,xml的解析有很多方法,这里采用进行dom方式的xml解析。
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import android.util.Log;
public class XMLParser {
// 构造方法
public XMLParser() {
}
/**
* 从URL获取XML使HTTP请求
* @param url string
* */
public String getXmlFromUrl(String url) {
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return xml;
}
/**
* 获取XML DOM元素
* @param XML string
* */
public Document getDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
return doc;
}
/** 获取节点值
* @param elem element
*/
public final String getElementValue( Node elem ) {
Node child;
if( elem != null){
if (elem.hasChildNodes()){
for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
if( child.getNodeType() == Node.TEXT_NODE ){
return child.getNodeValue();
}
}
}
}
return "";
}
/**
* 获取节点值
* @param Element node
* @param key string
* */
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
} ④程序缓存的处理,主要是内存缓存+文件缓存。内存缓存中网上很多是采用SoftReference来防止堆溢出:
MemoryCache.java:
import java.lang.ref.SoftReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import android.graphics.Bitmap;
public class MemoryCache {
private Map> cache=Collections.synchronizedMap(new HashMap>());//软引用
public Bitmap get(String id){
if(!cache.containsKey(id))
return null;
SoftReference ref=cache.get(id);
return ref.get();
}
public void put(String id, Bitmap bitmap){
cache.put(id, new SoftReference(bitmap));
}
public void clear() {
cache.clear();
}
} FileCache.java
import java.io.File;
import android.content.Context;
public class FileCache {
private File cacheDir;
public FileCache(Context context){
//找一个用来缓存图片的路径
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
else
cacheDir=context.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
}
public File getFile(String url){
String filename=String.valueOf(url.hashCode());
File f = new File(cacheDir, filename);
return f;
}
public void clear(){
File[] files=cacheDir.listFiles();
if(files==null)
return;
for(File f:files)
f.delete();
}
} ⑤还有一个读取流的工具类,Utils.java:
import java.io.InputStream;
import java.io.OutputStream;
public class Utils {
public static void CopyStream(InputStream is, OutputStream os)
{
final int buffer_size=1024;
try
{
byte[] bytes=new byte[buffer_size];
for(;;)
{
int count=is.read(bytes, 0, buffer_size);
if(count==-1)
break;
os.write(bytes, 0, count);
is.close();
os.close();
}
}
catch(Exception ex){}
}
}
还可以像下面这样表达,方法是一样的,就是表达形式上不同:
public static byte[] readStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while( (len=inStream.read(buffer)) != -1){
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
return outSteam.toByteArray();
}
} 最后就是主Activity的代码了,
package com.example.androidhive;
import java.util.ArrayList;
import java.util.HashMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
public class CustomizedListView extends Activity {
// 所有的静态变量
static final String URL = "http://api.androidhive.info/music/music.xml";//xml目的地址,打开地址看一下
// XML 节点
static final String KEY_SONG = "song"; // parent node
static final String KEY_ID = "id";
static final String KEY_TITLE = "title";
static final String KEY_ARTIST = "artist";
static final String KEY_DURATION = "duration";
static final String KEY_THUMB_URL = "thumb_url";
ListView list;
LazyAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList> songsList = new ArrayList>();
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // 从网络获取xml
Document doc = parser.getDomElement(xml); // 获取 DOM 节点
NodeList nl = doc.getElementsByTagName(KEY_SONG);
// 循环遍历所有的歌节点
for (int i = 0; i
// 新建一个 HashMap
HashMap map = new HashMap();
Element e = (Element) nl.item(i);
//每个子节点添加到HashMap关键= >值
map.put(KEY_ID, parser.getValue(e, KEY_ID));
map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION));
map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));
// HashList添加到数组列表
songsList.add(map);
}
list=(ListView)findViewById(R.id.list);
adapter=new LazyAdapter(this, songsList);
list.setAdapter(adapter);
//为单一列表行添加单击事件
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view,
int position, long id) {
//这里可以自由发挥,比如播放一首歌曲等等
}
});
}
} 最后看一下效果:
android listview网络图片,Android ListView从网络获取图片及文字显示相关推荐
- Android ListView从网络获取图片及文字显示
原帖地址:http://blog.csdn.net/wangjinyu501/article/details/8219317 上一篇文章说的是ListView展示本地的图片以及文本,这一篇说一下如何从 ...
- blob二进制显示在html,使用Blob获取图片并二进制显示实例页面
HTML代码: JS代码: var eleAppend = document.getElementById("forAppend"); window.URL = window.UR ...
- Android ListView 和 ***Adapter 从本地/网络获取歌曲列表
本文内容 环境 项目结构 测试数据 演示 1:SimpleAdapter 演示 2:BaseAdapter 演示 3:CustomLazyList 演示 4:CustomLazyCompleteLis ...
- android 代码获取图片信息吗,Android 通过网络获取图片的代码
Android 通过网络获取图片的代码 主activity package com.netimg; import android.app.Activity; import android.graphi ...
- Android 网络获取图片处理
今天做项目,需要从网络获取图片,然后加载到Listview里面. 这边需要分为两步. 第一步:从网络获取图片 public InputStream getImageViewInputStream(St ...
- 实现图片中文的识别和获取图片上文字的坐标(java实现)
实现图片中文的识别和获取图片上文字的坐标(java实现) 现在利用python来进行图片的文字识别较为普遍,但是如果我们利用常用的家庭电脑来识别,需要的时间比较长,达到20~30 ...
- Android:ViewPager详细解释(异步网络负载图片,有图片缓存,)并与导航点
android 应用.准则欢迎页面. 和图像旋转木马特征, 或者没有很多其他的内容显示在一个页面.以被划分成多个页面,在这一刻viewpager这是非常容易使用. 首先看下效果: 以下是一个样例.带异 ...
- android+背景+网络图片,android背景图片平铺
Android背景平铺: 在drawable文件夹下建立如下文件bg.xml: android:src ="@drawable/pattern" android:tileMode ...
- 无限轮播加小圆点(从网络获取图片)
思路: 1:floatview移动范围:直播下面和主题下面,最左边是直播View的 tabLive.getX (),最右边是 tabLive.getX ()加上3倍的直播View宽度. 2:滑动一个页 ...
最新文章
- jenkins android sdk,Jenkins为什么找不到Android SDK?
- main 函数内的变量是全局变量,还是局部变量?
- Spring 的优秀工具类盘点---转
- 校级选修课《软件开发实践》教学大纲(200807修订)
- C语言及程序设计进阶例程-17 认识链表
- python读取栅格gdal库下载链接
- 转载:jQuery 1.3.3 新功能
- 无法安装 计算机缺失,还原安装程序Windows缺失的文件 - Windows Client | Microsoft Docs...
- MFC开发-待整理 --VS调试 不会命中断点,源代码与原始版本不同的解决办法
- mysql三表联合更新_mysql三表连接update
- 普通话转粤语_语音转文字评测:几款语音转文字app,你了解多少?
- 文件操作命令(replace)
- 一款无惧“魔改”的设计系统开源了,已支持字节跳动4000多个项目
- 的稳定性 linux_Linux系统KDE桌面,打造最接近Windows的界面环境!不用才后悔
- centos安装python3.6.3、pip_Centos 7安装python3和pip
- 软件multisim的安装教程
- 小规模免税新政,账务怎么做?
- 一些可以参考的文档集合5
- 一个WinForm程序的生与死
- 批量导入AD账户批量启用Exchange 账户步骤
热门文章
- 你知道云渲染和自己渲染有什么区别吗?
- 微信h5支付添加域名时报错,“h5支付域名需要提供完整的支付路径“
- scara 机器人三四轴机械结构
- 测试iphone硬件好坏的软件,如何检测Apple手机硬件是否损坏
- js两只手指控制div图片放大缩小功能(2)
- Pandas与SQL比较
- Win11怎么设置让CPU性能全开?Win11CPU怎么设置高性能模式?
- Window 10 电源高性能模式设置
- python求解不等式组可行域_二元一次不等式(组)和可行域
- oracle dbms是什么意思,oracle的dbms_stats包详细解说