實現一個簡單的播放器,要求功能有:
1. 播放、暫停,停止,退出功能;
2. 后台播放功能;
3. 進度條顯示播放進度、拖動進度條改變進度功能;
4. 播放時圖片旋轉,顯示當前播放時間功能;
效果圖:


圖片旋轉:
圖片布局:主要是要實現圖片居中,還有就是id

定義rotate旋轉效果:在res/anim文件夾下新建tip.xml文件。
下面的代碼表示從0到359度開始循環旋轉,0-359(若設置成360在停止時會出現停頓現象)度旋轉所用時間為10000ms,旋轉中心距離view的左頂點為50%距離,距離view的上邊緣為50%距離,即正中心.

android:fromDegrees 起始的角度度數
android:toDegrees 結束的角度度數,負數表示逆時針,正數表示順時針。如10圈則比android:fromDegrees大3600即可
android:pivotX 旋轉中心的X坐標
android:pivotY 旋轉中心的Y坐標
浮點數或是百分比。浮點數表示相對於Object的左邊緣,如5; 百分比表示相對於Object的左邊緣,如5%; 另一種百分比表示相對於父容器的左邊緣,如5%p; 一般設置為50%表示在Object中心
android:duration 表示從android:fromDegrees轉動到android:toDegrees所花費的時間,單位為毫秒。可以用來計算速度。
android:interpolator表示變化率,但不是運行速度。一個插補屬性,可以將動畫效果設置為加速,減速,反復,反彈等。默認為開始和結束慢中間快,
android:startOffset 在調用start函數之后等待開始運行的時間,單位為毫秒,若為10,表示10ms后開始運行
android:repeatCount 重復的次數,默認為0,必須是int,可以為-1表示不停止
android:repeatMode 重復的模式,默認為restart,即重頭開始重新運行,可以為reverse即從結束開始向前重新運行。在android:repeatCount大於0或為infinite時生效
android:detachWallpaper 表示是否在壁紙上運行
android:zAdjustment 表示被animated的內容在運行時在z軸上的位置,默認為normal。
normal保持內容當前的z軸順序
top運行時在最頂層顯示
bottom運行時在最底層顯示
運行速度為運行時間(android:duration)除以運行角度差(android:toDegrees-android:fromDegrees)

setInterpolator表示設置旋轉速率。LinearInterpolator為勻速效果,Accelerateinterpolator為加速效果、DecelerateInterpolator為減速效果
AnimationUtils.loadAnimation(this,R.anim.tip)就是加載一個動態效果,tip就是前面定義的xml。
開始旋轉:imageview.startAnimation(operatingAnim)
停止旋轉:imageview.clearAnimation();
代碼:
package com.example.hp.lab6; import android.app.Activity; import android.content.ComponentName; import android.content.DialogInterface; import android.content.Intent; import android.content.ServiceConnection; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.drawable.BitmapDrawable; import android.media.Image; import android.os.Handler; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.LinearInterpolator; import android.widget.Button; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.TextView; import java.text.SimpleDateFormat; public class MainActivity extends Activity implements OnClickListener { private Button play_pauseBtn,stopBtn,quitBtn; private MusicService musicService; private ImageView imageview; private TextView state, playing_time,max_time; private SeekBar seekbar; private SimpleDateFormat time = new SimpleDateFormat("mm:ss"); //Bitmap bmp = BitmapFactory.decodeResource(this.getResources(),R.mipmap.image); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);//綁定布局 findView();//findIdByView,找到個個控件 bindButton();//按鈕綁定監聽器。 musicService=new MusicService();//新建一個MusicService后台服務 connection();//綁定后台服務 max_time.setText(time.format(musicService.mediaPlayer.getDuration()));//設置max_time這個textview的內容是歌曲的時間長度 Animation operatingAnim = AnimationUtils.loadAnimation(this, R.anim.tip); LinearInterpolator lin = new LinearInterpolator();//LinearInterpolator為勻速效果 operatingAnim.setInterpolator(lin);//setInterpolator表示設置旋轉速率。 imageview.startAnimation(operatingAnim);//開始旋轉 } private void findView(){ /** 通過id獲得各種組件 */ play_pauseBtn=(Button) findViewById(R.id.play_pause);//開始/暫停按鈕 stopBtn=(Button) findViewById(R.id.stop);//停止按鈕 quitBtn=(Button) findViewById(R.id.quit);//退出按鈕 state=(TextView) findViewById(R.id.state);//seekbar上面表示狀態的文字textview playing_time=(TextView) findViewById(R.id.playing_time);//seekbar左邊現在播放的時間 max_time=(TextView) findViewById(R.id.song_time);//播放的這首歌曲的時長 seekbar=(SeekBar) findViewById(R.id.seekbar);//seekbar imageview=(ImageView ) findViewById(R.id.imageview);//旋轉的圖片 } private void bindButton(){ /** 為按鈕添加監聽 ,三個按鈕的監聽器都是MainActivity*/ play_pauseBtn.setOnClickListener(this); stopBtn.setOnClickListener(this); quitBtn.setOnClickListener(this); } private ServiceConnection sc=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { musicService=((MusicService.MyBinder)service).getService(); } @Override public void onServiceDisconnected(ComponentName name) { musicService=null; } }; Handler mHandler=new Handler(); //創建Handler對象 //要用handler來處理多線程可以使用runnable接口,這里先定義該接口,線程中運行該接口的run函數 Runnable mRunnable=new Runnable() { //新建一個Runnable接口 @Override public void run() {//將要執行的操作寫在線程對象的run方法當中 //Matrix mtx = new Matrix(); //mtx.postRotate(1); // Rotating Bitmap //Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mtx, true); //BitmapDrawable bmd = new BitmapDrawable(rotatedBMP); //imageview.setImageDrawable(bmd); //設置seekbar左邊的playing_time textview為當前歌曲播放到的時間 playing_time.setText(time.format(musicService.mediaPlayer.getCurrentPosition())); //設置seekbar為當前歌曲播放到的時間 seekbar.setProgress(musicService.mediaPlayer.getCurrentPosition()); //seekbar條拖動監聽事件 seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override//seekbar發生改變時 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if(fromUser){ musicService.mediaPlayer.seekTo(seekBar.getProgress()); }//根據seekbar拖動到的位置改變設置歌曲播放到的進度 } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); mHandler.postDelayed(mRunnable,100);//100ms執行一次tun()函數 } }; @Override public void onClick(View v){ switch (v.getId()){ case R.id.play_pause://點擊play_pause按鈕事件 musicService.playORpuase();//調用musicService中的playORpause函數,暫停或開始音樂播放 if(musicService.mediaPlayer.isPlaying()){ state.setText("Playing");//當音樂在播放時,我們設置state的內容為Playing play_pauseBtn.setText("PAUSE");//設置button的內容為Puase //Animation operatingAnim = AnimationUtils.loadAnimation(this, R.anim.tip); //LinearInterpolator lin = new LinearInterpolator();//LinearInterpolator為勻速效果 //operatingAnim.setInterpolator(lin);//setInterpolator表示設置旋轉速率。 // imageview.startAnimation(operatingAnim);//開始旋轉 } else{ state.setText("Paused");//當音樂停止時,設置state內容為Paused play_pauseBtn.setText("PLAY");//button內容為Play } break; case R.id.stop://點擊暫停 musicService.stop();//關閉音樂 play_pauseBtn.setText("PLAY");//設置開始和暫停按鈕的內容為Play state.setText("Stop");//設置state為Stop //imageview.clearAnimation(); break; case R.id.quit://點擊退出 mHandler.removeCallbacks(mRunnable);//回調mRunnable接口 unbindService(sc);//解除后台服務的綁定 try{ MainActivity.this.finish();//結束當前的時間 System.exit(0); } catch (Exception e){ e.printStackTrace(); } break; } } private void connection(){ //啟動指定的Service Intent intent=new Intent(this ,MusicService.class); bindService(intent,sc,BIND_AUTO_CREATE);//綁定服務 } @Override protected void onResume() { seekbar.setProgress(musicService.mediaPlayer.getCurrentPosition()); seekbar.setMax(musicService.mediaPlayer.getDuration()); mHandler.post(mRunnable);//通過Handler啟動Runnable super.onResume(); } }
package com.example.hp.lab6; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.os.Binder; import android.os.IBinder; public class MusicService extends Service { public MediaPlayer mediaPlayer=new MediaPlayer(); private final IBinder binder=new MyBinder(); public class MyBinder extends Binder { MusicService getService(){ return MusicService.this;//找到后台服務的指針,返回后台服務實例 } } public MusicService() { try{ mediaPlayer.setDataSource("/data/K.Will-Melt.mp3");//綁定播放的歌曲 mediaPlayer.prepare();//進入就緒狀態 mediaPlayer.setLooping(true);//設置循環播放 } catch (Exception e){ e.printStackTrace(); } } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. //throw new UnsupportedOperationException("Not yet implemented"); return binder; } @Override public void onCreate(){ super.onCreate(); } @Override public void onDestroy(){ super.onDestroy(); if(mediaPlayer!=null){ mediaPlayer.stop();//停止歌曲播放 mediaPlayer.release();//釋放mediaPlayer資源 } } public void playORpuase(){ if(mediaPlayer.isPlaying()){ mediaPlayer.pause();//暫停 } else{ mediaPlayer.start();//開始 } } public void stop(){ if(mediaPlayer!=null){ mediaPlayer.stop();//停止 try{ mediaPlayer.prepare();//就緒 mediaPlayer.seekTo(0);//設置歌曲回到最開始 } catch (Exception e){ e.printStackTrace(); } } } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.hp.lab6.MainActivity" > <ImageView android:id="@+id/imageview" android:layout_gravity="center" android:layout_width="300sp" android:layout_height="300sp" android:src="@drawable/image" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="vertical"> <TextView android:id="@+id/state" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/margin_top" android:textSize="@dimen/textsize1" android:text="" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_marginTop="@dimen/margin_top" android:gravity="center_horizontal"> <TextView android:id="@+id/playing_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="00:00"/> <SeekBar android:id="@+id/seekbar" android:layout_width="280sp" android:layout_height="wrap_content" /> <TextView android:id="@+id/song_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="04:00"/> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="@dimen/margin_top" android:layout_gravity="center_horizontal" android:orientation="horizontal"> <Button android:id="@+id/play_pause" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="PLAY" /> <Button android:id="@+id/stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/textsize1" android:text="STOP" /> <Button android:id="@+id/quit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/textsize1" android:text="QUIT" /> </LinearLayout> </LinearLayout>
