失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > android listview网络图片 Android ListView从网络获取图片及文字显示

android listview网络图片 Android ListView从网络获取图片及文字显示

时间:2019-05-26 16:41:59

相关推荐

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="RihannaLovethewaylie"

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="Justgonastandthereand..."/>

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

importjava.util.ArrayList;

importjava.util.HashMap;

importandroid.app.Activity;

importandroid.content.Context;

importandroid.view.LayoutInflater;

importandroid.view.View;

importandroid.view.ViewGroup;

importandroid.widget.BaseAdapter;

importandroid.widget.ImageView;

importandroid.widget.TextView;

publicclassLazyAdapterextendsBaseAdapter{

privateActivityactivity;

privateArrayList>data;

privatestaticLayoutInflaterinflater=null;

publicImageLoaderimageLoader;//用来下载图片的类,后面有介绍

publicLazyAdapter(Activitya,ArrayList>d){

activity=a;

data=d;

inflater=(LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

imageLoader=newImageLoader(activity.getApplicationContext());

}

publicintgetCount(){

returndata.size();

}

publicObjectgetItem(intposition){

returnposition;

}

publiclonggetItemId(intposition){

returnposition;

}

publicViewgetView(intposition,ViewconvertView,ViewGroupparent){

Viewvi=convertView;

if(convertView==null)

vi=inflater.inflate(R.layout.list_row,null);

TextViewtitle=(TextView)vi.findViewById(R.id.title);//标题

TextViewartist=(TextView)vi.findViewById(R.id.artist);//歌手名

TextViewduration=(TextView)vi.findViewById(R.id.duration);//时长

ImageViewthumb_image=(ImageView)vi.findViewById(R.id.list_image);//缩略图

HashMapsong=newHashMap();

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);

returnvi;

}

}

②网络获取图片的类,ImageLoader.java:

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileNotFoundException;

importjava.io.FileOutputStream;

importjava.io.InputStream;

importjava.io.OutputStream;

.HttpURLConnection;

.URL;

importjava.util.Collections;

importjava.util.Map;

importjava.util.WeakHashMap;

importjava.util.concurrent.ExecutorService;

importjava.util.concurrent.Executors;

importandroid.app.Activity;

importandroid.content.Context;

importandroid.graphics.Bitmap;

importandroid.graphics.BitmapFactory;

importandroid.widget.ImageView;

publicclassImageLoader{

MemoryCachememoryCache=newMemoryCache();

FileCachefileCache;

privateMapimageViews=Collections.synchronizedMap(newWeakHashMap());

ExecutorServiceexecutorService;

publicImageLoader(Contextcontext){

fileCache=newFileCache(context);

executorService=Executors.newFixedThreadPool(5);

}

finalintstub_id=R.drawable.no_image;

publicvoidDisplayImage(Stringurl,ImageViewimageView)

{

imageViews.put(imageView,url);

Bitmapbitmap=memoryCache.get(url);

if(bitmap!=null)

imageView.setImageBitmap(bitmap);

else

{

queuePhoto(url,imageView);

imageView.setImageResource(stub_id);

}

}

privatevoidqueuePhoto(Stringurl,ImageViewimageView)

{

PhotoToLoadp=newPhotoToLoad(url,imageView);

executorService.submit(newPhotosLoader(p));

}

privateBitmapgetBitmap(Stringurl)

{

Filef=fileCache.getFile(url);

//从sd卡

Bitmapb=decodeFile(f);

if(b!=null)

returnb;

//从网络

try{

Bitmapbitmap=null;

URLimageUrl=newURL(url);

HttpURLConnectionconn=(HttpURLConnection)imageUrl.openConnection();

conn.setConnectTimeout(30000);

conn.setReadTimeout(30000);

conn.setInstanceFollowRedirects(true);

InputStreamis=conn.getInputStream();

OutputStreamos=newFileOutputStream(f);

Utils.CopyStream(is,os);

os.close();

bitmap=decodeFile(f);

returnbitmap;

}catch(Exceptionex){

ex.printStackTrace();

returnnull;

}

}

//解码图像用来减少内存消耗

privateBitmapdecodeFile(Filef){

try{

//解码图像大小

BitmapFactory.Optionso=newBitmapFactory.Options();

o.inJustDecodeBounds=true;

BitmapFactory.decodeStream(newFileInputStream(f),null,o);

//找到正确的刻度值,它应该是2的幂。

finalintREQUIRED_SIZE=70;

intwidth_tmp=o.outWidth,height_tmp=o.outHeight;

intscale=1;

while(true){

if(width_tmp/2

break;

width_tmp/=2;

height_tmp/=2;

scale*=2;

}

BitmapFactory.Optionso2=newBitmapFactory.Options();

o2.inSampleSize=scale;

returnBitmapFactory.decodeStream(newFileInputStream(f),null,o2);

}catch(FileNotFoundExceptione){}

returnnull;

}

/任务队列

privateclassPhotoToLoad

{

publicStringurl;

publicImageViewimageView;

publicPhotoToLoad(Stringu,ImageViewi){

url=u;

imageView=i;

}

}

classPhotosLoaderimplementsRunnable{

PhotoToLoadphotoToLoad;

PhotosLoader(PhotoToLoadphotoToLoad){

this.photoToLoad=photoToLoad;

}

@Override

publicvoidrun(){

if(imageViewReused(photoToLoad))

return;

Bitmapbmp=getBitmap(photoToLoad.url);

memoryCache.put(photoToLoad.url,bmp);

if(imageViewReused(photoToLoad))

return;

BitmapDisplayerbd=newBitmapDisplayer(bmp,photoToLoad);

Activitya=(Activity)photoToLoad.imageView.getContext();

a.runOnUiThread(bd);

}

}

booleanimageViewReused(PhotoToLoadphotoToLoad){

Stringtag=imageViews.get(photoToLoad.imageView);

if(tag==null||!tag.equals(photoToLoad.url))

returntrue;

returnfalse;

}

//用于显示位图在UI线程

classBitmapDisplayerimplementsRunnable

{

Bitmapbitmap;

PhotoToLoadphotoToLoad;

publicBitmapDisplayer(Bitmapb,PhotoToLoadp){bitmap=b;photoToLoad=p;}

publicvoidrun()

{

if(imageViewReused(photoToLoad))

return;

if(bitmap!=null)

photoToLoad.imageView.setImageBitmap(bitmap);

else

photoToLoad.imageView.setImageResource(stub_id);

}

}

publicvoidclearCache(){

memoryCache.clear();

fileCache.clear();

}

} ③xml解析,xml的解析有很多方法,这里采用进行dom方式的xml解析。

importjava.io.IOException;

importjava.io.StringReader;

importjava.io.UnsupportedEncodingException;

importjavax.xml.parsers.DocumentBuilder;

importjavax.xml.parsers.DocumentBuilderFactory;

importjavax.xml.parsers.ParserConfigurationException;

importorg.apache.http.HttpEntity;

importorg.apache.http.HttpResponse;

importorg.apache.http.client.ClientProtocolException;

importorg.apache.http.client.methods.HttpPost;

importorg.apache.http.impl.client.DefaultHttpClient;

importorg.apache.http.util.EntityUtils;

importorg.w3c.dom.Document;

importorg.w3c.dom.Element;

importorg.w3c.dom.Node;

importorg.w3c.dom.NodeList;

importorg.xml.sax.InputSource;

importorg.xml.sax.SAXException;

importandroid.util.Log;

publicclassXMLParser{

//构造方法

publicXMLParser(){

}

/**

*从URL获取XML使HTTP请求

*@paramurlstring

**/

publicStringgetXmlFromUrl(Stringurl){

Stringxml=null;

try{

//defaultHttpClient

DefaultHttpClienthttpClient=newDefaultHttpClient();

HttpPosthttpPost=newHttpPost(url);

HttpResponsehttpResponse=httpClient.execute(httpPost);

HttpEntityhttpEntity=httpResponse.getEntity();

xml=EntityUtils.toString(httpEntity);

}catch(UnsupportedEncodingExceptione){

e.printStackTrace();

}catch(ClientProtocolExceptione){

e.printStackTrace();

}catch(IOExceptione){

e.printStackTrace();

}

returnxml;

}

/**

*获取XMLDOM元素

*@paramXMLstring

**/

publicDocumentgetDomElement(Stringxml){

Documentdoc=null;

DocumentBuilderFactorydbf=DocumentBuilderFactory.newInstance();

try{

DocumentBuilderdb=dbf.newDocumentBuilder();

InputSourceis=newInputSource();

is.setCharacterStream(newStringReader(xml));

doc=db.parse(is);

}catch(ParserConfigurationExceptione){

Log.e("Error:",e.getMessage());

returnnull;

}catch(SAXExceptione){

Log.e("Error:",e.getMessage());

returnnull;

}catch(IOExceptione){

Log.e("Error:",e.getMessage());

returnnull;

}

returndoc;

}

/**获取节点值

*@paramelemelement

*/

publicfinalStringgetElementValue(Nodeelem){

Nodechild;

if(elem!=null){

if(elem.hasChildNodes()){

for(child=elem.getFirstChild();child!=null;child=child.getNextSibling()){

if(child.getNodeType()==Node.TEXT_NODE){

returnchild.getNodeValue();

}

}

}

}

return"";

}

/**

*获取节点值

*@paramElementnode

*@paramkeystring

**/

publicStringgetValue(Elementitem,Stringstr){

NodeListn=item.getElementsByTagName(str);

returnthis.getElementValue(n.item(0));

}

} ④程序缓存的处理,主要是内存缓存+文件缓存。内存缓存中网上很多是采用SoftReference来防止堆溢出:

MemoryCache.java:

importjava.lang.ref.SoftReference;

importjava.util.Collections;

importjava.util.HashMap;

importjava.util.Map;

importandroid.graphics.Bitmap;

publicclassMemoryCache{

privateMap>cache=Collections.synchronizedMap(newHashMap>());//软引用

publicBitmapget(Stringid){

if(!cache.containsKey(id))

returnnull;

SoftReferenceref=cache.get(id);

returnref.get();

}

publicvoidput(Stringid,Bitmapbitmap){

cache.put(id,newSoftReference(bitmap));

}

publicvoidclear(){

cache.clear();

}

} FileCache.java

importjava.io.File;

importandroid.content.Context;

publicclassFileCache{

privateFilecacheDir;

publicFileCache(Contextcontext){

//找一个用来缓存图片的路径

if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))

cacheDir=newFile(android.os.Environment.getExternalStorageDirectory(),"LazyList");

else

cacheDir=context.getCacheDir();

if(!cacheDir.exists())

cacheDir.mkdirs();

}

publicFilegetFile(Stringurl){

Stringfilename=String.valueOf(url.hashCode());

Filef=newFile(cacheDir,filename);

returnf;

}

publicvoidclear(){

File[]files=cacheDir.listFiles();

if(files==null)

return;

for(Filef:files)

f.delete();

}

}⑤还有一个读取流的工具类,Utils.java:

importjava.io.InputStream;

importjava.io.OutputStream;

publicclassUtils{

publicstaticvoidCopyStream(InputStreamis,OutputStreamos)

{

finalintbuffer_size=1024;

try

{

byte[]bytes=newbyte[buffer_size];

for(;;)

{

intcount=is.read(bytes,0,buffer_size);

if(count==-1)

break;

os.write(bytes,0,count);

is.close();

os.close();

}

}

catch(Exceptionex){}

}

}

还可以像下面这样表达,方法是一样的,就是表达形式上不同:

publicstaticbyte[]readStream(InputStreaminStream)throwsException{

ByteArrayOutputStreamoutSteam=newByteArrayOutputStream();

byte[]buffer=newbyte[1024];

intlen=-1;

while((len=inStream.read(buffer))!=-1){

outSteam.write(buffer,0,len);

}

outSteam.close();

inStream.close();

returnoutSteam.toByteArray();

}

} 最后就是主Activity的代码了,

packagecom.example.androidhive;

importjava.util.ArrayList;

importjava.util.HashMap;

importorg.w3c.dom.Document;

importorg.w3c.dom.Element;

importorg.w3c.dom.NodeList;

importandroid.app.Activity;

importandroid.os.Bundle;

importandroid.view.View;

importandroid.widget.AdapterView;

importandroid.widget.AdapterView.OnItemClickListener;

importandroid.widget.ListView;

publicclassCustomizedListViewextendsActivity{

//所有的静态变量

staticfinalStringURL="http://api.androidhive.info/music/music.xml";//xml目的地址,打开地址看一下

//XML节点

staticfinalStringKEY_SONG="song";//parentnode

staticfinalStringKEY_ID="id";

staticfinalStringKEY_TITLE="title";

staticfinalStringKEY_ARTIST="artist";

staticfinalStringKEY_DURATION="duration";

staticfinalStringKEY_THUMB_URL="thumb_url";

ListViewlist;

LazyAdapteradapter;

@Override

publicvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

ArrayList>songsList=newArrayList>();

XMLParserparser=newXMLParser();

Stringxml=parser.getXmlFromUrl(URL);//从网络获取xml

Documentdoc=parser.getDomElement(xml);//获取DOM节点

NodeListnl=doc.getElementsByTagName(KEY_SONG);

//循环遍历所有的歌节点

for(inti=0;i

//新建一个HashMap

HashMapmap=newHashMap();

Elemente=(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=newLazyAdapter(this,songsList);

list.setAdapter(adapter);

//为单一列表行添加单击事件

list.setOnItemClickListener(newOnItemClickListener(){

@Override

publicvoidonItemClick(AdapterView>parent,Viewview,

intposition,longid){

//这里可以自由发挥,比如播放一首歌曲等等

}

});

}

} 最后看一下效果:

如果觉得《android listview网络图片 Android ListView从网络获取图片及文字显示》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。