由于最近自己在做一个音乐APP,在播放音乐时,想实现网易云那种带光盘和指针的界面,所以在慕课上找了学习教程,以下是我的学习过程,先放出网易云播放界面
1.隐藏statusBar
//隐藏statusBar,第一个参数是新窗口的标志位,第二个参数时要修改的标志位
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
2.布局文件(暂时添加返回按钮、背景、歌名和作者)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.PlayMusicActivity">
<ImageView
android:id="@+id/iv_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/album1"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/no_bar_back"
android:layout_margin="@dimen/marginSize"
android:onClick="onBackClick"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_marginTop="480dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="音乐名称"
android:textColor="@android:color/white"
android:textSize="@dimen/textSize"
android:textStyle="bold"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/marginSize"
android:textSize="@dimen/infoSize"
android:text="作者"
android:textColor="@android:color/white"/>
</LinearLayout>
</FrameLayout>
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 version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--光盘-->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/discTopSize">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/disc" />
<!--CircleImageView-->
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/cv_icon"
android:layout_width="@dimen/playMusicIconSize"
android:layout_height="@dimen/playMusicIconSize"
android:layout_gravity="center"
app:civ_border_width="2dp"
app:civ_border_color="@android:color/black"/>
<!--播放按钮-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/play_music"
android:layout_gravity="center"
android:visibility="gone"/>
</FrameLayout>
<!--指针-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/needle"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="@dimen/needleMarginSize"/>
</FrameLayout>
上面的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) 光盘转动动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator">
<!--转动效果-->
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="@integer/play_music_anim_duration"
android:repeatCount="infinite"/>
</set>
(2) 指针指向光盘动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator">
<!--指针旋转动画-->
<rotate
android:fromDegrees="-20"
android:toDegrees="0"
android:pivotX="0"
android:pivotY="0"
android:duration="@integer/play_needle_anim_duration"
/>
</set>
(3) 指针离开光盘动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:fillAfter="true">
<rotate
android:fromDegrees="0"
android:toDegrees="-20"
android:pivotY="0"
android:pivotX="0"
android:duration="@integer/play_needle_anim_duration"
/>
</set>
(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();
}
}
}