android:layout_width=\ android:layout_height=\ android:id=\ android:layout_gravity=\ android:src=\ />
为动画做闪屏动作,这样可以使这个动画在2秒钟后自动跳转到下一个Acitvity界面上,设计代码如下。
ImageView _ivSplash=(ImageView)findViewById(R.id.ivSplash);
Animation _anim=AnimationUtils.loadAnimation(this, android.R.anim.fade_in); _ivSplash.setAnimation(_anim); 5.2.2 布局的设计
要为这个Activity布局,我选用的LinearLayout做布局的,在一个大的LinearLayout下我有布置了四个小的LinearLayout,第一个小的LinearLayout下布置了一个TableLayout,两个TextView,第二个小的LinearLayout下布置了FrameLayout和一个ImageView,第三个小的LinearLayout下布置了RelativeLayout和一个seekbar,在第四个LinearLayout下布置了五个Imagebutton,布局的结构和每个空间的作用如下。
- 27 -
基于Android平台的手机音乐播放器的设计与实现
5.2.3 播放器音轨SeekBar的设计
不管是从界面外观还是从功能上,系统自带的SeekBar往往不能满足用户的需要。所以我在这里自定义了一个音轨SeekBar,在play_rack.Xml配置文件中,SeekBar的代码及效果图如下:
android:layout_marginLeft=\android:layout_marginRight=\android:id=\ android:layout_width=\android:layout_height=\ android:progressDrawable=\android:thumb=\ 图5-11 自定义SeekBar - 28 - 下图为系统默认的SeekBar。 图5-12 系统默认的Seekbar 播放器最重要的一部分就是音轨与歌曲进度同步的实现。音轨设置了两个TextView用来显示当前歌曲播放的进度时间和歌曲的长度5-13。 图5-13 音乐播放同步 音轨对象SeekBar在歌曲刚开始播放的时候调用方法SeekBar.setMax(),参数传入歌曲的长度。SeekBar.setProgress(1)设置游标的起始进度为1。然后程序运行如下代码: // 设置SeekBar的监听事件 sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { // 当停止拖动时调用的方法 public void onStopTrackingTouch(SeekBar seekBar) {} public void onStartTrackingTouch(SeekBar seekBar) {} // 当SeekBar拖动时会执行此方法 public void onProgressChanged(SeekBar seekBar, int prog, } boolean fromUser) {// fromUser参数意思是判断拖动是否是用户用手拖动的 if (fromUser == true && Math.abs(prog - progress) >= 5) { progress = prog; Intent i = new Intent(Const.MUSIC_CONTROL); } int cmd = Const.CMD_SEEK;// 发送拖动的命令 i.putExtra(\ i.putExtra(\讲拖动的进度传进Service sendBroadcast(i); sb.setProgress(progress); }); Android的线程的开始是通过Handler类来进行的,Handler类是线程与线程之间通信的桥梁,实现Runnable接口会实现里面的run方法,当线程开始的时候,Runnable中的run - 29 - 基于Android平台的手机音乐播放器的设计与实现 方法会向Handler发一个Message消息,这样,Handler类就可以接收到run方法发送过来的不同的消息进行不同的代码处理。这样就达到了各线程之间的通信。要启动一个线程调用Handler的方法postDelayed(Runnable,1000)表示线程睡眠时间是1000ms 。 以上代码意思是让播放歌曲的线程每隔1000ms,即每1秒对音轨的TextView重新设置时间且让进度条前进1秒的进度。对音轨进行刷新。这样就实现了歌词同步功能SeekBar有一个监听器,该监听器的作用是一直保持着对进度条的监听,当我们用鼠标向SeekBar的各位置进行点击时,它会自动监听其位置,进行相应的位置显示。这也是进度条上的游标会不停的移动和歌曲时间会不停的变动的原因。 5.2.4 基本功能的设计 各按钮水平放置,用的是布局中的线性布局LinearLayout,用方法setOrientation,设置成horizontal,将其设置为水平。LinearLayout中依次放置播放、暂停、停止、上一曲、下一曲按钮属性。 android的媒体播放原理:android源程序已经为我们封装好了一个接口类,叫MediaPlayer。该接口在执行行需要一个数据源,通过如下四个步骤: 第一步:MediaPlayer.reset();复位操作,为以后的媒体准备播放作准备。 path);参数需要传一个路径,该接口类在收到路径后将其转化为数据源。 第三步;准备播放数据源,调用方法 MediaPlayer.Prepare(); 用MediaPlayer.Stop()方法让其停止或MediaPlayer.Start();让其启动; 歌曲数据源的获得:要获得数据源,需要我们提供给接口类一个歌曲存放路径,而这个路径已经被事先放到数据库里了,我们只需要进行数据库进行操作。将里面的路径取出。这里将调用PlayRackActivity的一个方法query();代码算法如下: private ContentResolver mresolver; public LocalMusicUtils(Context context){ mresolver=context.getContentResolver(); } /**查询媒体库中时长大于30秒的音频 * @return */ public ArrayList String[] projection={\ Cursor cursor=mresolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, - 30 - 第二步:传入歌曲数据源,这里也是一个数据流MediaPlayer.setDataSource(String 第四步:MediaPlayer.Start();播放数据源,该数据源播放后,不再与程序 有关,需要 projection, \ ArrayList if (cursor!=null&&cursor.getCount()>0) { musics=new ArrayList cursor.close(); } return musics; 方法getContentResolver是包android.content.ContextWrapper里面的方法,它会自动的调用ContentProvider中的关联数据库,我们需用这个方法就可以操作数据库。数据库操作需要一个Uri 。Uri类似一个网络连接的Url。Uri是数据库唯一的标识,不同的Uri可以操作不同的数据库表。在查询数据库时需要传入一个当前播放的歌曲名字,通过歌曲名字来查询歌曲的路径。这样我们就得到了歌曲的所有信息了。 歌曲获取以后就可以对其控制(播放、暂停、上一曲、下一曲等操作)。 1. 播放/暂停 //播放与暂停功能实现 playPauseBtn.setOnClickListener(new OnClickListener() { public void onClick(View v) { int cmd = 0; Intent i = new Intent(Const.MUSIC_CONTROL); // 判断当前的状态值是什么状态 如果是播放状态 if (status == Const.STATUS_PLAYING) { } i.putExtra(\将命令广播出去 Log.i(\当前播放的状态\ - 31 - cmd = Const.CMD_PAUSE;// 发送暂停的命令 cmd = Const.CMD_START;// 发送播放的命令 cmd = Const.CMD_RESUME;// 继续播放的命令 } else if (status == Const.STATUS_STOPPED) { } else {