由于最近自己在做一个音乐APP,在播放音乐时,想实现网易云那种带光盘和指针的界面,所以在慕课上找了学习教程,以下是我的学习过程,先放出网易云播放界面

                                                                 Android开发----实现音乐播放界面(模仿网易云)-LMLPHP

         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) 效果

                                                            Android开发----实现音乐播放界面(模仿网易云)-LMLPHP

         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来设置图片,效果如下:

                                                              Android开发----实现音乐播放界面(模仿网易云)-LMLPHP

         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();
        }
    }
}
04-23 09:21