上一篇文章说的是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从网络获取图片及文字显示相关推荐

  1. Android ListView从网络获取图片及文字显示

    原帖地址:http://blog.csdn.net/wangjinyu501/article/details/8219317 上一篇文章说的是ListView展示本地的图片以及文本,这一篇说一下如何从 ...

  2. blob二进制显示在html,使用Blob获取图片并二进制显示实例页面

    HTML代码: JS代码: var eleAppend = document.getElementById("forAppend"); window.URL = window.UR ...

  3. Android ListView 和 ***Adapter 从本地/网络获取歌曲列表

    本文内容 环境 项目结构 测试数据 演示 1:SimpleAdapter 演示 2:BaseAdapter 演示 3:CustomLazyList 演示 4:CustomLazyCompleteLis ...

  4. android 代码获取图片信息吗,Android 通过网络获取图片的代码

    Android 通过网络获取图片的代码 主activity package com.netimg; import android.app.Activity; import android.graphi ...

  5. Android 网络获取图片处理

    今天做项目,需要从网络获取图片,然后加载到Listview里面. 这边需要分为两步. 第一步:从网络获取图片 public InputStream getImageViewInputStream(St ...

  6. 实现图片中文的识别和获取图片上文字的坐标(java实现)

    实现图片中文的识别和获取图片上文字的坐标(java实现)            现在利用python来进行图片的文字识别较为普遍,但是如果我们利用常用的家庭电脑来识别,需要的时间比较长,达到20~30 ...

  7. Android:ViewPager详细解释(异步网络负载图片,有图片缓存,)并与导航点

    android 应用.准则欢迎页面. 和图像旋转木马特征, 或者没有很多其他的内容显示在一个页面.以被划分成多个页面,在这一刻viewpager这是非常容易使用. 首先看下效果: 以下是一个样例.带异 ...

  8. android+背景+网络图片,android背景图片平铺

    Android背景平铺: 在drawable文件夹下建立如下文件bg.xml: android:src ="@drawable/pattern" android:tileMode ...

  9. 无限轮播加小圆点(从网络获取图片)

    思路: 1:floatview移动范围:直播下面和主题下面,最左边是直播View的 tabLive.getX (),最右边是 tabLive.getX ()加上3倍的直播View宽度. 2:滑动一个页 ...

最新文章

  1. jenkins android sdk,Jenkins为什么找不到Android SDK?
  2. main 函数内的变量是全局变量,还是局部变量?
  3. Spring 的优秀工具类盘点---转
  4. 校级选修课《软件开发实践》教学大纲(200807修订)
  5. C语言及程序设计进阶例程-17 认识链表
  6. python读取栅格gdal库下载链接
  7. 转载:jQuery 1.3.3 新功能
  8. 无法安装 计算机缺失,还原安装程序Windows缺失的文件 - Windows Client | Microsoft Docs...
  9. MFC开发-待整理 --VS调试 不会命中断点,源代码与原始版本不同的解决办法
  10. mysql三表联合更新_mysql三表连接update
  11. 普通话转粤语_语音转文字评测:几款语音转文字app,你了解多少?
  12. 文件操作命令(replace)
  13. 一款无惧“魔改”的设计系统开源了,已支持字节跳动4000多个项目
  14. 的稳定性 linux_Linux系统KDE桌面,打造最接近Windows的界面环境!不用才后悔
  15. centos安装python3.6.3、pip_Centos 7安装python3和pip
  16. 软件multisim的安装教程
  17. 小规模免税新政,账务怎么做?
  18. 一些可以参考的文档集合5
  19. 一个WinForm程序的生与死
  20. 批量导入AD账户批量启用Exchange 账户步骤

热门文章

  1. 你知道云渲染和自己渲染有什么区别吗?
  2. 微信h5支付添加域名时报错,“h5支付域名需要提供完整的支付路径“
  3. scara 机器人三四轴机械结构
  4. 测试iphone硬件好坏的软件,如何检测Apple手机硬件是否损坏
  5. js两只手指控制div图片放大缩小功能(2)
  6. Pandas与SQL比较
  7. Win11怎么设置让CPU性能全开?Win11CPU怎么设置高性能模式?
  8. Window 10 电源高性能模式设置
  9. python求解不等式组可行域_二元一次不等式(组)和可行域
  10. oracle dbms是什么意思,oracle的dbms_stats包详细解说