云音乐-预览与设计初衷

为什么还在使用它。。。因为怀念吧。其实现在已经很少因为一个小的技术更新而更新博客,知识的迭代过快,更多的选择还是将知识放入自己的“笔记”之中,久而久之就越来越不再更新博客。周末发现已经超过一年多没有使用了,就前一段时间因为这里使用的插图“新浪图床”跪了,有更新一下图片,近期还是再更新一波吧,真的下一次想更新不知道要到什么时候了,这次更新的是记一个实现网易云音乐APP的思路,先上预览图,要是想了解就继续看

Share

这两年变化的技术太多了,然后看到了NeteaseCloudMusicApi就突然萌生了写一个冲动,当然我也知道很多的人已经分享过这个App了,然后我再github上寻找了好多个看过人家的源码,发现不是java就是mvp的模式,连是用kotlin编写的都少,还有就是在使用.aidl的Service接口。想自己也撸一个。。

5月7号新建的工程,现在都快过一个月了,想着更新一下博客就分享出来了,因为我相信Google和Github已经很强大了,解决不了的问题请找他们吧。我想分享的如何实现这个App

先上一波图,对比最新网易云音乐,我还是尽量还原得一样。

其次分享一下主要实现技术:Navigation+MVVM+Dagger Hilt+exoplayer

以下是完整依赖

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
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines"

implementation 'androidx.core:core-ktx:1.6.0-beta01'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
implementation 'androidx.paging:paging-runtime-ktx:3.0.0'
implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01'
implementation 'androidx.palette:palette-ktx:1.0.0'

// hilt-dagger
implementation "com.google.dagger:hilt-android:$dagger_hilt_core"
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
kapt "com.google.dagger:hilt-compiler:$dagger_hilt_core"
androidTestImplementation "com.google.dagger:hilt-android-testing:$dagger_hilt_core"
kaptAndroidTest "com.google.dagger:hilt-compiler:$dagger_hilt_core"

implementation "androidx.hilt:hilt-common:$dagger_hilt"
kapt "androidx.hilt:hilt-compiler:$dagger_hilt"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"

implementation "com.squareup.retrofit2:retrofit:$retrofit2_version"
implementation "com.squareup.retrofit2:converter-moshi:$retrofit2_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit2_version"
implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.2'
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2'

implementation "androidx.media:media:1.3.1"
api "com.google.android.exoplayer:exoplayer-core:$exoplayer_version"
api "com.google.android.exoplayer:exoplayer-ui:$exoplayer_version"
api "com.google.android.exoplayer:extension-mediasession:$exoplayer_version"
api "com.google.android.exoplayer:extension-cast:$exoplayer_version"

// room
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
androidTestImplementation "androidx.room:room-testing:$room_version"

implementation 'com.google.android.flexbox:flexbox:3.0.0'

implementation 'com.jakewharton.timber:timber:4.7.1'
implementation "io.coil-kt:coil:1.2.1"
implementation 'com.youth.banner:banner:2.1.0'
implementation 'com.github.kirich1409:viewbindingpropertydelegate:1.4.6'
implementation 'com.tencent:mmkv-static:1.2.8'
implementation 'com.just.agentweb:agentweb:4.1.4'

最后,怎么实现的?如果喜欢就看接下来的篇章,我会分享做这部分的原理及碰到的坑

补充,最近闲时一直有在更新这个api,发现有很多功能都没有,比如“视频合辑”后的vid play list一直找不到;电台播放缺失;播客没有;云村-关注没有等一系列都没有找到,在些补一下近来完善程序,很不错的一个api,再次感谢NeteaseCloudMusicApi,不打算再更新功能了,项多再完善其中的内容(找不到很想添加的,当然、前提是api不会再出新功能。)

Mad Score

Gif

music_player
music_player2
music_player3
music
playlist
playlist_cat_label
toplist
video
friends

Tree

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
app/src/main/java/com/xuie0000/netease/cloud/
├── data
│   ├── api
│   │   └── NeteaseApi.kt
│   ├── bean
│   │   ├── Account.kt
│   │   ├── Album.kt
│   │   ├── Al.kt
│   │   ├── All.kt
│   │   ├── Ar.kt
│   │   ├── Artist.kt
│   │   ├── ArtistToplist.kt
│   │   ├── ArtistX.kt
│   │   ├── AvatarDetail.kt
│   │   ├── BannerItem.kt
│   │   ├── Binding.kt
│   │   ├── Block.kt
│   │   ├── Button.kt
│   │   ├── Categories.kt
│   │   ├── ChargeInfo.kt
│   │   ├── ChargeInfoX.kt
│   │   ├── CommentSimpleData.kt
│   │   ├── Content.kt
│   │   ├── CreativeExtInfoVO.kt
│   │   ├── Creative.kt
│   │   ├── Creator.kt
│   │   ├── CreatorX.kt
│   │   ├── DailyRecommend.kt
│   │   ├── Data.kt
│   │   ├── DjRadio.kt
│   │   ├── ExtMonitorInfo.kt
│   │   ├── ExtMonitor.kt
│   │   ├── FreeTrialPrivilege.kt
│   │   ├── GuideToast.kt
│   │   ├── HistoryKeyword.kt
│   │   ├── H.kt
│   │   ├── Image.kt
│   │   ├── Klyric.kt
│   │   ├── L.kt
│   │   ├── Lrc.kt
│   │   ├── MainTitle.kt
│   │   ├── M.kt
│   │   ├── MlogBaseData.kt
│   │   ├── MlogExtVO.kt
│   │   ├── MLogUrl.kt
│   │   ├── Music.kt
│   │   ├── MvArtist.kt
│   │   ├── Mv.kt
│   │   ├── MvUrl.kt
│   │   ├── Operate.kt
│   │   ├── PageConfig.kt
│   │   ├── Playlist.kt
│   │   ├── PlaylistType.kt
│   │   ├── Privilege.kt
│   │   ├── Profile.kt
│   │   ├── ProfileX.kt
│   │   ├── Recommend.kt
│   │   ├── Resolution.kt
│   │   ├── ResourceExtInfo.kt
│   │   ├── Resource.kt
│   │   ├── ResourceX.kt
│   │   ├── ResourceXX.kt
│   │   ├── ResponseAlbum.kt
│   │   ├── ResponseBanner.kt
│   │   ├── ResponseDailyRecommend.kt
│   │   ├── ResponseHomePage.kt
│   │   ├── ResponseLogin.kt
│   │   ├── ResponseLoginStatus.kt
│   │   ├── ResponseLyric.kt
│   │   ├── ResponseMLogToVideo.kt
│   │   ├── ResponseMLogUrl.kt
│   │   ├── ResponseMvFirst.kt
│   │   ├── ResponseMvNetease.kt
│   │   ├── ResponseMvUrl.kt
│   │   ├── ResponseNormal.kt
│   │   ├── ResponsePlaylistCatlist.kt
│   │   ├── ResponsePlayListDetail.kt
│   │   ├── ResponseRecommendResource.kt
│   │   ├── ResponseRecommendSongs.kt
│   │   ├── ResponseSearchHotDetail.kt
│   │   ├── ResponseSearchHot.kt
│   │   ├── ResponseSearch.kt
│   │   ├── ResponseSongDetail.kt
│   │   ├── ResponseTopListDetail.kt
│   │   ├── ResponseTopList.kt
│   │   ├── ResponseTopPlaylistHighQuality.kt
│   │   ├── ResponseTopPlaylist.kt
│   │   ├── ResponseUserDetail.kt
│   │   ├── ResponseUserPlayList.kt
│   │   ├── ResponseVideoTimelineRecommend.kt
│   │   ├── ResponseVideoUrl.kt
│   │   ├── RewardToplist.kt
│   │   ├── ShareCover.kt
│   │   ├── ShowCover.kt
│   │   ├── SongData.kt
│   │   ├── Song.kt
│   │   ├── SongPrivilege.kt
│   │   ├── SongX.kt
│   │   ├── SubTitle.kt
│   │   ├── TailMark.kt
│   │   ├── Talk.kt
│   │   ├── Tlyric.kt
│   │   ├── TopList.kt
│   │   ├── TrackId.kt
│   │   ├── UiElement.kt
│   │   ├── UrlInfo.kt
│   │   ├── UrlInfoX.kt
│   │   ├── UserPoint.kt
│   │   ├── UserProfile.kt
│   │   ├── VideoBean.kt
│   │   ├── VideoGroup.kt
│   │   ├── VideoInfo.kt
│   │   ├── Video.kt
│   │   ├── VideoTimeline.kt
│   │   ├── VideoTimelineRecommend.kt
│   │   └── VideoUrl.kt
│   ├── Constants.kt
│   ├── datasource
│   │   ├── LyricSource.kt
│   │   └── NeteaseDatasource.kt
│   ├── db
│   │   ├── HistoryKeywordDao.kt
│   │   ├── NeteaseDatabase.kt
│   │   └── PlaylistTypeDao.kt
│   ├── di
│   │   ├── NetworkModule.kt
│   │   ├── PersistenceModule.kt
│   │   ├── RepositoryModule.kt
│   │   └── ServiceModule.kt
│   ├── network
│   │   ├── AddCookiesInterceptor.kt
│   │   └── AddUserAgentInterceptor.kt
│   ├── repository
│   │   ├── LyricRepository.kt
│   │   ├── mv
│   │   │   ├── InMemoryByItemMvRepository.kt
│   │   │   ├── InMemoryByItemVideoTimelineRepository.kt
│   │   │   ├── ItemMvPagingSource.kt
│   │   │   ├── ItemVideoTimelinePagingSource.kt
│   │   │   ├── MvRepository.kt
│   │   │   └── VideoTimelineRepository.kt
│   │   ├── NeteaseRepository.kt
│   │   └── playlist
│   │   ├── InMemoryByItemPlaylistHighQualityRepository.kt
│   │   ├── InMemoryByItemPlaylistRepository.kt
│   │   ├── ItemPlaylistHighQualityPagingSource.kt
│   │   ├── ItemPlaylistPagingSource.kt
│   │   ├── PlaylistHighQualityRepository.kt
│   │   └── PlaylistRepository.kt
│   └── Resource.kt
├── media
│   ├── CommandBundle.kt
│   ├── extensions
│   │   ├── FileExt.kt
│   │   ├── JavaLangExt.kt
│   │   ├── MediaMetadataCompatExt.kt
│   │   └── PlaybackStateCompatExt.kt
│   ├── library
│   │   ├── AlbumArtContentProvider.kt
│   │   ├── BrowseTree.kt
│   │   ├── JsonSource.kt
│   │   ├── LocalSource.kt
│   │   ├── MusicSource.kt
│   │   └── NeteaseSource.kt
│   ├── MediaItemData.kt
│   ├── MusicServiceConnection.kt
│   ├── MusicService.kt
│   ├── PackageValidator.kt
│   ├── PersistentStorage.kt
│   └── UampNotificationManager.kt
├── NeteaseApplication.kt
├── ui
│   ├── base
│   │   └── BaseActivity.kt
│   ├── broadcast
│   │   └── BroadcastFragment.kt
│   ├── daily
│   │   ├── RecommendSongsActivity.kt
│   │   └── RecommendSongsViewModel.kt
│   ├── discover
│   │   ├── adapter
│   │   │   ├── BannerViewHolder.kt
│   │   │   ├── child
│   │   │   │   ├── ChildBannerAdapter.kt
│   │   │   │   ├── ChildDailyRecommendAdapter.kt
│   │   │   │   ├── ChildMusicCalendarAdapter.kt
│   │   │   │   ├── ChildMusicMLogAdapter.kt
│   │   │   │   ├── ChildPlaylistAdapter.kt
│   │   │   │   ├── ChildPodcast24Adapter.kt
│   │   │   │   ├── ChildStyleRecommendAdapter.kt
│   │   │   │   └── ChildVideoListAdapter.kt
│   │   │   ├── CodeType.kt
│   │   │   ├── DailyRecommendViewHolder.kt
│   │   │   ├── DiscoverAdapter.kt
│   │   │   ├── DiscoverEmptyViewHolder.kt
│   │   │   ├── MusicCalendarViewHolder.kt
│   │   │   ├── MusicMLogViewHolder.kt
│   │   │   ├── NewAlbumSongViewHolder.kt
│   │   │   ├── PlaylistViewHolder.kt
│   │   │   ├── Podcast24ViewHolder.kt
│   │   │   ├── StyleRecommendViewHolder.kt
│   │   │   └── VideoListViewHolder.kt
│   │   ├── DiscoverFragment.kt
│   │   └── DiscoverViewModel.kt
│   ├── friends
│   │   ├── adapter
│   │   │   ├── FriendsMvAdapter.kt
│   │   │   ├── MvLoadStateAdapter.kt
│   │   │   ├── MvPagingAdapter.kt
│   │   │   ├── MvViewHolder.kt
│   │   │   └── NetworkStateItemViewHolder.kt
│   │   ├── FriendsFragment.kt
│   │   ├── FriendsMvFragment.kt
│   │   ├── FriendsMvViewModel.kt
│   │   ├── FriendsNeteaseFragment.kt
│   │   ├── FriendsNeteaseViewModel.kt
│   │   └── FriendsRecommendFragment.kt
│   ├── gallery
│   │   ├── GalleryFragment.kt
│   │   └── GalleryViewModel.kt
│   ├── karaoke
│   │   └── KaraokeFragment.kt
│   ├── login
│   │   ├── email
│   │   │   ├── LoginEmailFragment.kt
│   │   │   └── LoginEmailViewModel.kt
│   │   ├── LoginActivity.kt
│   │   ├── logout
│   │   │   ├── LogoutFragment.kt
│   │   │   └── LogoutViewModel.kt
│   │   └── welcome
│   │   └── LoginWelcomeFragment.kt
│   ├── main
│   │   ├── MainActivity.kt
│   │   └── MainViewModel.kt
│   ├── mlog
│   │   ├── MLogActivity.kt
│   │   ├── MLogFragment.kt
│   │   ├── MLogPagerAdapter.kt
│   │   └── MLogViewModel.kt
│   ├── music
│   │   ├── adapter
│   │   │   ├── MyAdapter.kt
│   │   │   └── UserPlaylistAdapter.kt
│   │   ├── MyFragment.kt
│   │   └── MyViewModel.kt
│   ├── mv
│   │   ├── MvActivity.kt
│   │   ├── MvFragment.kt
│   │   ├── MvPagerAdapter.kt
│   │   └── MvViewModel.kt
│   ├── player
│   │   ├── adapter
│   │   │   └── MusicListAdapter.kt
│   │   ├── MusicListFragment.kt
│   │   ├── MusicListViewModel.kt
│   │   ├── PlayerFragment.kt
│   │   └── PlayerViewModel.kt
│   ├── playlist
│   │   ├── adapter
│   │   │   ├── CatLabelAdapter.kt
│   │   │   ├── CatLabelItemAdapter.kt
│   │   │   ├── PlaylistDetailAdapter.kt
│   │   │   ├── PlaylistPagingAdapter.kt
│   │   │   ├── VideoListDetailAdapter.kt
│   │   │   └── VideoTimelinePagingAdapter.kt
│   │   ├── album
│   │   │   ├── AlbumActivity.kt
│   │   │   └── AlbumViewModel.kt
│   │   ├── cat
│   │   │   ├── CatLabelActivity.kt
│   │   │   └── CatLabelViewModel.kt
│   │   ├── detail
│   │   │   ├── PlaylistDetailActivity.kt
│   │   │   └── PlaylistDetailViewModel.kt
│   │   ├── PlaylistActivity.kt
│   │   ├── PlaylistFragment.kt
│   │   ├── PlaylistPagerAdapter.kt
│   │   ├── PlaylistViewModel.kt
│   │   ├── PlViewModel.kt
│   │   ├── VideoTimelineFragment.kt
│   │   └── VideoTimelineViewModel.kt
│   ├── search
│   │   ├── adapter
│   │   │   ├── child
│   │   │   │   ├── SearchChildAlbumAdapter.kt
│   │   │   │   ├── SearchChildArtistAdapter.kt
│   │   │   │   ├── SearchChildDjRadioAdapter.kt
│   │   │   │   ├── SearchChildPlayListAdapter.kt
│   │   │   │   ├── SearchChildSimQueryAdapter.kt
│   │   │   │   ├── SearchChildSongAdapter.kt
│   │   │   │   ├── SearchChildTalkAdapter.kt
│   │   │   │   ├── SearchChildUserAdapter.kt
│   │   │   │   └── SearchChildVideoAdapter.kt
│   │   │   ├── CustomSuggestionsAdapter.kt
│   │   │   ├── SearchAdapter.kt
│   │   │   ├── SearchAlbumViewHolder.kt
│   │   │   ├── SearchArtistViewHolder.kt
│   │   │   ├── SearchDjRadioViewHolder.kt
│   │   │   ├── SearchHistoryAdapter.kt
│   │   │   ├── SearchHotAdapter.kt
│   │   │   ├── SearchMLogViewHolder.kt
│   │   │   ├── SearchOrder.kt
│   │   │   ├── SearchPlayListViewHolder.kt
│   │   │   ├── SearchSimQueryViewHolder.kt
│   │   │   ├── SearchSongViewHolder.kt
│   │   │   ├── SearchTalkViewHolder.kt
│   │   │   ├── SearchUserViewHolder.kt
│   │   │   └── SearchVideoViewHolder.kt
│   │   ├── SearchActivity.kt
│   │   └── SearchViewModel.kt
│   ├── slideshow
│   │   ├── SlideshowFragment.kt
│   │   └── SlideshowViewModel.kt
│   ├── toplist
│   │   ├── adapter
│   │   │   ├── child
│   │   │   │   ├── ItemTopListChildNeteaseAdapter.kt
│   │   │   │   ├── TopListChildNeteaseAdapter.kt
│   │   │   │   └── TopListChildOtherAdapter.kt
│   │   │   ├── TopListAdapter.kt
│   │   │   ├── TopListNeteaseViewHolder.kt
│   │   │   └── TopListOtherViewHolder.kt
│   │   ├── TopListActivity.kt
│   │   └── TopListViewModel.kt
│   └── web
│   └── WebActivity.kt
├── util
│   ├── AccountExt.kt
│   ├── ActivityExt.kt
│   ├── BlurBitmap.kt
│   ├── ContextExt.kt
│   ├── DateExt.kt
│   ├── DpExt.kt
│   ├── FilesExt.kt
│   ├── MusicExt.kt
│   ├── NeteaseExt.kt
│   ├── PlaylistExt.kt
│   ├── ResponseExt.kt
│   └── TopListExt.kt
└── widget
├── AppBarStateChangeListener.kt
├── ClearableEditText.kt
├── DropDownHideBottomSheetBehavior.kt
├── FixedHeightBottomSheetDialog.kt
├── lrc
│   ├── LrcHelper.kt
│   ├── Lrc.kt
│   └── LrcView.kt
├── NestedScrollableHost.kt
├── ViewPager2Container.kt
└── WrapContentHeightViewPager.kt

Downloads

App预览下载 - 2021.6.24

文章作者: 二十I邊界
文章链接: https://xuie0000.com/post/2021-05-31-netease-app-design.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 二十I邊界