由于最近自己在做一个音乐APP,在播放音乐时,想实现网易云那种带光盘和指针的界面,所以在慕课上找了学习教程,以下是我的学习过程,先放出网易云播放界面
1.隐藏statusBar
//隐藏statusBar,第一个参数是新窗口的标志位,第二个参数时要修改的标志位
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
2.布局文件(暂时添加返回按钮、背景、歌名和作者)
3.设置背景模糊
使用GlideTransTransformations包
(1) 引入包(app/build.gradle)
//如果没有引入Glide的包也要记得引入,因为两者是配合使用的
implementation 'com.github.bumptech.glide:glide:4.9.0'
//glide-transformation
implementation 'jp.wasabeef:glide-transformations:4.0.1'
(2) 加载图片,这里设置效果为模糊,具体的其他效果可以参考github中该包的详细说明,地址是https://github.com/wasabeef/glide-transformations
(3) 操作代码,load中的可以是网络图片url,也可以是模块中的文件
iv_bg = this.findViewById(R.id.iv_bg);
//glide-transformation
Glide.with(this)
.load(R.mipmap.album1)
.apply(RequestOptions.bitmapTransform(new BlurTransformation(25,10)))
.into(iv_bg);
(4) 效果
4.自定义带指针光盘的View(如果不懂自定义View的详细过程,可以看下我前面的一篇自定义View的文章)
(1) 指针
(2) 光盘
上面的xml,是这个自定义view的一个布局,具体的自定义view的代码如下
package com.musicplaer.eminemmusic.views;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import com.bumptech.glide.Glide;
import com.musicplaer.eminemmusic.R;
import de.hdodenhof.circleimageview.CircleImageView;
public class PlayMusicView extends FrameLayout {
private Context mContext;
private View mView;
private CircleImageView cv_icon;
public PlayMusicView(@NonNull Context context) {
super(context);
init(context);
}
public PlayMusicView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public PlayMusicView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public PlayMusicView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context){
this.mContext = context;
mView = LayoutInflater.from(mContext).inflate(R.layout.play_music,this,false);
cv_icon = mView.findViewById(R.id.cv_icon);
addView(mView);
}
/**
* 设置光盘中显示的音乐封面图片
*/
public void setMusicIcon(String icon){
Glide.with(mContext)
.load(icon)
.into(cv_icon);
}
public void setMusicIcon(int album1) {
cv_icon.setImageResource(album1);
}
}
然后将该自定义的view添加到原先的布局文件中,在Activity中调用setMusicIcon来设置图片,效果如下:
5.设置动画(@integers/xxxx是在app/src/main/res/values/integers.xml中自定义的变量)
(1) 光盘转动动画
(2) 指针指向光盘动画
(3) 指针离开光盘动画
(4) 在自定义View中设置动画,且在播放Activity中还要调用playMusic()的方法,使得一开始就有动画效果
package com.musicplaer.eminemmusic.views;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.musicplaer.eminemmusic.R;
import de.hdodenhof.circleimageview.CircleImageView;
public class PlayMusicView extends FrameLayout {
private Context mContext;
private View mView;
private CircleImageView cv_icon;
private Animation mPlayMusicAnim,mPlayNeedleAnim,mStopNeedleAnim;
private FrameLayout fl_disc;
private ImageView iv_needle,iv_play;
private boolean isPlay;
public PlayMusicView(@NonNull Context context) {
super(context);
init(context);
}
public PlayMusicView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public PlayMusicView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public PlayMusicView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context){
this.mContext = context;
mView = LayoutInflater.from(mContext).inflate(R.layout.play_music,this,false);
cv_icon = mView.findViewById(R.id.cv_icon);
iv_play = mView.findViewById(R.id.iv_play);
fl_disc = mView.findViewById(R.id.fl_fisc);
iv_needle = mView.findViewById(R.id.iv_needle);
//设置监听事件
fl_disc.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
trigger();
}
});
/**
* 定义所需要执行的动画:
* 1,光盘转动的动画
* 2.指针指向光盘的动画
* 3.指针离开光盘的动画
* 使用startAnimation
*/
//初始化
mPlayMusicAnim = AnimationUtils.loadAnimation(mContext,R.anim.play_music_animation);
mPlayNeedleAnim = AnimationUtils.loadAnimation(mContext,R.anim.play_needle_anim);
mStopNeedleAnim = AnimationUtils.loadAnimation(mContext,R.anim.stao_needle_anim);
addView(mView);
}
/**
* 设置光盘中显示的音乐封面图片
*/
public void setMusicIcon(String icon){
Glide.with(mContext)
.load(icon)
.into(cv_icon);
}
public void setMusicIcon(int album1) {
cv_icon.setImageResource(album1);
}
/**
* 播放音乐:设置动画执行效果
*/
public void playMusic(){
isPlay = true;
fl_disc.startAnimation(mPlayMusicAnim);
iv_needle.startAnimation(mPlayNeedleAnim);
}
/**
* 停止音乐:设置动画执行效果
*/
private void stopMusic(){
isPlay = false;
fl_disc.clearAnimation();
iv_needle.startAnimation(mStopNeedleAnim);
//显示按钮
iv_play.setVisibility(View.VISIBLE);
}
/**
* 切换播放状态
*/
private void trigger(){
if(isPlay){
stopMusic();
}else {
playMusic();
}
}
}