Android应用开发--MP3音乐播放器代码实现(二)
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过滤器的定义,动作的添加,注册广播接收器:
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; } } } }
关于主界面的业务逻辑具体实现和需要注意的地方,小巫已经说完了。其实最重要的是要写好服务类,下一篇播放将会给童鞋们介绍服务类的实现。最后感谢大家的关注。