Android ListView从网络获取图片及文字显示(转)

10 篇文章 1 订阅
7 篇文章 0 订阅

   上一篇文章说的是ListView展示本地的图片以及文本,这一篇说一下如何从网络获取图片以及文本来显示。事实上,一般是先获取Josn或sml数据,然后解释显示。我们先从网上获取xml,然后对其进行解析,最后显示在ListView上。具体步骤:

  • 客户端发出请求,获取xml
  • 客户端异步解析xml
  • ListView将解析完的数据显示

      一、Android客户端

                                                                            

     (1)xml布局文件

        mainxml,就是一个ListView。     

复制代码

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="fill_parent"
 4     android:layout_height="fill_parent"
 5     android:orientation="vertical">
 6     
 7     <ListView
 8         android:id="@+id/list"
 9         android:layout_width="fill_parent"
10         android:layout_height="wrap_content"
11         android:divider="#b5b5b5"
12         android:dividerHeight="1dp"
13         android:listSelector="@drawable/list_selector" />
14 
15 </LinearLayout>

复制代码

 ListView的每一行的布局,list_raw.xml,看一下结构图:

                                                         

复制代码

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="fill_parent"
 4     android:layout_height="wrap_content"
 5     android:background="@drawable/list_selector"
 6     android:orientation="horizontal"
 7     android:padding="5dip" >
 8 
 9     <!--  ListView最左边的缩略图 -->
10     <LinearLayout android:id="@+id/thumbnail" 
11         android:layout_width="wrap_content"
12         android:layout_height="wrap_content"
13         android:padding="3dip"        
14         android:layout_alignParentLeft="true"
15         android:background="@drawable/image_bg" 
16         android:layout_marginRight="5dip">
17         
18         <ImageView     
19             android:id="@+id/list_image"   
20             android:layout_width="50dip"
21             android:layout_height="50dip"
22             android:src="@drawable/rihanna"/>
23         
24     </LinearLayout>
25     
26     <!-- 歌曲名-->
27     <TextView
28         android:id="@+id/title"
29         android:layout_width="wrap_content"
30         android:layout_height="wrap_content"
31         android:layout_alignTop="@+id/thumbnail"
32         android:layout_toRightOf="@+id/thumbnail"
33         android:text="Rihanna Love the way lie"
34         android:textColor="#040404"
35         android:typeface="sans" 
36         android:textSize="15dip"
37         android:textStyle="bold"/>
38 
39     <!-- 歌手名 -->
40     <TextView
41         android:id="@+id/artist"
42         android:layout_width="fill_parent"
43         android:layout_height="wrap_content"
44         android:layout_below="@id/title"
45         android:textColor="#343434"
46         android:textSize="10dip"
47         android:layout_marginTop="1dip"
48         android:layout_toRightOf="@+id/thumbnail"
49         android:text="Just gona stand there and ..." />
50 
51     <!-- 歌曲播放时间 -->
52     <TextView
53         android:id="@+id/duration"
54         android:layout_width="wrap_content"
55         android:layout_height="wrap_content"
56         android:layout_alignParentRight="true"
57         android:layout_alignTop="@id/title"
58         android:gravity="right"
59         android:text="5:45"
60         android:layout_marginRight="5dip"
61         android:textSize="10dip"
62         android:textColor="#10bcc9"
63         android:textStyle="bold"/>
64       
65      <!-- 进入播放 -->    
66      <ImageView android:layout_width="wrap_content"
67          android:layout_height="wrap_content"
68          android:src="@drawable/arrow"
69          android:layout_alignParentRight="true"
70          android:layout_centerVertical="true"/>
71 
72 </RelativeLayout>

复制代码

另外我们打算使用几个特效,一个是当点击列表项目的时候,项目背景色改变,其实就是一个selector;另一个就是用shape美化视觉效果,具体看xml代码:

      1.list_selector.xml     

复制代码

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
 3 <!-- Selector style for listrow -->
 4 <item 
 5  android:state_selected="false"
 6     android:state_pressed="false" 
 7     android:drawable="@drawable/gradient_bg" />
 8 <item android:state_pressed="true" 
 9     android:drawable="@drawable/gradient_bg_hover" />
10 <item android:state_selected="true"
11  android:state_pressed="false" 
12     android:drawable="@drawable/gradient_bg_hover" />
13 </selector>

复制代码

 2.gradient_bg.xml,是默认背景梯度风格  

复制代码

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <shape xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:shape="rectangle">
 4   <!--  Gradient Bg for listrow -->
 5   <gradient
 6       android:startColor="#f1f1f2"
 7       android:centerColor="#e7e7e8"
 8       android:endColor="#cfcfcf"
 9       android:angle="270" />
10 </shape>

复制代码

3.gradient_bg_hover.xml 梯度风格在悬停状态

复制代码

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <shape xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:shape="rectangle">
 4   <!-- Gradient BgColor for listrow Selected -->
 5   <gradient
 6       android:startColor="#18d7e5"
 7       android:centerColor="#16cedb"
 8       android:endColor="#09adb9"
 9       android:angle="270" />
10   
11 </shape>

复制代码

4.image_bg.xml 在图片周围的白色边条

复制代码

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
 3     <item>
 4       <shape 
 5         android:shape="rectangle">
 6             <stroke android:width="1dp" android:color="#dbdbdc" />
 7             <solid android:color="#FFFFFF" />
 8         </shape>
 9    </item>
10 </layer-list>

复制代码

 以上效果基本上都用到了shape,对此不了解的可以去查看相关资料。上面就是全部的xml布局文件,下面将开始写代码。
 

   (2)主要代码

            代码部分主要涉及到一下几个功能,重写ListView的适配器(BaseAdapter),从网络获取图片,图片缓存的处理,xml的解析。

            ①重写ListView的适配器,这部分可以参考上一篇文章,LazyAdapter.java          

复制代码

 1 import java.util.ArrayList;
 2 import java.util.HashMap;
 3 import android.app.Activity;
 4 import android.content.Context;
 5 import android.view.LayoutInflater;
 6 import android.view.View;
 7 import android.view.ViewGroup;
 8 import android.widget.BaseAdapter;
 9 import android.widget.ImageView;
10 import android.widget.TextView;
11 
12 public class LazyAdapter extends BaseAdapter {
13     
14     private Activity activity;
15     private ArrayList<HashMap<String, String>> data;
16     private static LayoutInflater inflater=null;
17     public ImageLoader imageLoader; //用来下载图片的类,后面有介绍
18     
19     public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
20         activity = a;
21         data=d;
22         inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
23         imageLoader=new ImageLoader(activity.getApplicationContext());
24     }
25 
26     public int getCount() {
27         return data.size();
28     }
29 
30     public Object getItem(int position) {
31         return position;
32     }
33 
34     public long getItemId(int position) {
35         return position;
36     }
37     
38     public View getView(int position, View convertView, ViewGroup parent) {
39         View vi=convertView;
40         if(convertView==null)
41             vi = inflater.inflate(R.layout.list_row, null);
42 
43         TextView title = (TextView)vi.findViewById(R.id.title); // 标题
44         TextView artist = (TextView)vi.findViewById(R.id.artist); // 歌手名
45         TextView duration = (TextView)vi.findViewById(R.id.duration); // 时长
46         ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image); // 缩略图
47         
48         HashMap<String, String> song = new HashMap<String, String>();
49         song = data.get(position);
50         
51         // 设置ListView的相关值
52         title.setText(song.get(CustomizedListView.KEY_TITLE));
53         artist.setText(song.get(CustomizedListView.KEY_ARTIST));
54         duration.setText(song.get(CustomizedListView.KEY_DURATION));
55         imageLoader.DisplayImage(song.get(CustomizedListView.KEY_THUMB_URL), thumb_image);
56         return vi;
57   <em>  }
58 }</em>

复制代码

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

复制代码

  1 import java.io.File; 
  2 import java.io.FileInputStream; 
  3 import java.io.FileNotFoundException; 
  4 import java.io.FileOutputStream; 
  5 import java.io.InputStream; 
  6 import java.io.OutputStream; 
  7 import java.net.HttpURLConnection; 
  8 import java.net.URL; 
  9 import java.util.Collections; 
 10 import java.util.Map; 
 11 import java.util.WeakHashMap; 
 12 import java.util.concurrent.ExecutorService; 
 13 import java.util.concurrent.Executors;  
 14 import android.app.Activity; 
 15 import android.content.Context; 
 16 import android.graphics.Bitmap; 
 17 import android.graphics.BitmapFactory; 
 18 import android.widget.ImageView; 
 19   
 20 public class ImageLoader { 
 21   
 22     MemoryCache memoryCache=new MemoryCache(); 
 23     FileCache fileCache; 
 24     private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>()); 
 25     ExecutorService executorService;  
 26   
 27     public ImageLoader(Context context){ 
 28         fileCache=new FileCache(context); 
 29         executorService=Executors.newFixedThreadPool(5); 
 30     } 
 31   
 32     final int stub_id = R.drawable.no_image; 
 33     public void DisplayImage(String url, ImageView imageView) 
 34     { 
 35         imageViews.put(imageView, url); 
 36         Bitmap bitmap=memoryCache.get(url); 
 37         if(bitmap!=null) 
 38             imageView.setImageBitmap(bitmap); 
 39         else
 40         { 
 41             queuePhoto(url, imageView); 
 42             imageView.setImageResource(stub_id); 
 43         } 
 44     } 
 45   
 46     private void queuePhoto(String url, ImageView imageView) 
 47     { 
 48         PhotoToLoad p=new PhotoToLoad(url, imageView); 
 49         executorService.submit(new PhotosLoader(p)); 
 50     } 
 51   
 52     private Bitmap getBitmap(String url) 
 53     { 
 54         File f=fileCache.getFile(url); 
 55   
 56         //从sd卡
 57         Bitmap b = decodeFile(f); 
 58         if(b!=null) 
 59             return b; 
 60   
 61         //从网络
 62         try { 
 63             Bitmap bitmap=null; 
 64             URL imageUrl = new URL(url); 
 65             HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection(); 
 66             conn.setConnectTimeout(30000); 
 67             conn.setReadTimeout(30000); 
 68             conn.setInstanceFollowRedirects(true); 
 69             InputStream is=conn.getInputStream(); 
 70             OutputStream os = new FileOutputStream(f); 
 71             Utils.CopyStream(is, os); 
 72             os.close(); 
 73             bitmap = decodeFile(f); 
 74             return bitmap; 
 75         } catch (Exception ex){ 
 76            ex.printStackTrace(); 
 77            return null; 
 78         } 
 79     } 
 80   
 81     //解码图像用来减少内存消耗
 82     private Bitmap decodeFile(File f){ 
 83         try { 
 84             //解码图像大小
 85             BitmapFactory.Options o = new BitmapFactory.Options(); 
 86             o.inJustDecodeBounds = true; 
 87             BitmapFactory.decodeStream(new FileInputStream(f),null,o); 
 88   
 89             //找到正确的刻度值,它应该是2的幂。
 90             final int REQUIRED_SIZE=70; 
 91             int width_tmp=o.outWidth, height_tmp=o.outHeight; 
 92             int scale=1; 
 93             while(true){ 
 94                 if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) 
 95                     break; 
 96                 width_tmp/=2; 
 97                 height_tmp/=2; 
 98                 scale*=2; 
 99             } 
100   
101             BitmapFactory.Options o2 = new BitmapFactory.Options(); 
102             o2.inSampleSize=scale; 
103             return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
104         } catch (FileNotFoundException e) {} 
105         return null; 
106     } 
107   
108     /任务队列
109     private class PhotoToLoad 
110     { 
111         public String url; 
112         public ImageView imageView; 
113         public PhotoToLoad(String u, ImageView i){ 
114             url=u; 
115             imageView=i; 
116         } 
117     } 
118   
119     class PhotosLoader implements Runnable { 
120         PhotoToLoad photoToLoad; 
121         PhotosLoader(PhotoToLoad photoToLoad){ 
122             this.photoToLoad=photoToLoad; 
123         } 
124   
125         @Override
126         public void run() { 
127             if(imageViewReused(photoToLoad)) 
128                 return; 
129             Bitmap bmp=getBitmap(photoToLoad.url); 
130             memoryCache.put(photoToLoad.url, bmp); 
131             if(imageViewReused(photoToLoad)) 
132                 return; 
133             BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad); 
134             Activity a=(Activity)photoToLoad.imageView.getContext(); 
135             a.runOnUiThread(bd); 
136         } 
137     } 
138   
139     boolean imageViewReused(PhotoToLoad photoToLoad){ 
140         String tag=imageViews.get(photoToLoad.imageView); 
141         if(tag==null || !tag.equals(photoToLoad.url)) 
142             return true; 
143         return false; 
144     } 
145   
146     //用于显示位图在UI线程
147     class BitmapDisplayer implements Runnable 
148     { 
149         Bitmap bitmap; 
150         PhotoToLoad photoToLoad; 
151         public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;} 
152         public void run() 
153         { 
154             if(imageViewReused(photoToLoad)) 
155                 return; 
156             if(bitmap!=null) 
157                 photoToLoad.imageView.setImageBitmap(bitmap); 
158             else
159                 photoToLoad.imageView.setImageResource(stub_id); 
160         } 
161     } 
162   
163     public void clearCache() { 
164         memoryCache.clear(); 
165         fileCache.clear(); 
166     } 
167   
168 } 

复制代码

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

复制代码

  1 import java.io.IOException; 
  2 import java.io.StringReader; 
  3 import java.io.UnsupportedEncodingException;   
  4 import javax.xml.parsers.DocumentBuilder; 
  5 import javax.xml.parsers.DocumentBuilderFactory; 
  6 import javax.xml.parsers.ParserConfigurationException;   
  7 import org.apache.http.HttpEntity; 
  8 import org.apache.http.HttpResponse; 
  9 import org.apache.http.client.ClientProtocolException; 
 10 import org.apache.http.client.methods.HttpPost; 
 11 import org.apache.http.impl.client.DefaultHttpClient; 
 12 import org.apache.http.util.EntityUtils; 
 13 import org.w3c.dom.Document; 
 14 import org.w3c.dom.Element; 
 15 import org.w3c.dom.Node; 
 16 import org.w3c.dom.NodeList; 
 17 import org.xml.sax.InputSource; 
 18 import org.xml.sax.SAXException;  
 19 import android.util.Log; 
 20   
 21 public class XMLParser { 
 22   
 23     // 构造方法
 24     public XMLParser() { 
 25   
 26     } 
 27   
 28     /** 
 29      * 从URL获取XML使HTTP请求
 30      * @param url string 
 31      * */
 32     public String getXmlFromUrl(String url) { 
 33         String xml = null; 
 34   
 35         try { 
 36             // defaultHttpClient 
 37             DefaultHttpClient httpClient = new DefaultHttpClient(); 
 38             HttpPost httpPost = new HttpPost(url); 
 39   
 40             HttpResponse httpResponse = httpClient.execute(httpPost); 
 41             HttpEntity httpEntity = httpResponse.getEntity(); 
 42             xml = EntityUtils.toString(httpEntity); 
 43   
 44         } catch (UnsupportedEncodingException e) { 
 45             e.printStackTrace(); 
 46         } catch (ClientProtocolException e) { 
 47             e.printStackTrace(); 
 48         } catch (IOException e) { 
 49             e.printStackTrace(); 
 50         } 
 51         return xml; 
 52     } 
 53   
 54     /** 
 55      * 获取XML DOM元素
 56      * @param XML string 
 57      * */
 58     public Document getDomElement(String xml){ 
 59         Document doc = null; 
 60         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
 61         try { 
 62   
 63             DocumentBuilder db = dbf.newDocumentBuilder(); 
 64   
 65             InputSource is = new InputSource(); 
 66                 is.setCharacterStream(new StringReader(xml)); 
 67                 doc = db.parse(is);  
 68   
 69             } catch (ParserConfigurationException e) { 
 70                 Log.e("Error: ", e.getMessage()); 
 71                 return null; 
 72             } catch (SAXException e) { 
 73                 Log.e("Error: ", e.getMessage()); 
 74                 return null; 
 75             } catch (IOException e) { 
 76                 Log.e("Error: ", e.getMessage()); 
 77                 return null; 
 78             } 
 79   
 80             return doc; 
 81     } 
 82   
 83     /** 获取节点值
 84       * @param elem element 
 85       */
 86      public final String getElementValue( Node elem ) { 
 87          Node child; 
 88          if( elem != null){ 
 89              if (elem.hasChildNodes()){ 
 90                  for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){ 
 91                      if( child.getNodeType() == Node.TEXT_NODE  ){ 
 92                          return child.getNodeValue(); 
 93                      } 
 94                  } 
 95              } 
 96          } 
 97          return ""; 
 98      } 
 99   
100      /** 
101       * 获取节点值
102       * @param Element node 
103       * @param key string 
104       * */
105      public String getValue(Element item, String str) { 
106             NodeList n = item.getElementsByTagName(str); 
107             return this.getElementValue(n.item(0)); 
108         } 
109 }

复制代码

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

     MemoryCache.java:

复制代码

 1 import java.lang.ref.SoftReference;
 2 import java.util.Collections;
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 import android.graphics.Bitmap;
 6 
 7 public class MemoryCache {
 8     private Map<String, SoftReference<Bitmap>> cache=Collections.synchronizedMap(new HashMap<String, SoftReference<Bitmap>>());//软引用
 9     
10     public Bitmap get(String id){
11         if(!cache.containsKey(id))
12             return null;
13         SoftReference<Bitmap> ref=cache.get(id);
14         return ref.get();
15     }
16     
17     public void put(String id, Bitmap bitmap){
18         cache.put(id, new SoftReference<Bitmap>(bitmap));
19     }
20 
21     public void clear() {
22         cache.clear();
23     }
24 }

复制代码

 FileCache.java

复制代码

 1 import java.io.File;
 2 import android.content.Context;
 3 
 4 public class FileCache {
 5     
 6     private File cacheDir;
 7     
 8     public FileCache(Context context){
 9         //找一个用来缓存图片的路径
10         if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
11             cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
12         else
13             cacheDir=context.getCacheDir();
14         if(!cacheDir.exists())
15             cacheDir.mkdirs();
16     }
17     
18     public File getFile(String url){
19         
20         String filename=String.valueOf(url.hashCode());
21         File f = new File(cacheDir, filename);
22         return f;
23         
24     }
25     
26     public void clear(){
27         File[] files=cacheDir.listFiles();
28         if(files==null)
29             return;
30         for(File f:files)
31             f.delete();
32     }
33 
34 }

复制代码

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

  1. import java.io.InputStream;  
  2. import java.io.OutputStream;  
  3.   
  4.   
  5. public class Utils {  
  6.     public static void CopyStream(InputStream is, OutputStream os)  
  7.     {  
  8.         final int buffer_size=1024;  
  9.         try  
  10.         {  
  11.             byte[] bytes=new byte[buffer_size];  
  12.             for(;;)  
  13.             {  
  14.               int count=is.read(bytes, 0, buffer_size);  
  15.               if(count==-1)  
  16.                   break;  
  17.               os.write(bytes, 0, count);   
  18.             }  
  19.             is.close();  
  20.             os.close(); 
  21.         }  
  22.         catch(Exception ex){}  
  23.     }  
  24. }  

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

复制代码

 1 public static byte[] readStream(InputStream inStream) throws Exception{
 2 
 3 ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
 4 byte[] buffer = new byte[1024];
 5 int len = -1;
 6 while( (len=inStream.read(buffer)) != -1){
 7 outSteam.write(buffer, 0, len);
 8 
 9 }
10 outSteam.close();
11 inStream.close();
12 return outSteam.toByteArray();
13 
14 }
15 }

复制代码

 最后就是主Activity的代码了,

复制代码

 1 package com.example.androidhive;
 2 
 3 import java.util.ArrayList;
 4 import java.util.HashMap;
 5 import org.w3c.dom.Document;
 6 import org.w3c.dom.Element;
 7 import org.w3c.dom.NodeList;
 8 import android.app.Activity;
 9 import android.os.Bundle;
10 import android.view.View;
11 import android.widget.AdapterView;
12 import android.widget.AdapterView.OnItemClickListener;
13 import android.widget.ListView;
14 
15 public class CustomizedListView extends Activity {
16     // 所有的静态变量
17     static final String URL = "http://api.androidhive.info/music/music.xml";//xml目的地址,打开地址看一下
18     // XML 节点
19     static final String KEY_SONG = "song"; // parent node
20     static final String KEY_ID = "id";
21     static final String KEY_TITLE = "title";
22     static final String KEY_ARTIST = "artist";
23     static final String KEY_DURATION = "duration";
24     static final String KEY_THUMB_URL = "thumb_url";
25     
26     ListView list;
27         LazyAdapter adapter;
28 
29     @Override
30     public void onCreate(Bundle savedInstanceState) {
31         super.onCreate(savedInstanceState);
32         setContentView(R.layout.main);
33         
34 
35         ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
36 
37         XMLParser parser = new XMLParser();
38         String xml = parser.getXmlFromUrl(URL); // 从网络获取xml
39         Document doc = parser.getDomElement(xml); // 获取 DOM 节点
40         
41         NodeList nl = doc.getElementsByTagName(KEY_SONG);
42         // 循环遍历所有的歌节点 <song>
43         for (int i = 0; i < nl.getLength(); i++) {
44             // 新建一个 HashMap
45             HashMap<String, String> map = new HashMap<String, String>();
46             Element e = (Element) nl.item(i);
47             //每个子节点添加到HashMap关键= >值
48             map.put(KEY_ID, parser.getValue(e, KEY_ID));
49             map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
50             map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
51             map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION));
52             map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));
53 
54             // HashList添加到数组列表
55             songsList.add(map);
56         }
57         
58 
59         list=(ListView)findViewById(R.id.list);
60         
61         
62               adapter=new LazyAdapter(this, songsList);        
63               list.setAdapter(adapter);
64         
65 
66         //为单一列表行添加单击事件
67 
68         list.setOnItemClickListener(new OnItemClickListener() {
69 
70             @Override
71             public void onItemClick(AdapterView<?> parent, View view,
72                     int position, long id) {
73                             
74                         //这里可以自由发挥,比如播放一首歌曲等等
75             }
76         });        
77     }    
78 }

复制代码

  最后看一下效果:

转载:http://blog.csdn.net/wangjinyu501/article/details/8219317 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值