Android期末作业,临时抱佛脚(手动滑稽
分享下音乐播放的源码吧。(只能播放内嵌音乐
注意事项
接下来是音乐播放器步骤:
- 在工程文件夹“ ..\app\src\main\res ”下,新建一个文件夹“raw”,然后把音乐放进去,命名为“ lucky.mp3 ” ;
- 在工程文件夹 “ ..\app\src\main\res\drawable ”下,放入你喜欢的图片作为播放器背景,命名为“bg1”;以及4个控制按钮(尺寸:34*30),分别命名为 “exit”,“stop”,“play”,“pause”,和菜单按钮(尺寸:45*42) “menu” ;
- 在工程文件夹 “ ..\app\src\main\res\mipmap-hdpi ”下,放入歌手海报,命名为“img”。由于要制作旋转效果,故推荐选择圆形的图片;
- 在工程文件夹“ ..\app\src\main\res ”下,新建一个文件夹“anim”,在里面新建3个xml文档,命名为“anim.xml”,“bigalpha.xml”,“smallalpha.xml”;
- “ AndroidManifest.xml ”里,在</activity>后加一句<service android:name=".MusicService" android:enabled="true" android:exported="true" />
- 在工程文件夹“ ..\app\src\main\res\values ”下,新建xml文档,命名为“dimens.xml”;找到styles.xml文件,把
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
改为
<style name="AppTheme" parent="Base.Theme.AppCompat.Light.DarkActionBar">
预览图
源码
anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http:///apk/res/android">
<rotate
android:duration="300"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"/>
</set>
bigalpha.xml
<?xml version="1.0" encoding="utf-8"?>
<!--android:fillAfter="true"得加,取动画结束后的最后一帧-->
<set xmlns:android="http:///apk/res/android"
android:fillAfter="true">
<alpha
android:duration="200"
android:fromAlpha="1"
android:toAlpha="0"/>
<scale
android:duration="200"
android:fromXScale="1"
android:fromYScale="1"
android:toXScale="3"
android:toYScale="3"
android:pivotX="50%"
android:pivotY="50%" />
</set>
smallalpha.xml
<?xml version="1.0" encoding="utf-8"?>
<!--android:fillAfter="true"得加,取动画结束后的最后一帧-->
<set xmlns:android="http:///apk/res/android"
android:fillAfter="true">
<alpha
android:duration="200"
android:fromAlpha="1"
android:toAlpha="0"/>
<scale
android:duration="200"
android:fromXScale="1"
android:fromYScale="1"
android:toXScale="0"
android:toYScale="0"
android:pivotX="50%"
android:pivotY="50%" />
</set>
dimens.xml
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
MainActivity.java
1package com.example.slyarh.text;
import android.animation.ObjectAnimator;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import .AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import java.text.SimpleDateFormat;
public class MainActivity extends AppCompatActivity {
private TextView musicStatus, musicTime, musicTotal;
private SeekBar seekBar;
private ImageView btnPlayOrPause, btnStop, btnQuit;
private SimpleDateFormat time = new SimpleDateFormat("mm:ss");
private boolean tag1 = false;
private boolean tag2 = false;
private MusicService musicService;
private ArcDemo mArc;
// 在Activity中调用 bindService 保持与 Service 的通信
private void bindServiceConnection() {
Intent intent = new Intent(MainActivity.this, MusicService.class);
startService(intent);
bindService(intent, serviceConnection, this.BIND_AUTO_CREATE);
}
// 回调onServiceConnected 函数,通过IBinder 获取 Service对象,实现Activity与 Service的绑定
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
musicService = ((MusicService.MyBinder) (service)).getService();
Log.i("musicService", musicService + "");
musicTotal.setText(time.format(musicService.mediaPlayer.getDuration()));
}
@Override
public void onServiceDisconnected(ComponentName name) {
musicService = null;
}
};
// 通过 Handler 更新 UI 上的组件状态
public Handler handler = new Handler();
public Runnable runnable = new Runnable() {
@Override
public void run() {
musicTime.setText(time.format(musicService.mediaPlayer.getCurrentPosition()));
seekBar.setProgress(musicService.mediaPlayer.getCurrentPosition());
seekBar.setMax(musicService.mediaPlayer.getDuration());
musicTotal.setText(time.format(musicService.mediaPlayer.getDuration()));
handler.postDelayed(runnable, 200);
}
};
private void findViewById() {
musicTime = (TextView) findViewById(.MusicTime);
musicTotal = (TextView) findViewById(.MusicTotal);
seekBar = (SeekBar) findViewById(.MusicSeekBar);
btnPlayOrPause = (ImageView) findViewById(.BtnPlayorPause);
btnStop = (ImageView) findViewById(.BtnStop);
btnQuit = (ImageView) findViewById(.BtnQuit);
musicStatus = (TextView) findViewById(.MusicStatus);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById();
bindServiceConnection();
//myListener();
ImageView imageView = (ImageView) findViewById(.Image);
final ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360.0f);
animator.setDuration(10000);
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(-1);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser == true) {
musicService.mediaPlayer.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mArc = (ArcDemo) findViewById(.view_arc);
mArc.setOnSubItemClickListener(new ArcDemo.onSubItemClickListener() {
@Override
public void onItemClick(View view, int position) {
if(position==5){
if (musicService.mediaPlayer != null) {
seekBar.setProgress(musicService.mediaPlayer.getCurrentPosition());
seekBar.setMax(musicService.mediaPlayer.getDuration());
}
// 由tag的变换来控制事件的调用
if (musicService.tag != true) {
//btnPlayOrPause.setText("PAUSE");
musicStatus.setText("正在播放..");
musicService.playOrPause();
musicService.tag = true;
btnPlayOrPause.setImageDrawable(getResources().getDrawable(R.drawable.pause));
if (tag1 == false) {
animator.start();
tag1 = true;
}
else {
animator.resume();
}
}
else {
//btnPlayOrPause.setText("PLAY");
musicStatus.setText("暂停播放..");
musicService.playOrPause();
animator.pause();
btnPlayOrPause.setImageDrawable(getResources().getDrawable(R.drawable.play));
musicService.tag = false;
}
if (tag2 == false) {
handler.post(runnable);
tag2 = true;
}
}
else if(position==6){
musicStatus.setText("停止播放..");
// btnPlayOrPause.setText("PLAY");
musicService.stop();
btnPlayOrPause.setImageDrawable(getResources().getDrawable(R.drawable.play));
animator.pause();
musicService.tag = false;
}
else if(position==7) exit();
}
});
}
// 停止服务时,必须解除绑定,写入btnQuit按钮中
public void exit(){
handler.removeCallbacks(runnable);
unbindService(serviceConnection);
Intent intent = new Intent(MainActivity.this, MusicService.class);
stopService(intent);
try {
MainActivity.this.finish();
} catch (Exception e) {}
}
// 获取并设置返回键的点击事件
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(false);
return true;
}
return super.onKeyDown(keyCode, event);
}
}
activity_main.xml
1<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http:///apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="wrap_content"
android:background="@drawable/bg1"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#00000000"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp">
<ImageView
android:id="@+id/Image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@mipmap/img" />
<!--显示歌曲状态-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="@+id/MusicStatus"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:gravity="center_horizontal">
<!--显示当前进度-->
<TextView
android:id="@+id/MusicTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00" />
<SeekBar
android:layout_width="230sp"
android:layout_height="wrap_content"
android:id="@+id/MusicSeekBar"
android:layout_weight="1"
android:max="100"
android:layout_toRightOf="@+id/MusicTime"/>
<!--显示总进度-->
<TextView
android:id="@+id/MusicTotal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00"
android:layout_toRightOf="@+id/MusicSeekBar"/>
</RelativeLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:background="#00000000"
android:layout_height="match_parent">
<com.example.slyarh.text.ArcDemo
android:background="#00000000"
android:id="@+id/view_arc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true">
<RelativeLayout
android:id="@+id/main_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/menu">
</RelativeLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/BtnPlayorPause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/play" />
<ImageView
android:id="@+id/BtnStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/stop" />
<ImageView
android:id="@+id/BtnQuit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/exit" />
</com.example.slyarh.text.ArcDemo>
</RelativeLayout>
</LinearLayout>
</FrameLayout>
MusicService.java
1package com.example.slyarh.text;
import .Service;
import android.content.Intent;
import .MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
public class MusicService extends Service {
public MediaPlayer mediaPlayer=null;
public boolean tag = false;
public MusicService() {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.reset();
mediaPlayer = MediaPlayer.create(this, R.raw.lucky);
mediaPlayer.seekTo(0);
mediaPlayer.setLooping(true);
stop();
} catch (Exception e) {
e.printStackTrace();
}
}
// 通过 Binder 来保持 Activity 和 Service 的通信
public MyBinder binder = new MyBinder();
public class MyBinder extends Binder {
MusicService getService() {
return MusicService.this;
}
}
public void playOrPause() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.setLooping(true);
mediaPlayer.pause();
} else {
mediaPlayer.setLooping(true);
mediaPlayer.start();
}
}
public void stop() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.setLooping(true);
try {
mediaPlayer.reset();
mediaPlayer = MediaPlayer.create(this, R.raw.lucky);
mediaPlayer.seekTo(0);
mediaPlayer.setLooping(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
}
ArcDemo.java
package com.example.slyarh.text;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import android.view.animation.TranslateAnimation;
public class ArcDemo extends ViewGroup {
private View mButton;
private BStatus mBStatus = BStatus.STATUS_CLOSE;
private onSubItemClickListener onListener;
public enum BStatus {
STATUS_OPEN, STATUS_CLOSE
}
//子菜单点击接口
public interface onSubItemClickListener {
void onItemClick(View view, int position);
}
public void setOnSubItemClickListener(onSubItemClickListener mListener) {
this.onListener = mListener;
}
public ArcDemo(Context context) {
super(context);
// this(context, null);
}
public ArcDemo(Context context, AttributeSet attrs) {
super(context, attrs);
// this(context, attrs, 0);
}
public ArcDemo(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
//添加布局,就是所要显示的控件View
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed) {
//主菜单按钮
onMainButton();
//子菜单按钮
onSubItemButton();
}
}
//获取主菜单按钮
private void onMainButton() {
mButton = getChildAt(0);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//主菜单动画
Animation rotateAnim = AnimationUtils.loadAnimation(getContext(), R.anim.anim);
mButton.startAnimation(rotateAnim);
//子菜单动画
subItemAnim();
}
});
int l, t, r = 0, b = 0;
int mWidth = mButton.getMeasuredWidth();
int mHeight = mButton.getMeasuredHeight();
l = getMeasuredWidth() - mWidth;
t = getMeasuredHeight() - mHeight;
mButton.layout(l, t, getMeasuredWidth(), getMeasuredHeight());
}
//获取子菜单按钮
private void onSubItemButton() {
int count = getChildCount();
for (int i = 0; i < count - 1; i++) {
View childView = getChildAt(i + 1);
//开始时不呈现子菜单
childView.setVisibility(View.GONE);
int radius = 350;
int cl, ct, cr, cb;
cr = (int) (radius * Math.sin(Math.PI / 2 / (count - 2) * i));
cb = (int) (radius * Math.cos(Math.PI / 2 / (count - 2) * i));
int cWidth = childView.getMeasuredWidth();
int cHeight = childView.getMeasuredHeight();
cl = getMeasuredWidth() - cWidth - cr;
ct = getMeasuredHeight() - cHeight - cb;
//layout(l,t,r,b);前两参数决定位置,后两参数决定大小
//参数(1,t)为View控件的左上角坐标
// (r-l,b-t)为View控件大小,r-l为控件宽度,b-t为控件高度
childView.layout(cl, ct, getMeasuredWidth() - cr, getMeasuredHeight() - cb);
}
}
//子菜单散开回笼动画
public void subItemAnim() {
int count = getChildCount();
for (int i = 0; i < count - 1; i++) {
final View cView = getChildAt(i + 1);
//点击主菜单后,子菜单就立刻呈现,否则后面的动画无法完成
cView.setVisibility(VISIBLE);
int radius = 350;
int l, t, r, d;
r = (int) (radius * Math.sin(Math.PI / 2 / (count - 2) * i));
d = (int) (radius * Math.cos(Math.PI / 2 / (count - 2) * i));
// int cWidth = cView.getMeasuredWidth();
// int cHeight = cView.getMeasuredHeight();
//
// l = getMeasuredWidth() - cWidth - r;
// t = getMeasuredHeight() - cHeight - d;
AnimationSet set = new AnimationSet(true);
Animation tranAnim = null;
if (mBStatus == BStatus.STATUS_CLOSE) {
//散开动画
tranAnim = new TranslateAnimation(r, 0, d, 0);
cView.setClickable(true);
cView.setFocusable(true);
} else {
//回笼动画
tranAnim = new TranslateAnimation(0, r, 0, d);
cView.setClickable(false);
cView.setFocusable(false);
}
tranAnim.setDuration(300);
// tranAnim.setFillAfter(true); //让最后一帧的动画不消失
tranAnim.setStartOffset(100 * i / count);
tranAnim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (mBStatus == BStatus.STATUS_CLOSE) {
cView.setVisibility(GONE);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
Animation rotateAnim = new RotateAnimation(
0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnim.setDuration(300);
// rotateAnim.setFillAfter(false);
set.addAnimation(rotateAnim);
set.addAnimation(tranAnim);
cView.startAnimation(set);
//散开后子菜单的点击监听事件
final int pos = i + 1;
cView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (onListener != null) {
onListener.onItemClick(cView, pos);
}
//散开后点击子菜单动画
subItemClickAnim(pos - 1);
changStatus();
}
});
}
changStatus();
}
//监听子菜单状态改变
private void changStatus() {
mBStatus = (mBStatus == BStatus.STATUS_CLOSE ? BStatus.STATUS_OPEN : BStatus.STATUS_CLOSE);
}
//散开后点击子菜单动画
private void subItemClickAnim(int pos) {
int count = getChildCount();
for (int i = 0;i<count-1;i++) {
View cView = getChildAt(i+1);
if(i == pos) {
//变大,变透明
cView.startAnimation(toBig());
}
else {
//变小,变透明
cView.startAnimation(toSmall());
}
cView.setClickable(false);
cView.setFocusable(false);
}
}
//变大,变透明
private Animation toBig(){
Animation big = AnimationUtils.loadAnimation(getContext(),R.anim.bigalpha);
return big;
}
//变小,变透明
private Animation toSmall(){
Animation small = AnimationUtils.loadAnimation(getContext(),R.anim.smallalpha);
return small;
}
//给ListView调用
public boolean isOpen() {
return mBStatus == BStatus.STATUS_OPEN;
}
}
✎﹏﹏₯㎕《晴天》从出生那年就飘着...﹍﹍﹍﹍﹍﹍