android简易音乐重构mvvmjava版-新增歌曲播放界面+状态栏黑科技(十七)(代码片段)

雪の星空朝酱 雪の星空朝酱     2022-12-04     238

关键词:

Android简易音乐重构MVVM Java版-新增歌曲播放界面(十七)

关于

本篇主要实现播放界面包括,歌曲暂停、播放下一首、上一首、播放模式、歌词展示,实现根据歌曲背景深浅实现状态栏文字、标题文字黑白切换适配。
音乐播放封装使用《开源库MusicPlayManager - 封装StarrySky音乐库》
简易音乐app仅作为学习用,禁止用于商业及非法用途,如产生法律纠纷与本人无关

效果

新增歌曲播放界面

  新增activity_current_song_play.xml

<?xml version="1.0" encoding="utf-8"?>
<layout 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">
    <data>
        <variable
            name="vm"
            type="com.tobery.personalmusic.ui.song.SongPlayViewModel" />
    </data>
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.song.CurrentSongPlayActivity">

    <ImageView
        android:id="@+id/img_bc"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        android:src="@drawable/bg_default_song"
        tools:layout_editor_absoluteX="0dp"
        tools:layout_editor_absoluteY="52dp" />

    <View
        android:id="@+id/view_title_bg"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_45"
        app:layout_constraintTop_toTopOf="parent"
        />

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="@id/view_title_bg"
        app:layout_constraintBottom_toBottomOf="@id/view_title_bg"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:textColor="@color/white"
        />

    <View
        android:id="@+id/view_body"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_0"
        app:layout_constraintTop_toBottomOf="@id/view_title_bg"
        app:layout_constraintBottom_toTopOf="@id/view_bottom"
        />

    <ImageView
        android:id="@+id/iv_music_cover"
        android:layout_width="@dimen/dp_200"
        android:layout_height="@dimen/dp_200"
        imSrc="@vm.currentSongUrl"
        error="@@drawable/shape_music_record"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@id/view_title_bg"
        app:layout_constraintBottom_toBottomOf="@id/view_bottom"
        />

    <com.tobery.personalmusic.widget.LyricView
        android:id="@+id/lrc"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_0"
        app:current_color="#ffffff"
        app:default_label="暂无歌词,我也不知道怎么上传OvO"
        app:lrc_padding="@dimen/dp_10"
        app:normal_color="#808080"
        app:text_divider="@dimen/dp_15"
        app:text_gravity="center"
        app:text_size="@dimen/sp_18"
        app:time_color="#c5c3c2"
        app:time_text_size="@dimen/sp_13"
        app:timeline_color="#4d4948"
        android:visibility="gone"
        app:layout_constraintTop_toBottomOf="@id/view_title_bg"
        app:layout_constraintBottom_toTopOf="@id/view_bottom"
        />


    <View
        android:id="@+id/view_bottom"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_90"
        app:layout_constraintBottom_toBottomOf="parent"
        />

    <TextView
        android:id="@+id/tv_past_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/white"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@id/view_bottom"
        android:layout_marginStart="@dimen/dp_8"
        android:textSize="@dimen/sp_12" />

    <SeekBar
        android:id="@+id/seek_bar"
        android:layout_width="@dimen/dp_0"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:max="100"
        android:maxHeight="@dimen/dp_3"
        android:minHeight="@dimen/dp_3"
        android:progressDrawable="@drawable/seekbar_bg"
        android:thumb="@drawable/seekbar_thumb"
        app:layout_constraintTop_toTopOf="@id/view_bottom"
        app:layout_constraintStart_toEndOf="@id/tv_past_time"
        app:layout_constraintEnd_toStartOf="@id/tv_total_time"
        android:layout_marginStart="@dimen/dp_5"
        />

    <TextView
        android:id="@+id/tv_total_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/white"
        app:layout_constraintTop_toTopOf="@id/view_bottom"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginEnd="@dimen/dp_8"
        android:textSize="@dimen/sp_12" />

    <ImageView
        android:id="@+id/iv_play_mode"
        android:layout_width="@dimen/dp_45"
        android:layout_height="@dimen/dp_45"
        android:padding="@dimen/dp_15"
        android:layout_marginEnd="@dimen/dp_10"
        android:scaleType="centerCrop"
        android:src="@drawable/ic_play_list_loop_white"
        app:layout_constraintTop_toTopOf="@id/seek_bar"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/iv_pre"
        />
    <ImageView
        android:id="@+id/iv_pre"
        android:layout_width="@dimen/dp_45"
        android:layout_height="@dimen/dp_45"
        android:padding="@dimen/dp_15"
        android:scaleType="centerCrop"
        android:src="@drawable/shape_pre"
        android:onClick="@() -> vm.previous()"
        app:layout_constraintTop_toTopOf="@id/seek_bar"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/iv_play"
        />

    <ImageView
        android:id="@+id/iv_play"
        android:layout_width="@dimen/dp_50"
        android:layout_height="@dimen/dp_50"
        android:padding="@dimen/dp_5"
        android:src="@drawable/shape_play_white"
        app:layout_constraintTop_toTopOf="@id/seek_bar"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:onClick="@() -> vm.musicPlayOrPause()"
        />

    <ImageView
        android:id="@+id/iv_next"
        android:layout_width="@dimen/dp_45"
        android:layout_height="@dimen/dp_45"
        android:padding="@dimen/dp_15"
        android:scaleType="centerCrop"
        android:src="@drawable/shape_next"
        android:onClick="@() -> vm.next()"
        app:layout_constraintStart_toEndOf="@id/iv_play"
        app:layout_constraintTop_toTopOf="@id/seek_bar"
        app:layout_constraintBottom_toBottomOf="parent"
        />

    <ImageView
        android:id="@+id/iv_list"
        android:layout_width="@dimen/dp_45"
        android:layout_height="@dimen/dp_45"
        android:layout_marginStart="@dimen/dp_10"
        android:padding="@dimen/dp_10"
        android:scaleType="centerCrop"
        android:src="@drawable/ic_song_play_list"
        app:layout_constraintStart_toEndOf="@id/iv_next"
        app:layout_constraintTop_toTopOf="@id/seek_bar"
        app:layout_constraintBottom_toBottomOf="parent"
        />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

  新增bg_default_song.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <gradient
        android:endColor="#221B1A"
        android:gradientRadius="120%p"
        android:startColor="#4b3832"
        android:type="radial" />

</shape>

增加歌词view LyricView

public class LyricView extends View 
    private static final String TAG = "LyricView";
    //播放图片的宽高
    private static final float PLAY_DRAWABLE_WIDTH = ContextProvider.get().getContext().getResources().getDimension(R.dimen.dp_30);
    //时间 也就是 [XX:XX] 的宽度
    private static final float TIME_TEXT_WIDTH = ContextProvider.get().getContext().getResources().getDimension(R.dimen.dp_40);
    //时间线从一行 滑到另一行的时间
    private static final int ANIMATION_DURATION = 1000;
    //时间线从当前行 的某处 移到中间的时间
    private static final int ADJUST_DURATION = 100;

    private List<LrcEntry> mLrcEntryList = new ArrayList<>();
    //歌词画笔
    private TextPaint mLrcPaint = new TextPaint();
    //时间线 画笔
    private TextPaint mTimePaint = new TextPaint();
    //时间线 画笔属性
    private Paint.FontMetrics mTimeFontMetrics;
    //播放按钮
    private Drawable mPlayDrawable;
    //普通字体的颜色
    private int mNormalTextColor;
    //字体的大小(普通和选中的都一样大
    private float mTextSize;
    //选中行 字体颜色
    private int mCurrentTextColor;
    //时间线 所在的一行歌词 已经时间的颜色
    private int mTimelineTextColor;
    //时间线的颜色
    private int mTimelineColor;
    //padding值
    private float mPadding;
    //没有加载完歌词的 默认显示text
    private String mDefaultLabel;
    //滑动的动画
    private ValueAnimator mAnimator;
    //手势监听器
    private GestureDetector mGestureDetector;
    //播放监听器
    private OnPlayClickListener mListener;
    //滑动类
    private Scroller mScroller;
    //是否正在滑动/正在点击/显示时间线
    private boolean isFling, isTouching, isShowTimeline;
    //歌词位置
    private int mTextGravity;
    //手指在 屏幕上滑动的 偏移量
    private float mOffset;
    //每句歌词之间的间隔
    private float mDividerHeight = 0;
    //选中的歌词,即时间线所在的歌词
    private int mCurrentLine;
    //单击该view,如果不是点击播放按钮,则歌词界面消失
    private OnCoverChangeListener coverChangeListener;

    /**
     * 播放按钮的监听器,如果成功消费该事件,则更新Ui
     */
    public interface OnPlayClickListener 
        boolean onPlayClick(long time);
    

    public LyricView(Context context) 
        this(context, null);
    

    public LyricView(Context context, @Nullable AttributeSet attrs) 
        this(context, attrs, 0);
    

    public LyricView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) 
        super(context, attrs, defStyleAttr);
        initView(context, attrs);

        mGestureDetector = new GestureDetector(context, mSimpleOnGestureListener);
        mGestureDetector.setIsLongpressEnabled(false);
        mScroller = new Scroller(context);
    

    private void initView(Context context, AttributeSet attrs) 
        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.LyricView);
        mTextSize = ta.getDimension(R.styleable.LyricView_text_size, getResources()android简易音乐重构mvvmjava版-新增推荐菜单及侧边栏展示(代码片段)

Android简易音乐重构MVVMJava版-新增推荐菜单及侧边栏展示(十二)关于效果图添加侧边栏添加推荐歌单新增RecommendAdapter适配器修改DiscoverFragment.java关于  本篇主要实现主界面新增推荐歌单展示及侧滑栏菜单。效果图添加... 查看详情

android简易音乐重构mvvmjava版-新增looklive+用户vip等级动画展示(十四)(代码片段)

Android简易音乐重构MVVMJava版-新增looklive+用户vip等级动画展示(十四)关于效果图新增looklive适配器(LookAdapter)新增LookLiveEntity实体类修改DiscoverFragment布局修改DiscoverFragment修改DiscoverFragmentViewModel新增本地 查看详情

android简易音乐重构mvvmjava版-新增歌曲播放界面+状态栏黑科技(十七)(代码片段)

Android简易音乐重构MVVMJava版-新增歌曲播放界面(十七)关于效果新增歌曲播放界面增加歌词view`LyricView`修改ApiService添加引用添加SongPlayViewModel修改CurrentSongPlayActivity.java修改Constant.java修改日推界面DailySongsActivity修改... 查看详情

android简易音乐重构mvvmjava版-新增歌曲播放界面+状态栏黑科技(十七)(代码片段)

Android简易音乐重构MVVMJava版-新增歌曲播放界面(十七)关于效果新增歌曲播放界面增加歌词view`LyricView`修改ApiService添加引用添加SongPlayViewModel修改CurrentSongPlayActivity.java修改Constant.java修改日推界面DailySongsActivity修改... 查看详情

android简易音乐重构mvvmjava版-新增轮播图网页链接跳转展示(十五)(代码片段)

Android简易音乐重构MVVMJava版-新增轮播图网页链接跳转展示(十五)关于效果图新增WebActivity页面修改WebActivity修改DiscoverFragment新增BindingAdapter修改MgcAdapter与LookAdapter关于  本篇主要讲述轮播图跳转web网页及个人新版webvie... 查看详情

android简易音乐重构mvvmjava版-新增轮播图网页链接跳转展示(十五)(代码片段)

Android简易音乐重构MVVMJava版-新增轮播图网页链接跳转展示(十五)关于效果图新增WebActivity页面修改WebActivity修改DiscoverFragment新增BindingAdapter修改MgcAdapter与LookAdapter关于  本篇主要讲述轮播图跳转web网页及个人新版webvie... 查看详情

android简易音乐重构mvvmjava版-新增首页最近播放歌曲展示及底部音乐bar+日推功能(十六)(代码片段)

Android简易音乐重构MVVMJava版-新增首页最近播放歌曲展示及底部音乐bar+日推功能(十六)关于效果添加底部展示歌曲添加RecentSongInfoEntity实体类修改MainViewModel新增底部音乐bar`item_song_bottom_bar.xml`:修改MainActivity添加... 查看详情

android简易音乐重构mvvmjava版-新增looklive+用户vip等级动画展示(十四)(代码片段)

Android简易音乐重构MVVMJava版-新增looklive+用户vip等级动画展示(十四)关于效果图新增looklive适配器(LookAdapter)新增LookLiveEntity实体类修改DiscoverFragment布局修改DiscoverFragment修改DiscoverFragmentViewModel新增本地html( ... 查看详情

android简易音乐重构mvvmjava版-新增我喜欢的歌单展示+底部bar点击跳转播放功能(十九)(代码片段)

Android简易音乐重构MVVMJava版-新增我喜欢的歌单展示+底部bar点击跳转播放功能(十九)关于效果修改MainActivity修改fragment_mine.xml修改MainViewModel添加用户profile添加用户信息接口添加用户实体类UserDetailEntity修改MineFragmentVie... 查看详情

android简易音乐重构mvvmjava版-新增我喜欢的歌单展示+底部bar点击跳转播放功能(十九)(代码片段)

Android简易音乐重构MVVMJava版-新增我喜欢的歌单展示+底部bar点击跳转播放功能(十九)关于效果修改MainActivity修改fragment_mine.xml修改MainViewModel添加用户profile添加用户信息接口添加用户实体类UserDetailEntity修改MineFragmentVie... 查看详情

android简易音乐重构mvvmjava版-新增启动动画(代码片段)

Android简易音乐重构MVVMJava版-新增启动动画(九)关于效果图修改color.xml添加dimens.xml修改strings.xml添加splash主题添加部分实体类添加login_bean.java添加SharePreferencesUtil帮助类添加Constant常量添加activity_splash.xml添加splash图标添... 查看详情

android简易音乐重构mvvmjava版-新增首页最近播放歌曲展示及底部音乐bar+日推功能(十六)(代码片段)

Android简易音乐重构MVVMJava版-新增首页最近播放歌曲展示及底部音乐bar+日推功能(十六)关于效果添加底部展示歌曲添加RecentSongInfoEntity实体类修改MainViewModel新增底部音乐bar`item_song_bottom_bar.xml`:修改MainActivity添加... 查看详情

android简易音乐重构mvvmjava版-搭建项目(代码片段)

Android简易音乐重构MVVMJava版-搭建项目(八)关于新版本配置网易云音乐api版本更新重构代码新建app类继承Application项目结构定义BaseActivity.java状态栏工具防恶意多点工具类CrashHandler用于异常处理上报日志关于  本篇主要... 查看详情

android简易音乐重构mvvmjava版-使用navigation导航组件重构主界面及其他页面跳转(二十)(代码片段)

Android简易音乐重构MVVMJava版-使用Navigation导航组件重构主界面及其他页面跳转(二十)关于效果图实现修改Activity_main.xml页面修改MainActivity.java新建一个libCommon的library(一些kotlin写的工具放在这里)修改nav_graph.xml... 查看详情

android简易音乐重构mvvmjava版-使用navigation导航组件重构主界面及其他页面跳转(二十)(代码片段)

Android简易音乐重构MVVMJava版-使用Navigation导航组件重构主界面及其他页面跳转(二十)关于效果图实现修改Activity_main.xml页面修改MainActivity.java新建一个libCommon的library(一些kotlin写的工具放在这里)修改nav_graph.xml... 查看详情

android简易音乐重构mvvmjava版-github开源+功能介绍(二十三)

Android简易音乐重构MVVMJava版-github开源+功能介绍(二十三)关于涉及框架、三方lib等手机登录及token刷新登录主界面发现轮播图跳转每日推荐推荐歌单、雷达歌单等各种歌单列表界面look直播歌曲播放界面音乐通知栏我... 查看详情

android简易音乐重构mvvmjava版-github开源+功能介绍(二十三)

Android简易音乐重构MVVMJava版-github开源+功能介绍(二十三)关于涉及框架、三方lib等手机登录及token刷新登录主界面发现轮播图跳转每日推荐推荐歌单、雷达歌单等各种歌单列表界面look直播歌曲播放界面音乐通知栏我... 查看详情

android简易音乐重构mvvmjava版-使用diffutil解决recycleview整体数据刷新性能问题(二十二)(代码片段)

Android简易音乐重构MVVMJava版-使用DiffUtil解决recycleView整体数据刷新性能问题(二十二)关于优化格式化日期警告问题解决recycleView暴力刷新数据问题解决关于  因为最近项目原因,一些以前为了解决黄色警告的@Sup... 查看详情