Android简易音乐重构MVVM Java版-新增歌曲播放界面+状态栏黑科技(十七)

Posted 雪の星空朝酱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android简易音乐重构MVVM Java版-新增歌曲播放界面+状态栏黑科技(十七)相关的知识,希望对你有一定的参考价值。

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简易音乐重构MVVM Java版-新增歌曲播放界面+状态栏黑科技(十七)的主要内容,如果未能解决你的问题,请参考以下文章

Android简易音乐重构MVVM Java版-新增启动动画

Android简易音乐重构MVVM Java版-新增推荐菜单及侧边栏展示

Android简易音乐重构MVVM Java版-BottomNavigationView+viewpager主界面结构

Android简易音乐重构MVVM Java版-新增推荐雷达歌单详情列表界面(十八)

Android简易音乐重构MVVM Java版-新增推荐雷达歌单详情列表界面(十八)

Android简易音乐重构MVVM Java版-新增歌曲播放界面+状态栏黑科技(十七)