• Android简易音乐重构MVVM Java版-新增首页最近播放歌曲展示及底部音乐bar+日推功能(十六)


    关于

    本篇主要实现底部展示最近最后听的一首歌信息bar以及日推歌曲列表界面。本篇文章里面用到的资源文件图片也可以使用自己的。

    效果

    在这里插入图片描述

    添加底部展示歌曲

      修改ApiService

    @GET("record/recent/song") //最近播放音乐
        LiveData<ApiResponse<RecentSongInfoEntity>> getRecentSong(@Query("limit") int limit);
    
    • 1
    • 2

    添加RecentSongInfoEntity实体类

    @NoArgsConstructor
    @Data
    public class RecentSongInfoEntity {
    
        private int code;
        private RecentDataEntity data;
        private String message;
    
        @NoArgsConstructor
        @Data
        public static class RecentDataEntity {
            private int total;
            private List<ListEntity> list;
    
            @NoArgsConstructor
            @Data
            public static class ListEntity {
                private String resourceId;
                private long playTime;
                private String resourceType;
                private DataEntity data;
    
                @NoArgsConstructor
                @Data
                public static class DataEntity {
                    private String name;
                    private int id;
                    private int pst;
                    private int t;
                    private List<ArEntity> ar;
                    private List<?> alia;
                    private int pop;
                    private int st;
                    private String rt;
                    private int fee;
                    private int v;
                    private Object crbt;
                    private String cf;
                    private AlEntity al;
                    private int dt;
                    private HEntity h;
                    private MEntity m;
                    private LEntity l;
                    private Object a;
                    private String cd;
                    private int no;
                    private Object rtUrl;
                    private int ftype;
                    private List<?> rtUrls;
                    private int djId;
                    private int copyright;
                    private int s_id;
                    private int mark;
                    private int originCoverType;
                    private Object originSongSimpleData;
                    private int single;
                    private Object noCopyrightRcmd;
                    private int rtype;
                    private Object rurl;
                    private int mst;
                    private int cp;
                    private int mv;
                    private long publishTime;
    
                    @NoArgsConstructor
                    @Data
                    public static class AlEntity {
                        private int id;
                        private String name;
                        private String picUrl;
                        private List<?> tns;
                        private String pic_str;
                        private long pic;
                    }
    
                    @NoArgsConstructor
                    @Data
                    public static class HEntity {
                        private int br;
                        private int fid;
                        private int size;
                        private int vd;
                    }
    
                    @NoArgsConstructor
                    @Data
                    public static class MEntity {
                        private int br;
                        private int fid;
                        private int size;
                        private int vd;
                    }
    
                    @NoArgsConstructor
                    @Data
                    public static class LEntity {
                        private int br;
                        private int fid;
                        private int size;
                        private int vd;
                    }
    
                    @NoArgsConstructor
                    @Data
                    public static class ArEntity {
                        private int id;
                        private String name;
                        private List<?> tns;
                        private List<?> alias;
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114

    修改MainViewModel

     public ObservableField<String> currentSongUrl = new ObservableField<>("");
     public ObservableField<String> currentSongName = new ObservableField<>("");
     public MusicInfo currentMusicInfo;
    
     public LiveData<ApiResponse<RecentSongInfoEntity>> getRecentSong(){
            return RetrofitUtils.getmApiUrl().getRecentSong(1);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    新增底部音乐baritem_song_bottom_bar.xml:

    
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <data>
            <variable
                name="bottom"
                type="com.tobery.personalmusic.ui.home.MainViewModel" />
        data>
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_40"
            android:id="@+id/root_bottom_bar"
            android:background="@color/white"
            >
    
            <ImageView
                android:id="@+id/iv_cover"
                android:layout_width="@dimen/dp_35"
                android:layout_height="@dimen/dp_35"
                android:layout_marginStart="@dimen/dp_5"
                android:src="@drawable/shape_music_record"
                imSrc="@{bottom.currentSongUrl}"
                error="@{@drawable/shape_music_record}"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                />
    
            <TextView
                android:id="@+id/tv_song_name"
                android:layout_width="@dimen/dp_0"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:maxLines="1"
                android:singleLine="true"
                android:text="@{bottom.currentSongName}"
                android:textColor="@color/grays_01"
                android:layout_marginStart="@dimen/dp_16"
                android:layout_marginEnd="@dimen/dp_16"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toEndOf="@id/iv_cover"
                app:layout_constraintEnd_toStartOf="@id/iv_bottom_play"
                android:textSize="@dimen/sp_12"
                />
    
            <ImageView
                android:id="@+id/iv_song_list"
                android:layout_width="@dimen/dp_22"
                android:layout_height="@dimen/dp_22"
                android:layout_marginEnd="@dimen/dp_16"
                android:src="@drawable/ic_song_play_list"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                />
    
            <ImageView
                android:id="@+id/iv_bottom_play"
                android:layout_width="@dimen/dp_27"
                android:layout_height="@dimen/dp_27"
                android:layout_centerVertical="true"
                android:layout_marginEnd="@dimen/dp_20"
                android:src="@drawable/shape_play"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@id/iv_song_list"
                />
    
        androidx.constraintlayout.widget.ConstraintLayout>
    layout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    修改MainActivity

    private void initBottomBar() {
            viewModel.getRecentSong().observe(this,recentSongInfoEntityApiResponse -> {
                if (recentSongInfoEntityApiResponse.getStatus() == Status.SUCCESS ){
                    RecentSongInfoEntity.RecentDataEntity.ListEntity.DataEntity data =recentSongInfoEntityApiResponse.getData().getData().getList()
                            .get(0).getData();
                    viewModel.currentSongName.set(data.getName());
                    viewModel.currentSongUrl.set(data.getAl().getPicUrl());
                    MusicInfo musicInfo = new MusicInfo();
                    musicInfo.setArtist(data.getAr().get(0).getName());
                    musicInfo.setSongId(data.getId()+"");
                    musicInfo.setSongName(data.getName());
                    musicInfo.setSongCover(data.getAl().getPicUrl());
                    musicInfo.setSongUrl(SONG_URL+data.getId());
                    viewModel.currentMusicInfo = musicInfo;
                }
            });
    
            MusicPlay.onPlayStateListener(this, new OnMusicPlayStateListener() {
                @Override
                public void onPlayState(@NonNull PlayManger playManger) {
                    viewModel.currentSongUrl.set(playManger.getSongInfo().getSongCover());
                    viewModel.currentSongName.set(playManger.getSongInfo().getSongName());
                    switch (playManger.getStage()){
                        case PlayManger.PAUSE:
                        case PlayManger.IDLE:
                            binding.songBar.ivBottomPlay.setImageResource(R.drawable.shape_play);
                            break;
                        case PlayManger.PLAYING:
                            binding.songBar.ivBottomPlay.setImageResource(R.drawable.shape_pause_black);
                            viewModel.currentMusicInfo = playManger.getSongInfo();
                            break;
                        case PlayManger.BUFFERING:
                            ViewExtensionKt.printLog("缓冲");
                            break;
                        case PlayManger.SWITCH:
                            viewModel.currentMusicInfo = playManger.getSongInfo();
                            break;
    
                    }
                }
            });
    
            binding.songBar.rootBottomBar.setOnClickListener(view -> {
                if (ClickUtil.enableClick()){
                    MusicPlay.playMusicByInfo(viewModel.currentMusicInfo);
                }
            });
            binding.songBar.ivBottomPlay.setOnClickListener(view -> {
                if (MusicPlay.isPlaying()){
                    MusicPlay.pauseMusic();
                }else {
                    MusicPlay.restoreMusic();
                }
            });
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    添加shape_play.xml:

    
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="1024dp"
        android:height="1024dp"
        android:viewportWidth="1024"
        android:viewportHeight="1024">
    
        <path
            android:fillColor="#333333"
            android:pathData="M512 0C229.216 0 0 229.216 0 512c0 282.768 229.216 512 512 512 282.752 0 512-229.232 512-512C1024 229.216 794.752 0 512 0zM512 992C246.896 992 32 777.088 32 512 32 246.896 246.896 32 512 32c265.056 0 480 214.896 480 480C992 777.088 777.056 992 512 992z" />
        <path
            android:fillColor="#333333"
            android:pathData="M821.152 518.112c0.432-1.008 0.832-1.984 1.024-3.056 0.224-1.072 0.24-2.096 0.224-3.152 0-0.96-0.016-1.872-0.192-2.816-0.224-1.2-0.656-2.272-1.136-3.392-0.24-0.544-0.256-1.136-0.56-1.664-0.16-0.256-0.4-0.4-0.56-0.64-0.656-0.992-1.488-1.824-2.336-2.672-0.704-0.672-1.344-1.344-2.128-1.872-0.32-0.208-0.48-0.528-0.816-0.704l-457.264-264c-0.288-0.16-0.608-0.16-0.896-0.304-0.976-0.48-2-0.736-3.056-1.024-1.04-0.272-2.032-0.56-3.088-0.624-0.336-0.016-0.608-0.192-0.96-0.192-0.688 0-1.296 0.32-1.968 0.4-1.104 0.128-2.144 0.288-3.184 0.64-0.992 0.336-1.84 0.816-2.736 1.328-0.88 0.496-1.712 0.992-2.496 1.68-0.848 0.72-1.488 1.568-2.16 2.448-0.4 0.528-0.976 0.896-1.328 1.488-0.176 0.304-0.16 0.624-0.32 0.928-0.464 0.944-0.72 1.968-1.008 3.008-0.288 1.056-0.576 2.064-0.64 3.136-0.016 0.336-0.192 0.608-0.192 0.944l0 528.032c0 0.336 0.176 0.608 0.192 0.928 0.064 1.072 0.352 2.112 0.64 3.168 0.288 1.04 0.528 2.048 0.992 2.992 0.16 0.304 0.144 0.624 0.32 0.928 0.336 0.592 0.912 0.96 1.328 1.504 0.672 0.88 1.328 1.712 2.16 2.448 0.784 0.672 1.632 1.184 2.528 1.68 0.88 0.512 1.712 0.992 2.688 1.312 1.072 0.368 2.144 0.528 3.264 0.656 0.656 0.096 1.232 0.384 1.904 0.384 0.336 0 0.608-0.176 0.928-0.192 1.072-0.064 2.096-0.352 3.168-0.64 1.04-0.288 2.048-0.528 2.992-0.992 0.304-0.16 0.64-0.144 0.928-0.32l457.248-264c0.32-0.192 0.48-0.48 0.784-0.688 0.848-0.56 1.552-1.28 2.288-2.016 0.8-0.784 1.584-1.552 2.176-2.464 0.192-0.272 0.464-0.416 0.64-0.72C820.88 519.392 820.912 518.72 821.152 518.112zM365.408 275.696 774.672 512 365.408 748.304 365.408 275.696z" />
    vector>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    添加shape_pause_black.xml:

    
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="1024dp"
        android:height="1024dp"
        android:viewportWidth="1024"
        android:viewportHeight="1024">
    
        <path
            android:fillColor="#333333"
            android:pathData="M540.032 70.976c-245.952 0-446.016 200.064-446.016 446.016S294.08 963.008 540.032 963.008s446.016-200.064 446.016-446.016S785.984 70.976 540.032 70.976z m0 828.032c-210.624 0-382.016-171.392-382.016-382.016s171.392-382.016 382.016-382.016 382.016 171.392 382.016 382.016-171.392 382.016-382.016 382.016z" />
        <path
            android:fillColor="#333333"
            android:pathData="M430.4 340.608c-18.24 0-33.088 12.736-33.088 28.544v285.696c0 15.744 14.784 28.544 33.088 28.544 18.24 0 33.024-12.8 33.024-28.544V369.152c0-15.808-14.848-28.544-33.024-28.544z m164.224 0c-18.24 0-33.024 12.736-33.024 28.544v285.696c0 15.744 14.72 28.544 33.024 28.544s33.088-12.8 33.088-28.544V369.152c0-15.808-14.848-28.544-33.088-28.544z" />
    vector>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    添加日推界面

      新增activity_daily_songs.xml:

    
    <androidx.coordinatorlayout.widget.CoordinatorLayout 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=".ui.daily.DailySongsActivity">
    
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fitsSystemWindows="true"
            app:elevation="0dp">
    
            <com.google.android.material.appbar.CollapsingToolbarLayout
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_180"
                android:fitsSystemWindows="true"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                >
    
                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    app:layout_collapseMode="parallax">
    
                    <ImageView
                        android:id="@+id/img_daily_bg"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent" />
    
                    <TextView
                        android:id="@+id/tv_day"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="@dimen/dp_20"
                        android:layout_marginTop="@dimen/dp_80"
                        android:textColor="#f0f0f0f0"
                        android:textSize="@dimen/sp_30"
                        android:typeface="monospace" />
    
                    <TextView
                        android:id="@+id/tv_month"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignBottom="@id/tv_day"
                        android:layout_marginStart="@dimen/dp_10"
                        android:layout_toEndOf="@+id/tv_day"
                        android:textColor="#f0f0f0"
                        android:textSize="@dimen/sp_28"
                        android:typeface="monospace" />
                RelativeLayout>
    
                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_gravity="top"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_45"
                    app:layout_collapseMode="pin">
    
                    <include
                        android:id="@+id/title"
                        layout="@layout/ui_common_title"
                        app:layout_collapseMode="pin"/>
                androidx.appcompat.widget.Toolbar>
    
            com.google.android.material.appbar.CollapsingToolbarLayout>
        com.google.android.material.appbar.AppBarLayout>
    
    
        <RelativeLayout
            android:id="@+id/rl_play"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
    
            <RelativeLayout
                android:id="@+id/rv_play_top"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_40"
                tools:ignore="RtlSymmetry">
    
                <TextView
                    android:id="@+id/img_play"
                    android:layout_width="@dimen/dp_24"
                    android:layout_height="@dimen/dp_24"
                    android:layout_centerVertical="true"
                    android:layout_marginStart="@dimen/dp_13"
                    android:background="@drawable/ic_daily_play_all" />
    
                <TextView
                    android:id="@+id/daily_play"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_marginStart="@dimen/dp_8"
                    android:layout_toEndOf="@+id/img_play"
                    android:gravity="center"
                    android:text="@string/daily_play"
                    android:textColor="@color/pureBlack"
                    android:textSize="@dimen/sp_18"
                    android:textStyle="bold" />
    
            RelativeLayout>
    
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv_daily"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_below="@id/rv_play_top"
                android:background="@color/white35" />
    
        RelativeLayout>
    
    
    androidx.coordinatorlayout.widget.CoordinatorLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118

    新增ic_daily_play_all.xml

    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="64dp"
        android:height="64dp"
        android:viewportWidth="1024"
        android:viewportHeight="1024">
      <path
          android:pathData="M512,42.7C252.8,42.7 42.7,252.8 42.7,512s210.1,469.3 469.3,469.3 469.3,-210.1 469.3,-469.3S771.2,42.7 512,42.7zM708.5,543.2l-266.7,176A37.3,37.3 0,0 1,384 688L384,336a37.3,37.3 0,0 1,57.9 -31.2l266.7,176a37.3,37.3 0,0 1,0 62.3z"
          android:fillColor="#FFB6C1"/>
    vector>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    修改日推界面DailySongsActivity

    public class DailySongsActivity extends BaseActivity {
    
        private ActivityDailySongsBinding binding;
        private DailySongsAdapter adapter;
        private DailySongsViewModel viewModel;
        private ArrayList<MusicInfo> songList = new ArrayList<>();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            binding = ActivityDailySongsBinding.inflate(getLayoutInflater());
            viewModel = new ViewModelProvider(this).get(DailySongsViewModel.class);
            setContentView(binding.getRoot());
            initRecycle();
            initView();
            initObserver();
        }
    
        private void initView() {
            StatusBarUtil.setColor(this,getResources().getColor(R.color.colorPrimary,null),0);
            binding.tvDay.setText(Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "");
            binding.tvMonth.setText("/"+(Calendar.getInstance().get(Calendar.MONTH)+1)+"");
            binding.title.ivBack.setOnClickListener(view -> {
                if (ClickUtil.enableClick()){
                    finish();
                }
            });
            binding.rvPlayTop.setOnClickListener(v -> {
                if (ClickUtil.enableClick()){
                    MusicPlay.playMusicByList(songList,0);
                }
            });
        }
    
        private void initObserver() {
            viewModel.getDailySongs().observe(this, dailySongsEntityApiResponse -> {
                if (dailySongsEntityApiResponse.getStatus() == Status.SUCCESS){
                    adapter.setDataList(dailySongsEntityApiResponse.getData().getData().getDailySongs(),dailySongsEntityApiResponse.getData().getData().getRecommendReasons());
                    for (DailySongsEntity.DataEntity.SongsEntity data: dailySongsEntityApiResponse.getData().getData().getDailySongs()){
                        MusicInfo musicInfo = new MusicInfo();
                        musicInfo.setSongUrl(Constant.SONG_URL+data.getId());
                        musicInfo.setSongId(String.valueOf(data.getId()));
                        String songName = data.getName();
                        if (data.getTns() != null){ //外语翻译歌名
                            songName += "("+data.getTns().get(0)+")";
                        }
                        musicInfo.setSongName(songName);
                        musicInfo.setArtist(data.getAr().get(0).getName());
                        musicInfo.setSongCover(data.getAl().getPicUrl());
                        songList.add(musicInfo);
                    }
                }
            });
        }
    
        private void initRecycle() {
            adapter = new DailySongsAdapter(this);
            LinearLayoutManager manager = new LinearLayoutManager(this);
            manager.setOrientation(LinearLayoutManager.VERTICAL);
            binding.rvDaily.setLayoutManager(manager);
            binding.rvDaily.setAdapter(adapter);
            binding.rvDaily.setHasFixedSize(true);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    添加DailySongsViewModel.java

    public class DailySongsViewModel extends ViewModel {
    
        private SavedStateHandle state;
    
        public DailySongsViewModel(SavedStateHandle savedStateHandle) {
            this.state = savedStateHandle;
        }
    
        public LiveData<ApiResponse<DailySongsEntity>> getDailySongs(){
            return RetrofitUtils.getmApiUrl().getDailySongs();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    添加日推歌单适配器DailySongsAdapter

    public class DailySongsAdapter extends RecyclerView.Adapter<DailySongsViewHolder> {
    
        private final List<DailySongsEntity.DataEntity.SongsEntity> dataList = new ArrayList<>();
        private final List<DailySongsEntity.DataEntity.RecommendReasonsEntity> reasonList = new ArrayList<>();
    
        private final Context mContext;
    
        public DailySongsAdapter(Context context) {
            this.mContext = context;
        }
    
        @NonNull
        @Override
        public DailySongsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            ItemDailySongBinding binding = ItemDailySongBinding
                    .inflate(LayoutInflater.from(parent.getContext()), parent, false);
            return new DailySongsViewHolder(binding);
        }
    
        @SuppressLint("NotifyDataSetChanged")
        public void setDataList(List<DailySongsEntity.DataEntity.SongsEntity> data,List<DailySongsEntity.DataEntity.RecommendReasonsEntity> reason) {
            dataList.clear();
            dataList.addAll(data);
            reasonList.clear();
            reasonList.addAll(reason);
            notifyDataSetChanged();
        }
    
        @Override
        public void onBindViewHolder(@NonNull DailySongsViewHolder holder, int position) {
            DailySongsEntity.DataEntity.SongsEntity bean = dataList.get(position);
            holder.tvSongName.setText(bean.getName());
            holder.tvSinger.setText(bean.getAr().get(0).getName()+"-"+bean.getAl().getName());
            BindingAdapter.loadRadiusImage(holder.imgSong,bean.getAl().getPicUrl());
            MusicInfo musicInfo = new MusicInfo();
            musicInfo.setSongUrl(Constant.SONG_URL+bean.getId());
            musicInfo.setSongId(String.valueOf(bean.getId()));
            String songName = bean.getName();
            if (bean.getTns() != null){ //外语翻译歌名
                songName += "("+bean.getTns().get(0)+")";
            }
            musicInfo.setSongName(songName);
            musicInfo.setArtist(bean.getAr().get(0).getName());
            musicInfo.setSongCover(bean.getAl().getPicUrl());
            for (DailySongsEntity.DataEntity.RecommendReasonsEntity data: reasonList){
                if (data.getSongId() == bean.getId()){
                    holder.tvRecommend.setText(data.getReason());
                }
            }
            if (bean.getFee() == 1){//1表示vip歌曲
                holder.tvVip.setVisibility(View.VISIBLE);
            }
            if (bean.getSq() != null){//表示该歌曲有SQ版本
                holder.tvSq.setVisibility(View.VISIBLE);
            }
            if (bean.getHr() != null){//表示有hi版
                holder.tvSq.setText(mContext.getString(R.string.music_type_hi));
                holder.tvSq.setVisibility(View.VISIBLE);
            }
            holder.itemView.setOnClickListener(view -> {
                if (ClickUtil.enableClick()){
                    MusicPlay.playMusicByInfo(musicInfo);
                }
            });
        }
    
        @Override
        public int getItemCount() {
            return dataList.size();
        }
    }
    
    class DailySongsViewHolder extends RecyclerView.ViewHolder {
        TextView tvSongName,tvSinger,tvRecommend,tvVip,tvSq;
        ImageView imgSong;
    
        public DailySongsViewHolder(ItemDailySongBinding binding) {
            super(binding.getRoot());
            tvSongName = binding.tvSongName;
            tvSinger = binding.tvSinger;
            imgSong = binding.imgSong;
            tvRecommend = binding.tvRecommend;
            tvVip = binding.tvVipFlag;
            tvSq = binding.tvMusicSq;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    本篇到此就结束了,下篇主要实现歌曲播放界面,包括适配动态背景和状态栏变化等。

  • 相关阅读:
    <Linux进程控制>——《Linux》
    【vue】 vue2 监听滚动条滚动事件
    基于栅格地图的路径规划(一)基于Matlab二维、三维栅格地图的构建
    【Android Studio】Git可视化基本操作
    使用Dataset 和DataLoader 加载数据集
    金融行业多活架构设计及容灾发展趋势
    抽取泛微和建云的销售合同定时任务(要求记录翻译不成功的字段)
    HWUI渲染中RenderProxy视角看一种很有用的编程模式
    数据治理中的核心元素——元数据
    Opencv 极坐标变换
  • 原文地址:https://blog.csdn.net/Tobey_r1/article/details/125791302