仿网易云音乐播放界面

前言

网易云音乐是一款非常优秀的音乐播放器,尤其是播放界面,使用唱盘机风格,显得格外古典优雅。笔者出于学习与挑战的想法,思考播放界面背后的实现原理,并写了一个小程序。

笔者尽可能地去模仿官方的视觉、交互效果,其中包括了唱盘与唱针切换时的细节处理、背景渐变等。本文将会分享一些视觉效果实现的方法以及设计思想,但难免有错漏之处。若读者发现有错误的地方或者更好的实现方法,请留言回复,希望与大家共同进步。

1 源码地址

需要源码的朋友,可以到github中自行下载。Android开发技术进阶群;701740775。加群的朋友麻烦备注一下csdn
  github;https://github.com/AchillesLzg/jianshu-neteasedisc

2 本文内容

  • 项目结构介绍
  • 解决加载大图OOM问题
  • 生成圆图最简单的方法
  • 使用LayerDrawable进行图片合成
  • 实现背景毛玻璃效果
  • 使用LayerDrawable与属性动画,实现背景切换时渐变效果
  • 遇到复杂的场景,应该如何编写代码
  • 配合Service、本地广播进行音乐播放
  • 结束语

3 项目结构介绍

项目结构介绍包括以下内容:

  • 主界面布局设计
  • 唱盘布局设计
  • 动态布局
  • 唱盘控件DiscView对外接口及方法
  • 音乐状态控制时序图

3.1主界面布局设计

主界面布局从上到下可以划分几大区域,如图3-1所示:

                             图 3-1 主界面布局

标题栏 
使用ToolBar实现,字体可能需要自定义。

唱盘区域 
唱盘区域包括唱盘、唱针、底盘、以及实现切换的ViewPager等控件,该布局比较复杂,本案例使用自定义控件实现唱盘区域。

时长显示区域 
使用RelativeLayout作为根布局,进度条使用SeekBar实现。

播放控制区域 
比较简单,使用LinearLayout作为根布局。

另外,主界面使用RelativeLayout作为根布局。

3.2 唱盘布局设计

唱盘区域由控件DiscView实现,以RelativeLayout为根布局,子控件包括:底盘、唱针、ViewPager等。其中,底盘和唱针均用ImageView实现,然后使用ViewPager加载ImageView实现唱片的切换。如图3-2所示。

                    图 3-2 唱盘区域布局

唱盘布局代码如下所示:

<?ml version="1.0" encoding="utf-8"?>
<com.achillesl.neteasedisc.widget.DiscView
    mlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <!--底盘-->
    <ImageView
        android:id="@+id/ivDiscBlackgound"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        />

    <!--ViewPager实现唱片切换-->
    <android.support.v4.view.ViewPager
        android:id="@+id/vpDiscContain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        />

    <!--唱针-->
    <ImageView
        android:id="@+id/ivNeedle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_needle"/>

</com.achillesl.neteasedisc.widget.DiscView>

3.3 动态布局

到这里,读者可能有些好奇,上述布局中并没有指定控件的宽高、边距等参数,那如何保证控件显示在正确的位置?我们没有网易云音乐的设计图,因此不能得知官方的布局参数,那该怎么办呢?其实有个笨方法,我们可以打开网易云音乐的播放界面并截图,然后手动去量需要的高度、边距等参数。

截图量到控件的宽高、边距等数值,除以截图的宽或高,得到控件参数比例。使用时,我们根据手机的屏幕宽高,乘以对应的比例,就能得到该屏幕尺寸下的控件宽高、边距。

当然,这种动态布局肯定会消耗更多性能,但不失为没有办法中的办法。

相关控件参数比例,笔者统一放在DisplayUtil.java文件中,代码如下:

public class DisplayUtil {

    /*手柄起始角度*/
    public static final float ROTATION_INIT_NEEDLE = -30;

    /*截图屏幕宽高*/
    private static final float BASE_SCREEN_WIDTH = (float) 1080.0;
    private static final float BASE_SCREEN_HEIGHT = (float) 1920.0;

    /*唱针宽高、距离等比例*/
    public static final float SCALE_NEEDLE_WIDTH = (float) (276.0 / BASE_SCREEN_WIDTH);
    public static final float SCALE_NEEDLE_MARGIN_LEFT = (float) (500.0 / BASE_SCREEN_WIDTH);
    public static final float SCALE_NEEDLE_PIVOT_ = (float) (43.0 / BASE_SCREEN_WIDTH);
    public static final float SCALE_NEEDLE_PIVOT_Y = (float) (43.0 / BASE_SCREEN_WIDTH);
    public static final float SCALE_NEEDLE_HEIGHT = (float) (413.0 / BASE_SCREEN_HEIGHT);
    public static final float SCALE_NEEDLE_MARGIN_TOP = (float) (43.0 / BASE_SCREEN_HEIGHT);

    /*唱盘比例*/
    public static final float SCALE_DISC_SIZE = (float) (813.0 / BASE_SCREEN_WIDTH);
    public static final float SCALE_DISC_MARGIN_TOP = (float) (190 / BASE_SCREEN_HEIGHT);

    /*专辑图片比例*/
    public static final float SCALE_MUSIC_PIC_SIZE = (float) (533.0 / BASE_SCREEN_WIDTH);

    /*设备屏幕宽度*/
    public static int getScreenWidth(Contet contet) {
        return contet.getResources().getDisplayMetrics().widthPiels;
    }

    /*设备屏幕高度*/
    public static int getScreenHeight(Contet contet) {
        return contet.getResources().getDisplayMetrics().heightPiels;
    }
}

例如需要设置唱盘底盘的顶部外边距,我们先获得该比例,然后乘上当前屏幕高度,得到具体数值,最后通过LayoutParams类进行动态设置。

int marginTop = (int) (DisplayUtil.SCALE_DISC_MARGIN_TOP * mScreenHeight);
RelativeLayout.LayoutParams layoutParams = (LayoutParams) mDiscBlackground.getLayoutParams();
layoutParams.setMargins(0, marginTop, 0, 0);

3.4 DiscView对外接口及方法

唱盘控件DiscView提供一个接口IPlayInfo,代码如下:

public interface IPlayIn
  • 0
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值