Android 下 ListView 的使用方法详解
扫描二维码
随时随地手机看文章
ListView 的使用比我想像中的要麻烦很多,所以有必要记录下来。
首先在界面拖放一个 ListView 控件,生成的 XML。
ListView 每个子项显示需要与 Adapter 配合,这对于我来说不太好理解。
每个 ListView 子项需要格式说明,其 XML 如下(文件名是: my_mp3filelist.xml, 在后继的代码中要使用的):
以上,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; } }
音乐信息的获取与转存代码如下:
/** * 用于从数据库中查询歌曲的信息,保存在List当中 * class Mp3Info 有什么成员, 由 MediaStore.Audio.Media 和实际需要确定 */ public static ListgetMp3Infos(Context context) { Cursor cursor = context.getContentResolver().query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER); Listmp3Infos = new ArrayList(); for (int i = 0; i < cursor.getCount(); i++) { Mp3Info mp3Info = new Mp3Info(); cursor.moveToNext(); long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID)); // 音乐id String title = cursor.getString((cursor.getColumnIndex(MediaStore.Audio.Media.TITLE))); // 音乐标题 String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)); // 艺术家 long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)); // 时长 long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE)); // 文件大小 String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)); // 文件路径 int isMusic = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC)); // 是否为音乐 if (isMusic != 0) { // 只把音乐添加到集合当中 mp3Info.setId(id); mp3Info.setTitle(title); mp3Info.setArtist(artist); mp3Info.setDuration(duration); mp3Info.setSize(size); mp3Info.setUrl(url); mp3Infos.add(mp3Info); } } return mp3Infos; }
将保存后的音乐信息显示在 ListView 中:
(1) 定义相应变量及初始化
private ListView lvMp3File; Listmp3Infos; lvMp3File = (ListView)findViewById(R.id.listView1);
(2) 数据显示
// 测试音乐文件遍历 - 需改为线程(考虑若数据量大时是否会影响 UI 显示的时长) // 生成动态数组,并且加载数据 ArrayList<HashMap> mylist = new ArrayList<HashMap>(); mp3Infos = getMp3Infos(getApplicationContext()); for (Iteratoriterator = mp3Infos.iterator(); iterator.hasNext();) { Mp3Info mp3Info = (Mp3Info) iterator.next(); Log.v("Leo - MP3 Name: ", mp3Info.getMp3Name()); HashMapmap = new HashMap(); map.put("ItemTitle", mp3Info.getMp3Name()); map.put("ItemText", mp3Info.GetArtist()); // map.put("url", mp3Info.GetUrl()); mylist.add(map); // 生成 Apapter(适配器), 数组 -> ListItem SimpleAdapter mSchedule = new SimpleAdapter(this, // 数据来源 mylist, // ListItem 的 XML 实现 R.layout.my_mp3filelist, // 动态数组与 ListItem 对应的子项 new String[] {"ItemTitle", "ItemText"}, // ListItem 的 XML 文件里面的两个 TextView ID new int[] {R.id.ItemTitle,R.id.ItemText}); lvMp3File.setAdapter(mSchedule); }
此段代码在示例中,是放在主窗体的 protected void onCreate(Bundle savedInstanceState) 过程中。
ListView 还需要响应用户的点击操作,需要如下的声明:
lvMp3File.setOnItemClickListener(new MusicListItemClickListener());
MusicListItemClickListener 的实现如下:
private class MusicListItemClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView parent, View view, int position,long id) { if(mp3Infos != null) { // Leo 界面切换: 切换到播放界面 // Intent goPlaying = new Intent(MainActivity.this, PlayingActivity.class); // startActivity(goPlaying); Intent goPlayingIntent = new Intent(); goPlayingIntent.setClass(MainActivity.this, PlayingActivity.class); startActivity(goPlayingIntent); // 启动音乐后台播放服务 /* 若不做延时直接调用 run 中的代码,歌曲信息无法正确获取到 */ positionSelected = position; Timer timer = new Timer(); TimerTask task = new TimerTask(){ public void run(){ Mp3Info mp3Info = mp3Infos.get(positionSelected); Log.d("mp3Info-->", mp3Info.toString()); Intent intent = new Intent(); intent.putExtra("url", mp3Info.GetUrl()); intent.putExtra("listPosition", positionSelected/*getPlayingIndex(mp3Info.GetUrl())*/); intent.putExtra("MSG", AppConstant.PlayerMsg.PLAY_MSG.ordinal()); intent.setClass(MainActivity.this, PlayerService.class); startService(intent); // 启动服务 } }; timer.schedule(task, 300); // 0.3 秒后执行 run 中的代码段 } }