Android 下 ListView 的使用
ListView 的使用比我想像中的要麻烦很多,所以有必要记录下来。
首先在界面拖放一个 ListView 控件,生成的 XML 如下所示:
<ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView>
ListView 每个子项显示需要与 Adapter 配合,这对于我来说不太好理解。
每个 ListView 子项需要格式说明,其 XML 如下(文件名是: my_mp3filelist.xml, 在后继的代码中要使用的):
<LinearLayout android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_height="wrap_content" android:id="@+id/my_mp3filelist" android:paddingBottom="3dip" > <TextView android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/ItemTitle" android:textSize="30dip"> </TextView> <TextView android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/ItemText"> </TextView> </LinearLayout>
以上,ListView 的准备就绪了。接下来就是准备数据,此示例用于显示音乐文件列表,音乐文件的信息来自于系统的类: MediaStore.Audio.Media。
将 MediaStore.Audio.Media 中程序需要的信息转存在自定义的类中,自定义的类如下:
// 此类中成员的个数根据个人需要定义,没有必要的成员可以删除的
public class Mp3Info { private String id; private String mp3Name; private String mp3Size; private String lrcName; private String lrcSize; private String mp3Artist; private long mp3Duration; private String mp3Url; public Mp3Info() { super(); } public Mp3Info(String id, String mp3Name, String mp3Size, String lrcName, String lrcSize, String mp3Artist) { super(); this.id = id; this.mp3Name = mp3Name; this.mp3Size = mp3Size; this.lrcName = lrcName; this.lrcSize = lrcSize; this.mp3Artist = mp3Artist; } @Override public String toString() { return "Mp3Info [id=" + id + ", mp3Name=" + mp3Name + ", mp3Size=" + mp3Size + ", lrcName=" + lrcName + ", lrcSize=" + lrcSize + ", duration=" + mp3Duration + "]"; } public String getId() { return id; } public void setId(String id) { this.id = id; } public void setId(long id) { this.id = Long.toString(id); } public String getMp3Name() { return mp3Name; } public void setTitle(String strName){ this.mp3Name = strName; } public void setArtist(String strArtist){ mp3Artist = strArtist; } public String GetArtist() { return this.mp3Artist; } public void setDuration(long duration){ mp3Duration = duration; } public void setMp3Name(String mp3Name) { this.mp3Name = mp3Name; } public String getMp3Size() { return mp3Size; } public void setMp3Size(String mp3Size) { this.mp3Size = mp3Size; } public void setSize(long strSize) { this.mp3Size = Long.toString(strSize); } public String getLrcName() { return lrcName; } public void setLrcName(String lrcName) { this.lrcName = lrcName; } public String getLrcSize() { return lrcSize; } public void setLrcSize(String lrcSize) { this.lrcSize = lrcSize; } public void setUrl(String strUrl) { this.mp3Url = strUrl; } public String GetUrl() { return this.mp3Url; } }
音乐信息的获取与转存代码如下:
1 /** 2 * 用于从数据库中查询歌曲的信息,保存在List当中 3 * class Mp3Info 有什么成员, 由 MediaStore.Audio.Media 和实际需要确定 4 */ 5 public static List<Mp3Info> getMp3Infos(Context context) { 6 Cursor cursor = context.getContentResolver().query( 7 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, 8 MediaStore.Audio.Media.DEFAULT_SORT_ORDER); 9 List<Mp3Info> mp3Infos = new ArrayList<Mp3Info>(); 10 for (int i = 0; i < cursor.getCount(); i++) { 11 Mp3Info mp3Info = new Mp3Info(); 12 cursor.moveToNext(); 13 long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID)); // 音乐id 14 String title = cursor.getString((cursor.getColumnIndex(MediaStore.Audio.Media.TITLE))); // 音乐标题 15 String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)); // 艺术家 16 long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)); // 时长 17 long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE)); // 文件大小 18 String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)); // 文件路径 19 int isMusic = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC)); // 是否为音乐 20 if (isMusic != 0) { // 只把音乐添加到集合当中 21 mp3Info.setId(id); 22 mp3Info.setTitle(title); 23 mp3Info.setArtist(artist); 24 mp3Info.setDuration(duration); 25 mp3Info.setSize(size); 26 mp3Info.setUrl(url); 27 mp3Infos.add(mp3Info); 28 } 29 } 30 31 32 return mp3Infos; 33 }
将保存后的音乐信息显示在 ListView 中:
(1) 定义相应变量及初始化
1 private ListView lvMp3File; 2 List<Mp3Info> mp3Infos; 3 4 lvMp3File = (ListView)findViewById(R.id.listView1);
(2) 数据显示
1 // 测试音乐文件遍历 - 需改为线程(考虑若数据量大时是否会影响 UI 显示的时长) 2 // 生成动态数组,并且加载数据 3 ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>(); 4 mp3Infos = getMp3Infos(getApplicationContext()); 5 for (Iterator<Mp3Info> iterator = mp3Infos.iterator(); iterator.hasNext();) { 6 Mp3Info mp3Info = (Mp3Info) iterator.next(); 7 Log.v("Leo - MP3 Name: ", mp3Info.getMp3Name()); 8 9 HashMap<String, String> map = new HashMap<String, String>(); 10 map.put("ItemTitle", mp3Info.getMp3Name()); 11 map.put("ItemText", mp3Info.GetArtist()); 12 // map.put("url", mp3Info.GetUrl()); 13 mylist.add(map); 14 15 // 生成 Apapter(适配器), 数组 -> ListItem 16 SimpleAdapter mSchedule = new SimpleAdapter(this, 17 // 数据来源 18 mylist, 19 // ListItem 的 XML 实现 20 R.layout.my_mp3filelist, 21 // 动态数组与 ListItem 对应的子项 22 new String[] {"ItemTitle", "ItemText"}, 23 // ListItem 的 XML 文件里面的两个 TextView ID 24 new int[] {R.id.ItemTitle,R.id.ItemText}); 25 26 lvMp3File.setAdapter(mSchedule); 27 }
此段代码在示例中,是放在主窗体的 protected void onCreate(Bundle savedInstanceState) 过程中。
ListView 还需要响应用户的点击操作,需要如下的声明:
1 lvMp3File.setOnItemClickListener(new MusicListItemClickListener());
MusicListItemClickListener 的实现如下:
1 private class MusicListItemClickListener implements OnItemClickListener 2 { 3 @Override 4 public void onItemClick(AdapterView<?> parent, View view, int position,long id) 5 { 6 if(mp3Infos != null) 7 { 8 // Leo 界面切换: 切换到播放界面 9 // Intent goPlaying = new Intent(MainActivity.this, PlayingActivity.class); 10 // startActivity(goPlaying); 11 Intent goPlayingIntent = new Intent(); 12 goPlayingIntent.setClass(MainActivity.this, PlayingActivity.class); 13 startActivity(goPlayingIntent); 14 15 // 启动音乐后台播放服务 16 /* 若不做延时直接调用 run 中的代码,歌曲信息无法正确获取到 */ 17 positionSelected = position; 18 Timer timer = new Timer(); 19 TimerTask task = new TimerTask(){ 20 public void run(){ 21 Mp3Info mp3Info = mp3Infos.get(positionSelected); 22 Log.d("mp3Info-->", mp3Info.toString()); 23 Intent intent = new Intent(); 24 intent.putExtra("url", mp3Info.GetUrl()); 25 intent.putExtra("listPosition", positionSelected/*getPlayingIndex(mp3Info.GetUrl())*/); 26 intent.putExtra("MSG", AppConstant.PlayerMsg.PLAY_MSG.ordinal()); 27 intent.setClass(MainActivity.this, PlayerService.class); 28 startService(intent); // 启动服务 29 } 30 }; 31 timer.schedule(task, 300); // 0.3 秒后执行 run 中的代码段 32 } 33 }