2013年5月25日 简、美音乐播放器开发
小巫在这里罗列这个播放器已经实现的功能:
1. 自动显示音乐列表
2. 点击列表播放音乐
3. 长按列表弹出对话框
4. 暂停音乐
5. 上一首音乐
6. 下一首音乐
7. 自动播放下一首歌曲
8. 单曲循环
9. 全部循环
10. 随机播放
以上所有功能将会分为两篇博文来讲解,首先是主界面的,接着是播放界面的。在这里要说明一点,以上功能是小巫自己一点一点调试才实现的,并不能完全排除考虑不周的地方,原本这个软件实现起来并不太难,但确实要考虑到很多细节的地方,播放状态的切换和控制就是一块,也花了我不少实现,之前还很苦恼实现自己想要的效果,但后来还是经过思考和调试把功能实现。所以说,开发是一个需要很耐心的过程,各位童鞋,如果真正喜欢编程的话,想要做出一些小作品的话,那就好好掂量自己的耐心吧,好了,废话不多说,先贴一大段代码,后面在慢慢把需要注意的地方说一下。
主界面效果图:
以上界面的效果怎么实现的?
很简单的,就是ListView的数据填充,但要填的的东西就要考虑了,怎么把数据从SQLite中获取,小巫封装了一个工具类,用来获取与MP3相关的数据。
==>MediaUtils
- package com.wwj.sb.utils;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import android.content.Context;
- import android.database.Cursor;
- import android.provider.MediaStore;
- import com.wwj.sb.domain.Mp3Info;
- public class MediaUtil {
- /**
- * 用于从数据库中查询歌曲的信息,保存在List当中
- *
- * @return
- */
- public static List<Mp3Info> getMp3Infos(Context context) {
- Cursor cursor = context.getContentResolver().query(
- MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
- MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
- List<Mp3Info> mp3Infos = new ArrayList<Mp3Info>();
- for (int i = 0; i < cursor.getCount(); i++) {
- cursor.moveToNext();
- Mp3Info mp3Info = new Mp3Info();
- 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;
- }
- /**
- * 往List集合中添加Map对象数据,每一个Map对象存放一首音乐的所有属性
- * @param mp3Infos
- * @return
- */
- public static List<HashMap<String, String>> getMusicMaps(
- List<Mp3Info> mp3Infos) {
- List<HashMap<String, String>> mp3list = new ArrayList<HashMap<String, String>>();
- for (Iterator iterator = mp3Infos.iterator(); iterator.hasNext();) {
- Mp3Info mp3Info = (Mp3Info) iterator.next();
- HashMap<String, String> map = new HashMap<String, String>();
- map.put("title", mp3Info.getTitle());
- map.put("Artist", mp3Info.getArtist());
- map.put("duration", formatTime(mp3Info.getDuration()));
- map.put("size", String.valueOf(mp3Info.getSize()));
- map.put("url", mp3Info.getUrl());
- mp3list.add(map);
- }
- return mp3list;
- }
- /**
- * 格式化时间,将毫秒转换为分:秒格式
- * @param time
- * @return
- */
- public static String formatTime(long time) {
- String min = time / (1000 * 60) + "";
- String sec = time % (1000 * 60) + "";
- if (min.length() < 2) {
- min = "0" + time / (1000 * 60) + "";
- } else {
- min = time / (1000 * 60) + "";
- }
- if (sec.length() == 4) {
- sec = "0" + (time % (1000 * 60)) + "";
- } else if (sec.length() == 3) {
- sec = "00" + (time % (1000 * 60)) + "";
- } else if (sec.length() == 2) {
- sec = "000" + (time % (1000 * 60)) + "";
- } else if (sec.length() == 1) {
- sec = "0000" + (time % (1000 * 60)) + "";
- }
- return min + ":" + sec.trim().substring(0, 2);
- }
- }
好吧,来重头戏了,一大段代码来袭。
HomeActivity.Java
- package com.wwj.sb.activity;
- import java.util.HashMap;
- import java.util.List;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.app.Service;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.graphics.Color;
- import android.os.Bundle;
- import android.os.Vibrator;
- import android.view.ContextMenu;
- import android.view.ContextMenu.ContextMenuInfo;
- import android.view.KeyEvent;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.View.OnCreateContextMenuListener;
- import android.view.ViewGroup.LayoutParams;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.ArrayAdapter;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.ListView;
- import android.widget.SimpleAdapter;
- import android.widget.TextView;
- import android.widget.Toast;
- import com.wwj.sb.domain.AppConstant;
- import com.wwj.sb.domain.Mp3Info;
- import com.wwj.sb.service.PlayerService;
- import com.wwj.sb.utils.ConstantUtil;
- import com.wwj.sb.utils.CustomDialog;
- import com.wwj.sb.utils.MediaUtil;
- /**
- * 2013/5/7
- * 简、美音乐播放器
- * @author wwj
- *
- */
- public class HomeActivity extends Activity {
- private ListView mMusiclist; // 音乐列表
- private List<Mp3Info> mp3Infos = null;
- private SimpleAdapter mAdapter; // 简单适配器
- private Button previousBtn; // 上一首
- private Button repeatBtn; // 重复(单曲循环、全部循环)
- private Button playBtn; // 播放(播放、暂停)
- private Button shuffleBtn; // 随机播放
- private Button nextBtn; // 下一首
- private TextView musicTitle;//歌曲标题
- private TextView musicDuration; //歌曲时间
- private Button musicPlaying; //歌曲专辑
- private int repeatState; //循环标识
- private final int isCurrentRepeat = 1; // 单曲循环
- private final int isAllRepeat = 2; // 全部循环
- private final int isNoneRepeat = 3; // 无重复播放
- private boolean isFirstTime = true;
- private boolean isPlaying; // 正在播放
- private boolean isPause; // 暂停
- private boolean isNoneShuffle = true; // 顺序播放
- private boolean isShuffle = false; // 随机播放
- private int listPosition = 0; //标识列表位置
- private HomeReceiver homeReceiver; //自定义的广播接收器
- //一系列动作
- public static final String UPDATE_ACTION = "com.wwj.action.UPDATE_ACTION";
- public static final String CTL_ACTION = "com.wwj.action.CTL_ACTION";
- public static final String MUSIC_CURRENT = "com.wwj.action.MUSIC_CURRENT";
- public static final String MUSIC_DURATION = "com.wwj.action.MUSIC_DURATION";
- public static final String REPEAT_ACTION = "com.wwj.action.REPEAT_ACTION";
- public static final String SHUFFLE_ACTION = "com.wwj.action.SHUFFLE_ACTION";
- private int currentTime;
- private int duration;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.home_activity_layout);
- mMusiclist = (ListView) findViewById(R.id.music_list);
- mMusiclist.setOnItemClickListener(new MusicListItemClickListener());
- mMusiclist.setOnCreateContextMenuListener(new MusicListItemContextMenuListener());
- mp3Infos = MediaUtil.getMp3Infos(getApplicationContext()); //获取歌曲对象集合
- setListAdpter(MediaUtil.getMusicMaps(mp3Infos)); //显示歌曲列表
- findViewById(); //找到界面上的每一个控件
- setViewOnclickListener(); //为一些控件设置监听器
- repeatState = isNoneRepeat; // 初始状态为无重复播放状态
- homeReceiver = new HomeReceiver();
- // 创建IntentFilter
- IntentFilter filter = new IntentFilter();
- // 指定BroadcastReceiver监听的Action
- filter.addAction(UPDATE_ACTION);
- filter.addAction(MUSIC_CURRENT);
- filter.addAction(MUSIC_DURATION);
- filter.addAction(REPEAT_ACTION);
- filter.addAction(SHUFFLE_ACTION);
- // 注册BroadcastReceiver
- registerReceiver(homeReceiver, filter);
- }
- /**
- * 从界面上根据id获取按钮
- */
- private void findViewById() {
- previousBtn = (Button) findViewById(R.id.previous_music);
- repeatBtn = (Button) findViewById(R.id.repeat_music);
- playBtn = (Button) findViewById(R.id.play_music);
- shuffleBtn = (Button) findViewById(R.id.shuffle_music);
- nextBtn = (Button) findViewById(R.id.next_music);
- musicTitle = (TextView) findViewById(R.id.music_title);
- musicDuration = (TextView) findViewById(R.id.music_duration);
- musicPlaying = (Button) findViewById(R.id.playing);
- }
- /**
- * 给每一个按钮设置监听器
- */
- private void setViewOnclickListener() {
- ViewOnClickListener viewOnClickListener = new ViewOnClickListener();
- previousBtn.setOnClickListener(viewOnClickListener);
- repeatBtn.setOnClickListener(viewOnClickListener);
- playBtn.setOnClickListener(viewOnClickListener);
- shuffleBtn.setOnClickListener(viewOnClickListener);
- nextBtn.setOnClickListener(viewOnClickListener);
- musicPlaying.setOnClickListener(viewOnClickListener);
- }
- private class ViewOnClickListener implements OnClickListener {
- Intent intent = new Intent();
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.previous_music: // 上一首
- playBtn.setBackgroundResource(R.drawable.play_selector);
- isFirstTime = false;
- isPlaying = true;
- isPause = false;
- previous();
- break;
- case R.id.repeat_music: // 重复播放
- if (repeatState == isNoneRepeat) {
- repeat_one();
- shuffleBtn.setClickable(false);
- repeatState = isCurrentRepeat;
- } else if (repeatState == isCurrentRepeat) {
- repeat_all();
- shuffleBtn.setClickable(false);
- repeatState = isAllRepeat;
- } else if (repeatState == isAllRepeat) {
- repeat_none();
- shuffleBtn.setClickable(true);
- repeatState = isNoneRepeat;
- }
- switch (repeatState) {
- case isCurrentRepeat: // 单曲循环
- repeatBtn
- .setBackgroundResource(R.drawable.repeat_current_selector);
- Toast.makeText(HomeActivity.this, R.string.repeat_current,
- Toast.LENGTH_SHORT).show();
- break;
- case isAllRepeat: // 全部循环
- repeatBtn
- .setBackgroundResource(R.drawable.repeat_all_selector);
- Toast.makeText(HomeActivity.this, R.string.repeat_all,
- Toast.LENGTH_SHORT).show();
- break;
- case isNoneRepeat: // 无重复
- repeatBtn
- .setBackgroundResource(R.drawable.repeat_none_selector);
- Toast.makeText(HomeActivity.this, R.string.repeat_none,
- Toast.LENGTH_SHORT).show();
- break;
- }
- break;
- case R.id.play_music: // 播放音乐
- if(isFirstTime) {
- play();
- isFirstTime = false;
- isPlaying = true;
- isPause = false;
- } else {
- if (isPlaying) {
- playBtn.setBackgroundResource(R.drawable.pause_selector);
- intent.setAction("com.wwj.media.MUSIC_SERVICE");
- intent.putExtra("MSG", AppConstant.PlayerMsg.PAUSE_MSG);
- startService(intent);
- isPlaying = false;
- isPause = true;
- } else if (isPause) {
- playBtn.setBackgroundResource(R.drawable.play_selector);
- intent.setAction("com.wwj.media.MUSIC_SERVICE");
- intent.putExtra("MSG", AppConstant.PlayerMsg.CONTINUE_MSG);
- startService(intent);
- isPause = false;
- isPlaying = true;
- }
- }
- break;
- case R.id.shuffle_music: // 随机播放
- if (isNoneShuffle) {
- shuffleBtn
- .setBackgroundResource(R.drawable.shuffle_selector);
- Toast.makeText(HomeActivity.this, R.string.shuffle,
- Toast.LENGTH_SHORT).show();
- isNoneShuffle = false;
- isShuffle = true;
- shuffleMusic();
- repeatBtn.setClickable(false);
- } else if (isShuffle) {
- shuffleBtn
- .setBackgroundResource(R.drawable.shuffle_none_selector);
- Toast.makeText(HomeActivity.this, R.string.shuffle_none,
- Toast.LENGTH_SHORT).show();
- isShuffle = false;
- isNoneShuffle = true;
- repeatBtn.setClickable(true);
- }
- break;
- case R.id.next_music: // 下一首
- playBtn.setBackgroundResource(R.drawable.play_selector);
- isFirstTime = false;
- isPlaying = true;
- isPause = false;
- next();
- break;
- case R.id.playing: //正在播放
- Mp3Info mp3Info = mp3Infos.get(listPosition);
- Intent intent = new Intent(HomeActivity.this, PlayerActivity.class);
- intent.putExtra("title", mp3Info.getTitle());
- intent.putExtra("url", mp3Info.getUrl());
- intent.putExtra("artist", mp3Info.getArtist());
- intent.putExtra("listPosition", listPosition);
- intent.putExtra("currentTime", currentTime);
- intent.putExtra("duration", duration);
- intent.putExtra("MSG", AppConstant.PlayerMsg.PLAYING_MSG);
- startActivity(intent);
- break;
- }
- }
- }
- private class MusicListItemClickListener implements OnItemClickListener {
- /**
- * 点击列表播放音乐
- */
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- listPosition = position;
- playMusic(listPosition);
- }
- }
- public class MusicListItemContextMenuListener implements OnCreateContextMenuListener {
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
- Vibrator vibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
- vibrator.vibrate(50); //长按振动
- musicListItemDialog(); //长按后弹出的对话框
- }
- }
- /**
- * 填充列表
- *
- * @param mp3Infos
- */
- public void setListAdpter(List<HashMap<String, String>> mp3list) {
- mAdapter = new SimpleAdapter(this, mp3list,
- R.layout.music_list_item_layout, new String[] { "title",
- "Artist", "duration" }, new int[] { R.id.music_title,
- R.id.music_Artist, R.id.music_duration });
- mMusiclist.setAdapter(mAdapter);
- }
- /**
- * 下一首歌曲
- */
- public void next() {
- listPosition = listPosition + 1;
- if(listPosition <= mp3Infos.size() - 1) {
- Mp3Info mp3Info = mp3Infos.get(listPosition);
- musicTitle.setText(mp3Info.getTitle());
- Intent intent = new Intent();
- intent.setAction("com.wwj.media.MUSIC_SERVICE");
- intent.putExtra("listPosition", listPosition);
- intent.putExtra("url", mp3Info.getUrl());
- intent.putExtra("MSG", AppConstant.PlayerMsg.NEXT_MSG);
- startService(intent);
- } else {
- Toast.makeText(HomeActivity.this, "没有下一首了", Toast.LENGTH_SHORT).show();
- }
- }
- /**
- * 上一首歌曲
- */
- public void previous() {
- listPosition = listPosition - 1;
- if(listPosition >= 0) {
- Mp3Info mp3Info = mp3Infos.get(listPosition);
- musicTitle.setText(mp3Info.getTitle());
- Intent intent = new Intent();
- intent.setAction("com.wwj.media.MUSIC_SERVICE");
- intent.putExtra("listPosition", listPosition);
- intent.putExtra("url", mp3Info.getUrl());
- intent.putExtra("MSG", AppConstant.PlayerMsg.PRIVIOUS_MSG);
- startService(intent);
- }else {
- Toast.makeText(HomeActivity.this, "没有上一首了", Toast.LENGTH_SHORT).show();
- }
- }
- public void play() {
- playBtn.setBackgroundResource(R.drawable.play_selector);
- Mp3Info mp3Info = mp3Infos.get(listPosition);
- musicTitle.setText(mp3Info.getTitle());
- Intent intent = new Intent();
- intent.setAction("com.wwj.media.MUSIC_SERVICE");
- intent.putExtra("listPosition", 0);
- intent.putExtra("url", mp3Info.getUrl());
- intent.putExtra("MSG", AppConstant.PlayerMsg.PLAY_MSG);
- startService(intent);
- }
- /**
- * 单曲循环
- */
- public void repeat_one() {
- Intent intent = new Intent(CTL_ACTION);
- intent.putExtra("control", 1);
- sendBroadcast(intent);
- }
- /**
- * 全部循环
- */
- public void repeat_all() {
- Intent intent = new Intent(CTL_ACTION);
- intent.putExtra("control", 2);
- sendBroadcast(intent);
- }
- /**
- * 顺序播放
- */
- public void repeat_none() {
- Intent intent = new Intent(CTL_ACTION);
- intent.putExtra("control", 3);
- sendBroadcast(intent);
- }
- /**
- * 随机播放
- */
- public void shuffleMusic() {
- Intent intent = new Intent(CTL_ACTION);
- intent.putExtra("control", 4);
- sendBroadcast(intent);
- }
- public void musicListItemDialog() {
- String[] menuItems = new String[]{"播放音乐","设为铃声","查看详情"};
- ListView menuList = new ListView(HomeActivity.this);
- menuList.setCacheColorHint(Color.TRANSPARENT);
- menuList.setDividerHeight(1);
- menuList.setAdapter(new ArrayAdapter<String>(HomeActivity.this, R.layout.context_dialog_layout, R.id.dialogText, menuItems));
- menuList.setLayoutParams(new LayoutParams(ConstantUtil.getScreen(HomeActivity.this)[0] / 2, LayoutParams.WRAP_CONTENT));
- final CustomDialog customDialog = new CustomDialog.Builder(HomeActivity.this).setTitle(R.string.operation).setView(menuList).create();
- customDialog.show();
- menuList.setOnItemClickListener( new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- customDialog.cancel();
- customDialog.dismiss();
- }
- });
- }
- public void playMusic(int listPosition) {
- if (mp3Infos != null) {
- Mp3Info mp3Info = mp3Infos.get(listPosition);
- musicTitle.setText(mp3Info.getTitle());
- Intent intent = new Intent(HomeActivity.this, PlayerActivity.class);
- intent.putExtra("title", mp3Info.getTitle());
- intent.putExtra("url", mp3Info.getUrl());
- intent.putExtra("artist", mp3Info.getArtist());
- intent.putExtra("listPosition", listPosition);
- intent.putExtra("currentTime", currentTime);
- intent.putExtra("repeatState", repeatState);
- intent.putExtra("shuffleState", isShuffle);
- intent.putExtra("MSG", AppConstant.PlayerMsg.PLAY_MSG);
- startActivity(intent);
- }
- }
- @Override
- protected void onStop() {
- // TODO Auto-generated method stub
- super.onStop();
- }
- @Override
- protected void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- }
- /**
- * 按返回键弹出对话框确定退出
- */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK
- && event.getAction() == KeyEvent.ACTION_DOWN) {
- new AlertDialog.Builder(this)
- .setIcon(R.drawable.ic_launcher)
- .setTitle("退出")
- .setMessage("您确定要退出?")
- .setNegativeButton("取消", null)
- .setPositiveButton("确定",
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog,
- int which) {
- finish();
- Intent intent = new Intent(
- HomeActivity.this,
- PlayerService.class);
- unregisterReceiver(homeReceiver);
- stopService(intent); // 停止后台服务
- }
- }).show();
- }
- return super.onKeyDown(keyCode, event);
- }
- //自定义的BroadcastReceiver,负责监听从Service传回来的广播
- public class HomeReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if(action.equals(MUSIC_CURRENT)){
- //currentTime代表当前播放的时间
- currentTime = intent.getIntExtra("currentTime", -1);
- musicDuration.setText(MediaUtil.formatTime(currentTime));
- } else if (action.equals(MUSIC_DURATION)) {
- duration = intent.getIntExtra("duration", -1);
- }
- else if(action.equals(UPDATE_ACTION)) {
- //获取Intent中的current消息,current代表当前正在播放的歌曲
- listPosition = intent.getIntExtra("current", -1);
- if(listPosition >= 0) {
- musicTitle.setText(mp3Infos.get(listPosition).getTitle());
- }
- }else if(action.equals(REPEAT_ACTION)) {
- repeatState = intent.getIntExtra("repeatState", -1);
- switch (repeatState) {
- case isCurrentRepeat: // 单曲循环
- repeatBtn
- .setBackgroundResource(R.drawable.repeat_current_selector);
- shuffleBtn.setClickable(false);
- break;
- case isAllRepeat: // 全部循环
- repeatBtn
- .setBackgroundResource(R.drawable.repeat_all_selector);
- shuffleBtn.setClickable(false);
- break;
- case isNoneRepeat: // 无重复
- repeatBtn
- .setBackgroundResource(R.drawable.repeat_none_selector);
- shuffleBtn.setClickable(true);
- break;
- }
- }
- else if(action.equals(SHUFFLE_ACTION)) {
- isShuffle = intent.getBooleanExtra("shuffleState", false);
- if(isShuffle) {
- isNoneShuffle = false;
- shuffleBtn.setBackgroundResource(R.drawable.shuffle_selector);
- repeatBtn.setClickable(false);
- } else {
- isNoneShuffle = true;
- shuffleBtn.setBackgroundResource(R.drawable.shuffle_none_selector);
- repeatBtn.setClickable(true);
- }
- }
- }
- }
- }
到这里,要开讲啦。
以下是需要注意的几点:
1. 音乐是通过Service来播放的,Activity通过启动服务来实现在后台播放音乐。
2. Activity中自定义了一个广播接收器,需要进行intent过滤器的定义,动作的添加,注册广播接收器:
- <span style="white-space:pre"> </span>homeReceiver = new HomeReceiver();
- // 创建IntentFilter
- IntentFilter filter = new IntentFilter();
- // 指定BroadcastReceiver监听的Action
- filter.addAction(UPDATE_ACTION);
- filter.addAction(MUSIC_CURRENT);
- filter.addAction(MUSIC_DURATION);
- filter.addAction(REPEAT_ACTION);
- filter.addAction(SHUFFLE_ACTION);
- // 注册BroadcastReceiver
- registerReceiver(homeReceiver, filter);
3. 在广播接收器类当中对动作进行处理,比如实现时间的更新和标题的更新等。
4. 这里还要注意按钮触发,播放状态的改变,比如音乐循环,有三种状态:单曲、全部循环、顺序,每切换一个状态都要向服务发送一条广播,通知它要改变状态。
5. 点击列表的时候,会跳入到播放界面的Activity中,要注意用intent来传递参数,注意每个参数的用途,比如title、url、MSG,就分别代表标题、路径、播放状态。
6. 长按列表会弹出自定义对话框,也会有短暂的震动效果,自定义对话框需要自行实现。这里我也贴一下实现代码吧。
- package com.wwj.sb.utils;
- import android.app.Activity;
- import android.app.Dialog;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.text.TextUtils;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.ViewGroup.LayoutParams;
- import android.widget.Button;
- import android.widget.FrameLayout;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- import com.wwj.sb.activity.R;
- /**
- * 自定义对话框类
- *
- * @author wwj
- *
- */
- public class CustomDialog extends Dialog {
- public CustomDialog(Context context) {
- super(context);
- }
- public CustomDialog(Context context, int theme) {
- super(context, theme);
- }
- public static class Builder {
- private Context context;
- private int mIcon = -1; // 提示图标
- private CharSequence mTitle; // 提示标题
- private CharSequence mMessage; // 提示内容
- private CharSequence mPositiveButtonText; // 确定按钮文本
- private CharSequence mNegativeButtonText; // 取消按钮文本
- private CharSequence mNeutralButtonText; // 中间按钮文本
- private boolean mCancelable = true; // 是否启用取消键
- private int mViewSpacingLeft;
- private int mViewSpacingTop;
- private int mViewSpacingRight;
- private int mViewSpacingBottom;
- private boolean mViewSpacingSpecified = false;
- // 提示内容View
- private View mView;
- // 各种触发事件
- private OnClickListener mPositiveButtonClickListener,
- mNegativeButtonClickListener, mNeutralButtonClickListener;
- private OnCancelListener mCancelListener; // 取消键事件
- private OnKeyListener mKeyListener; // 按键处理
- public Builder(Context context) {
- this.context = context;
- }
- public Builder setMessage(CharSequence message) {
- this.mMessage = message;
- return this;
- }
- public Builder setMessage(int message) {
- this.mMessage = context.getText(message);
- return this;
- }
- public Builder setTitle(int title) {
- this.mTitle = context.getText(title);
- return this;
- }
- public Builder setTitle(CharSequence title) {
- this.mTitle = title;
- return this;
- }
- public Builder setIcon(int icon) {
- this.mIcon = icon;
- return this;
- }
- public Builder setView(View view) {
- this.mView = view;
- mViewSpacingSpecified = false;
- return this;
- }
- public Builder setView(View view, int left, int top, int right,
- int bottom) {
- this.mView = view;
- this.mViewSpacingLeft = left;
- this.mViewSpacingTop = top;
- this.mViewSpacingRight = right;
- this.mViewSpacingBottom = bottom;
- mViewSpacingSpecified = true;
- return this;
- }
- public Builder setPositonButton(int textId,
- final OnClickListener listener) {
- this.mPositiveButtonText = context.getText(textId);
- this.mPositiveButtonClickListener = listener;
- return this;
- }
- public Builder setPostionButton(String text,
- final OnClickListener listener) {
- this.mPositiveButtonText = text;
- this.mPositiveButtonClickListener = listener;
- return this;
- }
- public Builder setNeutralButton(int textId,
- final OnClickListener listener) {
- this.mNeutralButtonText = context.getText(textId);
- this.mNeutralButtonClickListener = listener;
- return this;
- }
- public Builder setNeutralButton(String text, final OnClickListener listener) {
- this.mNeutralButtonText = text;
- this.mNeutralButtonClickListener = listener;
- return this;
- }
- public Builder setNegativeButton(int textId,
- final OnClickListener listener) {
- this.mNegativeButtonText = context.getText(textId);
- this.mNegativeButtonClickListener = listener;
- return this;
- }
- public Builder setNegativeButton(String text,
- final OnClickListener listener) {
- this.mNegativeButtonText = text;
- this.mNegativeButtonClickListener = listener;
- return this;
- }
- public Builder setCancelable(boolean cancelable) {
- this.mCancelable = cancelable;
- return this;
- }
- public Builder setOnCancelListener(OnCancelListener listener) {
- this.mCancelListener = listener;
- return this;
- }
- public Builder setOnKeyListener(OnKeyListener listener) {
- this.mKeyListener = listener;
- return this;
- }
- public CustomDialog create() {
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- final CustomDialog dialog = new CustomDialog(context, R.style.CustomDialog);
- dialog.setCancelable(mCancelable);
- //设置取消键事件
- if(mCancelListener != null) {
- dialog.setOnCancelListener(mCancelListener);
- }
- //设置键盘监听事件
- if(mKeyListener != null) {
- dialog.setOnKeyListener(mKeyListener);
- }
- //获取对话框布局
- View layout = inflater.inflate(R.layout.alert_dialog, (ViewGroup)(((Activity)context).findViewById(R.id.parentPanel)));
- layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
- //设置标题
- ((TextView) layout.findViewById(R.id.alertTitle)).setText(mTitle);
- //设置图标
- if(mIcon != -1) {
- ((ImageView) layout.findViewById(R.id.icon))
- .setBackgroundResource(mIcon);
- }
- int count = 0;
- //设置确定按钮
- if(setButton(layout, mPositiveButtonText, R.id.button1, dialog, mPositiveButtonClickListener)) count++;
- // 设置拒绝按钮
- if(setButton(layout, mNegativeButtonText, R.id.button2, dialog, mNegativeButtonClickListener)) count++;
- // 设置中间按钮
- if(setButton(layout, mNeutralButtonText, R.id.button3, dialog, mNeutralButtonClickListener)) count++;
- if(count == 0) {
- layout.findViewById(R.id.buttonPanel).setVisibility(View.GONE);
- }
- //一个按钮时,显示两边空间
- if(count == 1) {
- layout.findViewById(R.id.leftSpacer)
- .setVisibility(View.INVISIBLE);
- layout.findViewById(R.id.rightSpacer).setVisibility(View.INVISIBLE);
- }
- //设置提示消息
- if(!TextUtils.isEmpty(mMessage)) {
- ((TextView)layout.findViewById(R.id.message))
- .setText(mMessage);
- } else {
- ((LinearLayout) layout.findViewById(R.id.contentPanel))
- .setVisibility(View.GONE);
- }
- //设置提示内容布局
- if(mView != null) {
- final FrameLayout customPanel = (FrameLayout) layout
- .findViewById(R.id.customPanel);
- if(mViewSpacingSpecified) {
- customPanel.setPadding(mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight, mViewSpacingBottom);
- }
- customPanel.addView(mView);
- } else {
- ((FrameLayout) layout.findViewById(R.id.customPanel))
- .setVisibility(View.GONE);
- }
- dialog.setContentView(layout);
- return dialog;
- }
- public CustomDialog show() {
- CustomDialog dialog = create();
- dialog.show();
- return dialog;
- }
- private boolean setButton(View layout, CharSequence mPositiveButtonText, int id, final Dialog dialog, final OnClickListener listener) {
- if(!TextUtils.isEmpty(mPositiveButtonText)) {
- final Button button = (Button) layout.findViewById(id);
- button.setText(mPositiveButtonText);
- if(listener != null) {
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- listener.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
- }
- });
- } else {
- //默认事件为关闭对话框
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- dialog.cancel();
- dialog.dismiss();
- }
- });
- }
- return true;
- } else {
- layout.findViewById(id).setVisibility(View.GONE);
- return false;
- }
- }
- }
- }
关于主界面的业务逻辑具体实现和需要注意的地方,小巫已经说完了。其实最重要的是要写好服务类,下一篇播放将会给童鞋们介绍服务类的实现。最后感谢大家的关注。