diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ab91825..ee6b35e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -56,6 +56,9 @@ dependencies { implementation("androidx.paging:paging-runtime-ktx:3.3.2") implementation("com.github.bumptech.glide:glide:4.16.0") + annotationProcessor("com.github.bumptech.glide:compiler:4.16.0") + // Glide 的图片变换库,包括高斯模糊 + implementation ("jp.wasabeef:glide-transformations:4.3.0") //提取图片主色 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 25c11bc..834c9e4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,13 +6,11 @@ - - + @@ -46,18 +47,13 @@ - - + android:exported="false"> - - - + android:exported="true"> - - - \ No newline at end of file diff --git a/app/src/main/java/com/hi/music/player/adapter/AdapterCategory.java b/app/src/main/java/com/hi/music/player/adapter/AdapterCategory.java index 4a5d1ac..1ab7395 100644 --- a/app/src/main/java/com/hi/music/player/adapter/AdapterCategory.java +++ b/app/src/main/java/com/hi/music/player/adapter/AdapterCategory.java @@ -2,6 +2,7 @@ package com.hi.music.player.adapter; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; @@ -57,12 +58,14 @@ public class AdapterCategory extends BaseAdapter { + + @Override + protected ItemCategoryListBinding getViewBinding(ViewGroup parent) { + return ItemCategoryListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + VHolder itemHolder = (VHolder) holder; + ResponseCategoryListChild child = data.get(position); + + ItemCategoryListBinding vb = itemHolder.getVb(); + vb.tvSongName.setText(child.getSongTitle()); + vb.tvSingerName.setText(child.getSingerName()); + + Glide.with(MusicApplication.myApplication) + .asDrawable() + .apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(16)))) + .load(child.getSongCovert()) + .placeholder(R.mipmap.ic_launcher) + .listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target target, boolean isFirstResource) { + CommonUtils.LogMsg(e.getMessage()); + return false; + } + + @OptIn(markerClass = UnstableApi.class) + @Override + public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target target, @NonNull DataSource dataSource, boolean isFirstResource) { + return false; + } + }) + .into(vb.image); + } + + +} diff --git a/app/src/main/java/com/hi/music/player/adapter/AdapterHome.java b/app/src/main/java/com/hi/music/player/adapter/AdapterHome.java index 176dba8..6c81a10 100644 --- a/app/src/main/java/com/hi/music/player/adapter/AdapterHome.java +++ b/app/src/main/java/com/hi/music/player/adapter/AdapterHome.java @@ -43,7 +43,7 @@ public class AdapterHome extends BaseAdapter vb.recyclerSinger.setVisibility(View.VISIBLE); CommonUtils.LogMsg("-----------singleList-=" + singleList.size()); AdapterSinger adapterSinger = new AdapterSinger(); - adapterSinger.setSingleClickSingerListener(singleClickSingerListener); + adapterSinger.setHomeItemClickListener(homeItemClickListener); adapterSinger.addData(singleList); vb.recyclerSinger.setLayoutManager(new GridLayoutManager(MusicApplication.myApplication, 4, RecyclerView.HORIZONTAL, false)); vb.recyclerSinger.setAdapter(adapterSinger); @@ -55,6 +55,7 @@ public class AdapterHome extends BaseAdapter vb.recyclerCategory.setVisibility(View.VISIBLE); CommonUtils.LogMsg("-----------categoryList-=" + categoryList.size()); AdapterCategory adapterCategory = new AdapterCategory(); + adapterCategory.setHomeItemClickListener(homeItemClickListener); adapterCategory.addData(categoryList); vb.recyclerCategory.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication, RecyclerView.HORIZONTAL, false)); vb.recyclerCategory.setAdapter(adapterCategory); diff --git a/app/src/main/java/com/hi/music/player/adapter/AdapterSinger.java b/app/src/main/java/com/hi/music/player/adapter/AdapterSinger.java index d23dbf8..3978fe1 100644 --- a/app/src/main/java/com/hi/music/player/adapter/AdapterSinger.java +++ b/app/src/main/java/com/hi/music/player/adapter/AdapterSinger.java @@ -61,8 +61,8 @@ public class AdapterSinger extends BaseAdapter extends RecyclerView - protected ClickSingerListener singleClickSingerListener; + protected HomeItemClickListener homeItemClickListener; - public void setSingleClickSingerListener(ClickSingerListener singleClickSingerListener) { - this.singleClickSingerListener = singleClickSingerListener; + + public void setHomeItemClickListener(HomeItemClickListener homeItemClickListener) { + this.homeItemClickListener = homeItemClickListener; } public void addData(List data) { diff --git a/app/src/main/java/com/hi/music/player/api/HomeItemClickListener.java b/app/src/main/java/com/hi/music/player/api/HomeItemClickListener.java new file mode 100644 index 0000000..4a03394 --- /dev/null +++ b/app/src/main/java/com/hi/music/player/api/HomeItemClickListener.java @@ -0,0 +1,11 @@ +package com.hi.music.player.api; + +import com.hi.music.player.javabean.response.child.ResponseCategory; +import com.hi.music.player.javabean.response.child.ResponseSingle; + +public interface HomeItemClickListener { + + void onClickItemSinger(ResponseSingle data) ; + + void onClickItemCategory(ResponseCategory data) ; +} diff --git a/app/src/main/java/com/hi/music/player/helper/CommonUtils.java b/app/src/main/java/com/hi/music/player/helper/CommonUtils.java index 317c177..dfedfb3 100644 --- a/app/src/main/java/com/hi/music/player/helper/CommonUtils.java +++ b/app/src/main/java/com/hi/music/player/helper/CommonUtils.java @@ -9,7 +9,9 @@ import android.graphics.drawable.GradientDrawable; import android.net.Uri; import android.util.DisplayMetrics; import android.util.Log; +import android.view.View; import android.widget.ImageView; +import android.widget.LinearLayout; import androidx.media3.common.MediaItem; import androidx.palette.graphics.Palette; @@ -170,7 +172,34 @@ public class CommonUtils { drawable.setCornerRadii(radii); return drawable; } + public static void extractColorsFromImage(Drawable drawable, View view) { + Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); + Palette.from(bitmap).generate(palette -> { + if (palette != null) { + // 获取主色 + int vibrantColor = palette.getVibrantColor(0); + int mutedColor = palette.getMutedColor(0); + + // 创建左右渐变色 + createGradientBackground(vibrantColor, mutedColor,view); + } + }); + } + + private static void createGradientBackground(int leftColor, int rightColor, View view) { + GradientDrawable gradientDrawable = new android.graphics.drawable.GradientDrawable( + android.graphics.drawable.GradientDrawable.Orientation.LEFT_RIGHT, + new int[]{leftColor, rightColor} + + ); + + + + + view.setBackground(gradientDrawable); + + } /** * 当前媒体项是否有有效的播放地址 diff --git a/app/src/main/java/com/hi/music/player/helper/MyValue.java b/app/src/main/java/com/hi/music/player/helper/MyValue.java index 10bffc0..ae1f557 100644 --- a/app/src/main/java/com/hi/music/player/helper/MyValue.java +++ b/app/src/main/java/com/hi/music/player/helper/MyValue.java @@ -16,4 +16,15 @@ public class MyValue { //-----------------------------PlayActivity + + + + + //-----------------------------CategoryListActivity + public static String KEY_PLAY_ACTIVITY_CATEGORY= "click_category"; + + + + + //-----------------------------CategoryListActivity } diff --git a/app/src/main/java/com/hi/music/player/javabean/requestbody/BodyHome.java b/app/src/main/java/com/hi/music/player/javabean/requestbody/BodyHome.java index 44ca69e..c565ebf 100644 --- a/app/src/main/java/com/hi/music/player/javabean/requestbody/BodyHome.java +++ b/app/src/main/java/com/hi/music/player/javabean/requestbody/BodyHome.java @@ -12,6 +12,15 @@ public class BodyHome implements Serializable { private String browseId = "FEmusic_home"; + + public String getBrowseId() { + return browseId; + } + + public void setBrowseId(String browseId) { + this.browseId = browseId; + } + private ContextBody context = new ContextBody(); public ContextBody getContext() { diff --git a/app/src/main/java/com/hi/music/player/javabean/response/ResponseCategoryList.java b/app/src/main/java/com/hi/music/player/javabean/response/ResponseCategoryList.java new file mode 100644 index 0000000..9cf07b2 --- /dev/null +++ b/app/src/main/java/com/hi/music/player/javabean/response/ResponseCategoryList.java @@ -0,0 +1,56 @@ +package com.hi.music.player.javabean.response; + +import com.hi.music.player.javabean.response.child.ResponseCategoryListChild; + +import java.util.List; + +public class ResponseCategoryList { + + private String covert; + private String title; + private String description; + private String secondSubtitle; + + private List list; + + + public String getCovert() { + return covert; + } + + public void setCovert(String covert) { + this.covert = covert; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getSecondSubtitle() { + return secondSubtitle; + } + + public void setSecondSubtitle(String secondSubtitle) { + this.secondSubtitle = secondSubtitle; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } +} diff --git a/app/src/main/java/com/hi/music/player/javabean/response/child/ResponseCategory.java b/app/src/main/java/com/hi/music/player/javabean/response/child/ResponseCategory.java index 049234c..d8d3a76 100644 --- a/app/src/main/java/com/hi/music/player/javabean/response/child/ResponseCategory.java +++ b/app/src/main/java/com/hi/music/player/javabean/response/child/ResponseCategory.java @@ -1,6 +1,8 @@ package com.hi.music.player.javabean.response.child; -public class ResponseCategory { +import java.io.Serializable; + +public class ResponseCategory implements Serializable { //类别封面 private String covert; @@ -11,6 +13,17 @@ public class ResponseCategory { private String twoSubtitle; + private String browseId; + + + public String getBrowseId() { + return browseId; + } + + public void setBrowseId(String browseId) { + this.browseId = browseId; + } + public String getCovert() { return covert; } diff --git a/app/src/main/java/com/hi/music/player/javabean/response/child/ResponseCategoryListChild.java b/app/src/main/java/com/hi/music/player/javabean/response/child/ResponseCategoryListChild.java new file mode 100644 index 0000000..f55cd89 --- /dev/null +++ b/app/src/main/java/com/hi/music/player/javabean/response/child/ResponseCategoryListChild.java @@ -0,0 +1,44 @@ +package com.hi.music.player.javabean.response.child; + +public class ResponseCategoryListChild { + private String SongTitle; + + private String SingerName; + + private String SongCovert; + + private String SongDuration; + + + public String getSongCovert() { + return SongCovert; + } + + public void setSongCovert(String songCovert) { + SongCovert = songCovert; + } + + public String getSongDuration() { + return SongDuration; + } + + public void setSongDuration(String songDuration) { + SongDuration = songDuration; + } + + public String getSongTitle() { + return SongTitle; + } + + public void setSongTitle(String songTitle) { + SongTitle = songTitle; + } + + public String getSingerName() { + return SingerName; + } + + public void setSingerName(String singerName) { + SingerName = singerName; + } +} diff --git a/app/src/main/java/com/hi/music/player/network/JsonHelper.java b/app/src/main/java/com/hi/music/player/network/JsonHelper.java index 2898e9d..8816ab1 100644 --- a/app/src/main/java/com/hi/music/player/network/JsonHelper.java +++ b/app/src/main/java/com/hi/music/player/network/JsonHelper.java @@ -1,10 +1,12 @@ package com.hi.music.player.network; import com.hi.music.player.helper.CommonUtils; +import com.hi.music.player.javabean.response.ResponseCategoryList; import com.hi.music.player.javabean.response.ResponsePlayListInfo; import com.hi.music.player.javabean.response.ResponsePlayUrl; import com.hi.music.player.javabean.response.child.ResponseCategory; import com.hi.music.player.javabean.response.ResponseHome; +import com.hi.music.player.javabean.response.child.ResponseCategoryListChild; import com.hi.music.player.javabean.response.child.ResponseHomeChild; import com.hi.music.player.javabean.response.child.ResponseSingle; @@ -22,7 +24,7 @@ public class JsonHelper { public static ResponseHome ResolveHomeJson(JSONObject jsonObject) { ResponseHome responseHome = new ResponseHome(); try { - String bgUrl = getJsonUrl(jsonObject.getJSONObject("background"),true); + String bgUrl = getJsonUrl(jsonObject.getJSONObject("background"), true); JSONObject sectionListRenderer = jsonObject.getJSONObject("contents").getJSONObject("singleColumnBrowseResultsRenderer").getJSONArray("tabs").getJSONObject(0).getJSONObject("tabRenderer").getJSONObject("content").getJSONObject("sectionListRenderer"); @@ -66,113 +68,6 @@ public class JsonHelper { return responseHome; } - private static void getCommonHome(JSONObject sectionListRenderer, ResponseHome responseHome) throws JSONException { - - - JSONObject nextContinuationData = sectionListRenderer.getJSONArray("continuations").getJSONObject(0).getJSONObject("nextContinuationData"); - - //token=continuation,cit= clickTrackingParams - - String clickTrackingParams = nextContinuationData.getString("clickTrackingParams"); - String continuation = nextContinuationData.getString("continuation"); - CommonUtils.LogMsg("---------参数---clickTrackingParams=" + clickTrackingParams); - CommonUtils.LogMsg("---------参数--continuation=" + continuation); - responseHome.setClickTrackingParams(clickTrackingParams); - responseHome.setContinuation(continuation); - - JSONArray contents = sectionListRenderer.getJSONArray("contents"); - - List childList = new ArrayList<>(); - - for (int i = 0; i < contents.length(); i++) { - ResponseHomeChild responseHomeChild = new ResponseHomeChild(); - JSONObject object = contents.getJSONObject(i); - - JSONObject musicCarouselShelfRenderer = object.optJSONObject("musicCarouselShelfRenderer"); - if (musicCarouselShelfRenderer != null) { - - //模块标题 - String title = getJsonTitle(musicCarouselShelfRenderer.getJSONObject("header").getJSONObject("musicCarouselShelfBasicHeaderRenderer").getJSONObject("title"), 0); - CommonUtils.LogMsg("----------headertitle=" + title); - responseHomeChild.setHeaderTitle(title); - JSONArray childContents = musicCarouselShelfRenderer.getJSONArray("contents"); - - - List categoryList = new ArrayList<>(); - List singleList = new ArrayList<>(); - for (int j = 0; j < childContents.length(); j++) { - JSONObject jsonList = childContents.getJSONObject(j); - JSONObject musicResponsiveListItemRenderer = jsonList.optJSONObject("musicResponsiveListItemRenderer"); - if (musicResponsiveListItemRenderer != null) { - ResponseSingle responseSingle = new ResponseSingle(); - - String SingerHead = getJsonUrl(musicResponsiveListItemRenderer.getJSONObject("thumbnail"),true); - - - JSONArray flexColumns = musicResponsiveListItemRenderer.getJSONArray("flexColumns"); - - //歌名、歌手名字、描述 - String SongTitle = ""; - String SingerName = ""; - String Description = ""; - for (int g = 0; g < flexColumns.length(); g++) { - JSONObject jsonObject = musicResponsiveListItemRenderer.getJSONArray("flexColumns").getJSONObject(g).getJSONObject("musicResponsiveListItemFlexColumnRenderer").getJSONObject("text"); - String text = getJsonTitle(jsonObject, 0); - if (g == 0) { - SongTitle = text; - - JSONObject runs = jsonObject.getJSONArray("runs").getJSONObject(0); - - String[] watchEndPoint = getWatchEndPoint(runs); - - responseSingle.setVideoId(watchEndPoint[0]); - responseSingle.setPlaylistId(watchEndPoint[1]); - responseSingle.setParams(watchEndPoint[2]); - responseSingle.setMusicVideoType(watchEndPoint[3]); - - } - if (g == 1) SingerName = text; - if (g == 2) Description = text; - } - responseSingle.setSongTitle(SongTitle); - responseSingle.setSingerName(SingerName); - responseSingle.setSingerHead(SingerHead); - responseSingle.setDescription(Description); - singleList.add(responseSingle); - CommonUtils.LogMsg(" ----------111111111111----SongTitle=" + SongTitle + "--SingerName=" + SingerName + "---Description=" + Description + "--SingerHead=" + SingerHead); - } - - JSONObject musicTwoRowItemRenderer = jsonList.optJSONObject("musicTwoRowItemRenderer"); - if (musicTwoRowItemRenderer != null) { - ResponseCategory responseCategory = new ResponseCategory(); - String covert = getJsonUrl(musicTwoRowItemRenderer.getJSONObject("thumbnailRenderer"),true); - - JSONObject title1 = musicTwoRowItemRenderer.getJSONObject("title"); - String twoTitle = getJsonTitle(title1, 0); - String twoSubtitle = getJsonTextNew(musicTwoRowItemRenderer.getJSONObject("subtitle")); -// String pageType = title1.getJSONObject("navigationEndpoint") -// .getJSONObject("browseEndpoint") -// .getJSONObject("browseEndpointContextSupportedConfigs") -// .getJSONObject("browseEndpointContextMusicConfig") -// .getString("pageType"); - - responseCategory.setCovert(covert); - responseCategory.setTwoTitle(twoTitle); - responseCategory.setTwoSubtitle(twoSubtitle); - categoryList.add(responseCategory); - CommonUtils.LogMsg(" ----------2222222222----twoTitle=" + twoTitle + "-twoSubtitle=" + twoSubtitle); - } - - } - responseHomeChild.setCategoryList(categoryList); - responseHomeChild.setSingleList(singleList); - } - childList.add(responseHomeChild); - } - responseHome.setChildList(childList); - - - } public static List ResolvePlayListJson(JSONObject jsonObject) { List list = new ArrayList<>(); @@ -185,7 +80,7 @@ public class JsonHelper { ResponsePlayListInfo responsePlayListInfo = new ResponsePlayListInfo(); JSONObject playlistPanelVideoRenderer = contents.getJSONObject(i).getJSONObject("playlistPanelVideoRenderer"); - String maxUrl = getJsonUrl(playlistPanelVideoRenderer,true); + String maxUrl = getJsonUrl(playlistPanelVideoRenderer, true); String smallUrl = getJsonUrl(playlistPanelVideoRenderer, false); @@ -273,6 +168,236 @@ public class JsonHelper { } + + + + public static ResponseCategoryList ResolveCategoryList(JSONObject jsonObject) { + try { + ResponseCategoryList responseCategoryList = new ResponseCategoryList(); + JSONObject jsonObject1 = jsonObject.getJSONObject("contents") + .getJSONObject("twoColumnBrowseResultsRenderer"); + JSONObject musicResponsiveHeaderRenderer = jsonObject1 + .getJSONArray("tabs") + .getJSONObject(0) + .getJSONObject("tabRenderer") + .getJSONObject("content") + .getJSONObject("sectionListRenderer") + .getJSONArray("contents") + .getJSONObject(0) + .getJSONObject("musicResponsiveHeaderRenderer"); + + //封面图 + String covert = getJsonUrl(musicResponsiveHeaderRenderer.getJSONObject("thumbnail") + .getJSONObject("musicThumbnailRenderer"), true); + + + //轻松愉悦的经典摇滚乐 + String title = getJsonTitle(musicResponsiveHeaderRenderer.getJSONObject("title"), 0); + + //Hold on to the feeling. + String description = getJsonTitle(musicResponsiveHeaderRenderer.getJSONObject("description") + .getJSONObject("musicDescriptionShelfRenderer") + .getJSONObject("description"), 0); + + //110 首歌曲.超过6小时 + String secondSubtitle = getJsonTextNew(musicResponsiveHeaderRenderer.getJSONObject("secondSubtitle")); + + CommonUtils.LogMsg("-------------title="+title+"--description="+description+"---secondSubtitle="+secondSubtitle+"---covert="+covert); + + JSONArray jsonArray = jsonObject1.getJSONObject("secondaryContents") + .getJSONObject("sectionListRenderer") + .getJSONArray("contents") + .getJSONObject(0) + .getJSONObject("musicPlaylistShelfRenderer") + .getJSONArray("contents"); + + responseCategoryList.setCovert(covert); + responseCategoryList.setDescription(description); + responseCategoryList.setTitle(title); + responseCategoryList.setSecondSubtitle(secondSubtitle); + List mList = new ArrayList<>(); + for(int i = 0;i childList = new ArrayList<>(); + + for (int i = 0; i < contents.length(); i++) { + ResponseHomeChild responseHomeChild = new ResponseHomeChild(); + JSONObject object = contents.getJSONObject(i); + + JSONObject musicCarouselShelfRenderer = object.optJSONObject("musicCarouselShelfRenderer"); + if (musicCarouselShelfRenderer != null) { + + //模块标题 + String title = getJsonTitle(musicCarouselShelfRenderer.getJSONObject("header").getJSONObject("musicCarouselShelfBasicHeaderRenderer").getJSONObject("title"), 0); + CommonUtils.LogMsg("----------headertitle=" + title); + responseHomeChild.setHeaderTitle(title); + JSONArray childContents = musicCarouselShelfRenderer.getJSONArray("contents"); + + + List categoryList = new ArrayList<>(); + List singleList = new ArrayList<>(); + for (int j = 0; j < childContents.length(); j++) { + JSONObject jsonList = childContents.getJSONObject(j); + JSONObject musicResponsiveListItemRenderer = jsonList.optJSONObject("musicResponsiveListItemRenderer"); + if (musicResponsiveListItemRenderer != null) { + ResponseSingle responseSingle = new ResponseSingle(); + + String SingerHead = getJsonUrl(musicResponsiveListItemRenderer.getJSONObject("thumbnail"), true); + + + JSONArray flexColumns = musicResponsiveListItemRenderer.getJSONArray("flexColumns"); + + //歌名、歌手名字、描述 + String SongTitle = ""; + String SingerName = ""; + String Description = ""; + for (int g = 0; g < flexColumns.length(); g++) { + JSONObject jsonObject = flexColumns.getJSONObject(g).getJSONObject("musicResponsiveListItemFlexColumnRenderer").getJSONObject("text"); + String text = getJsonTitle(jsonObject, 0); + if (g == 0) { + SongTitle = text; + + JSONObject runs = jsonObject.getJSONArray("runs").getJSONObject(0); + + String[] watchEndPoint = getWatchEndPoint(runs); + + responseSingle.setVideoId(watchEndPoint[0]); + responseSingle.setPlaylistId(watchEndPoint[1]); + responseSingle.setParams(watchEndPoint[2]); + responseSingle.setMusicVideoType(watchEndPoint[3]); + + } + if (g == 1) SingerName = text; + if (g == 2) Description = text; + } + responseSingle.setSongTitle(SongTitle); + responseSingle.setSingerName(SingerName); + responseSingle.setSingerHead(SingerHead); + responseSingle.setDescription(Description); + singleList.add(responseSingle); + CommonUtils.LogMsg(" ----------111111111111----SongTitle=" + SongTitle + "--SingerName=" + SingerName + "---Description=" + Description + "--SingerHead=" + SingerHead); + } + + JSONObject musicTwoRowItemRenderer = jsonList.optJSONObject("musicTwoRowItemRenderer"); + if (musicTwoRowItemRenderer != null) { + ResponseCategory responseCategory = new ResponseCategory(); + String covert = getJsonUrl(musicTwoRowItemRenderer.getJSONObject("thumbnailRenderer"), true); + + JSONObject title1 = musicTwoRowItemRenderer.getJSONObject("title"); + String twoTitle = getJsonTitle(title1, 0); + String twoSubtitle = getJsonTextNew(musicTwoRowItemRenderer.getJSONObject("subtitle")); + + String browseId = title1 + .getJSONArray("runs") + .getJSONObject(0) + .getJSONObject("navigationEndpoint") + .getJSONObject("browseEndpoint") + .getString("browseId"); + + + responseCategory.setBrowseId(browseId); + responseCategory.setCovert(covert); + responseCategory.setTwoTitle(twoTitle); + responseCategory.setTwoSubtitle(twoSubtitle); + categoryList.add(responseCategory); + CommonUtils.LogMsg(" ----------2222222222----twoTitle=" + twoTitle + "-twoSubtitle=" + twoSubtitle); + } + + } + responseHomeChild.setCategoryList(categoryList); + responseHomeChild.setSingleList(singleList); + } + childList.add(responseHomeChild); + } + responseHome.setChildList(childList); + + + } + + + + private static String[] getWatchEndPoint(JSONObject job) { String[] strings = new String[4]; @@ -303,14 +428,12 @@ public class JsonHelper { } - /** - * * @param jsonObject - * @param maxBig 是否取最大的一张图片 + * @param maxBig 是否取最大的一张图片 * @return */ - private static String getJsonUrl(JSONObject jsonObject,boolean maxBig) { + private static String getJsonUrl(JSONObject jsonObject, boolean maxBig) { try { boolean b = jsonObject.has("musicThumbnailRenderer"); if (b) { @@ -318,9 +441,9 @@ public class JsonHelper { } JSONArray jsonArray = jsonObject.getJSONObject("thumbnail").getJSONArray("thumbnails"); int length = jsonArray.length(); - int index = 3; - if(maxBig){ - index = length - 1; + int index = 0; + if (maxBig) { + index = length - 1; } String pngUrl = jsonArray.getJSONObject(index).getString("url"); @@ -346,6 +469,11 @@ public class JsonHelper { } + /** + * runs 数组的字符串拼接 + * @param jsonObject + * @return + */ private static String getJsonTextNew(JSONObject jsonObject) { StringBuilder text = new StringBuilder(); try { diff --git a/app/src/main/java/com/hi/music/player/network/MusicApi.java b/app/src/main/java/com/hi/music/player/network/MusicApi.java index 42951cb..93518fc 100644 --- a/app/src/main/java/com/hi/music/player/network/MusicApi.java +++ b/app/src/main/java/com/hi/music/player/network/MusicApi.java @@ -42,7 +42,7 @@ public interface MusicApi { - + //获取播放音频资源url @POST("youtubei/v1/player?prettyPrint=false") @Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8", "X-Goog-FieldMask:playabilityStatus.status,playerConfig.audioConfig,streamingData.adaptiveFormats,videoDetails.videoId"}) @@ -53,4 +53,11 @@ public interface MusicApi { @GET("videoplayback?expire=1727100941&ei=rSPxZoSXJ_eM2_gPgqT8mAs&ip=146.19.167.8&id=o-ADGacaLEhb3NOOc74tfR50VCTKy0vnUb2_GAm-tPlv9n&itag=137&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&mh=f8&mm=31%2C29&mn=sn-tt1e7nlz%2Csn-vgqsknzd&ms=au%2Crdu&mv=m&mvi=2&pl=24&gcr=us&initcwndbps=6450000&vprv=1&svpuc=1&mime=video%2Fmp4&rqh=1&gir=yes&clen=4444925&dur=293.280&lmt=1688643558849956&mt=1727078942&fvip=3&keepalive=yes&fexp=51299152&c=ANDROID_MUSIC&txp=4532434&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cgcr%2Cvprv%2Csvpuc%2Cmime%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRgIhAKjjifMN7NMLqeoVXyqHPK1uHqev1PcnVMoycknt4QGfAiEAiCEcEYPDpQsCbE0tJ6MXjvPs4HmT0yM8Yoa26rWpc7M%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=ABPmVW0wRAIgeur5lMiKDgdWV5rrRTkmt0jbOQnifmVQwoTXk_Y17E0CIBfjGXpbdW2u3mtu1I-") Observable getTest(); + + + //首页分类项下的播放列表子页面 + @POST("youtubei/v1/browse") + @Headers("X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8") + Observable getCategoryList(@Body RequestBody requestBody); + } diff --git a/app/src/main/java/com/hi/music/player/network/RetrofitManager.java b/app/src/main/java/com/hi/music/player/network/RetrofitManager.java index a64f8c8..17348c5 100644 --- a/app/src/main/java/com/hi/music/player/network/RetrofitManager.java +++ b/app/src/main/java/com/hi/music/player/network/RetrofitManager.java @@ -150,4 +150,18 @@ public class RetrofitManager { + public void getCategoryList(String browserId,RequestListener requestListener) { + BodyHome bodyHome = new BodyHome(); + bodyHome.setBrowseId(browserId); + Gson gson = new Gson(); + String s = gson.toJson(bodyHome); + RequestBody requestBody = RequestBody.Companion.create(s, JSON); + musicApi.getCategoryList(requestBody) + .subscribeOn(Schedulers.io()) + .unsubscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new ObserverWrapper(requestListener)); + } + + } diff --git a/app/src/main/java/com/hi/music/player/ui/activity/CategoryListActivity.java b/app/src/main/java/com/hi/music/player/ui/activity/CategoryListActivity.java new file mode 100644 index 0000000..ed30307 --- /dev/null +++ b/app/src/main/java/com/hi/music/player/ui/activity/CategoryListActivity.java @@ -0,0 +1,178 @@ +package com.hi.music.player.ui.activity; + +import static com.bumptech.glide.request.RequestOptions.bitmapTransform; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.OptIn; +import androidx.appcompat.app.AppCompatActivity; +import androidx.lifecycle.Observer; +import androidx.media3.common.util.UnstableApi; +import androidx.recyclerview.widget.LinearLayoutManager; + +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.os.Bundle; +import android.view.View; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.load.resource.bitmap.BitmapTransitionOptions; +import com.bumptech.glide.load.resource.bitmap.RoundedCorners; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.Target; +import com.hi.music.player.MusicApplication; +import com.hi.music.player.R; +import com.hi.music.player.adapter.AdapterCategoryList; +import com.hi.music.player.api.onImageColorListener; +import com.hi.music.player.databinding.ActivityCategoryListBinding; +import com.hi.music.player.databinding.ActivityHomeBinding; +import com.hi.music.player.helper.CommonUtils; +import com.hi.music.player.helper.MyValue; +import com.hi.music.player.javabean.response.ResponseCategoryList; +import com.hi.music.player.javabean.response.child.ResponseCategory; +import com.hi.music.player.ui.fragmnt.viewmodel.VMCategoryList; +import com.hi.music.player.ui.fragmnt.viewmodel.VMHome; + +import java.io.Serializable; + +import jp.wasabeef.glide.transformations.BlurTransformation; + +public class CategoryListActivity extends BaseActivity { + + + private VMCategoryList vm; + + @Override + protected ActivityCategoryListBinding getViewBinding() { + return ActivityCategoryListBinding.inflate(getLayoutInflater()); + } + + @Override + protected void onCreateInit() { + vm = getActivityScopeViewModel(VMCategoryList.class); + Intent intent = getIntent(); + if (intent == null) { + + return; + } + + if (!intent.hasExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY)) { + + return; + } + ResponseCategory category = (ResponseCategory) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY); + if (category == null) + return; + vb.pbLoading.setVisibility(View.VISIBLE); + vm.getList(category.getBrowseId()); + vm.data.observe(this, new Observer() { + @Override + public void onChanged(ResponseCategoryList responseCategoryList) { + if (responseCategoryList == null) { + + return; + } + + loadInfo(responseCategoryList); + + } + }); + } + + @Override + protected void onInitClick() { + vb.imBack.setOnClickListener(this); + } + + @Override + public boolean isFullScreen() { + return true; + } + + @Override + public boolean statusBarLight() { + return false; + } + + @Override + public void onClick(View v) { + if (v.equals(vb.imBack)) { + finish(); + } + + + } + + private void loadInfo(ResponseCategoryList info) { + vb.tvTitle.setText(info.getTitle()); + vb.tvSubTitle.setText(info.getSecondSubtitle()); + + AdapterCategoryList adapterCategoryList = new AdapterCategoryList(); + vb.recyclerview.setLayoutManager(new LinearLayoutManager(this)); + adapterCategoryList.setData(info.getList()); + vb.recyclerview.setAdapter(adapterCategoryList); + + loadCovert(info.getCovert()); + + } + + + private void loadCovert(String url) { + // 加载图片并应用高斯模糊效果 + Glide.with(this) + .load(url) + .apply(bitmapTransform(new BlurTransformation(25, 3))) // 设置模糊半径和模糊采样 + .listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target target, @NonNull DataSource dataSource, boolean isFirstResource) { + +// CommonUtils.extractColorsFromImage(resource,vb.imBg); + return false; + } + }) + .preload(); + + + Glide.with(MusicApplication.myApplication) + .asDrawable() + .apply(bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(10)))) + .load(url) + .placeholder(R.mipmap.ic_launcher) + .listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target target, boolean isFirstResource) { + CommonUtils.LogMsg(e.getMessage()); + vb.pbLoading.setVisibility(View.GONE); + return false; + } + + @OptIn(markerClass = UnstableApi.class) + @Override + public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target target, @NonNull DataSource dataSource, boolean isFirstResource) { +// CommonUtils.getDominantDarkColor1(resource, new onImageColorListener() { +// @Override +// public void onImageColor(int color) { +// if (color == -1) { +// return; +// } +// +// } +// }); + vb.pbLoading.setVisibility(View.GONE); + return false; + } + }) + .into(vb.imCovert); + + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/hi/music/player/ui/activity/PlayActivity.java b/app/src/main/java/com/hi/music/player/ui/activity/PlayActivity.java index f56e94c..b7f06bb 100644 --- a/app/src/main/java/com/hi/music/player/ui/activity/PlayActivity.java +++ b/app/src/main/java/com/hi/music/player/ui/activity/PlayActivity.java @@ -91,6 +91,7 @@ public class PlayActivity extends BaseActivity implements S responseSingle = (ResponseSingle) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER); vmPlay = getActivityScopeViewModel(VMPlay.class); initMediaController(); + vb.progressBarLoading.setVisibility(View.VISIBLE); vmPlay.getPlayMusicList(responseSingle); initPlayerView(); @@ -108,7 +109,6 @@ public class PlayActivity extends BaseActivity implements S if (playList.size() > 0) { mPlayList = playList; musicInfo = playList.get(0); - } } diff --git a/app/src/main/java/com/hi/music/player/ui/fragmnt/HomeFragment.java b/app/src/main/java/com/hi/music/player/ui/fragmnt/HomeFragment.java index 0ac1491..a1b520c 100644 --- a/app/src/main/java/com/hi/music/player/ui/fragmnt/HomeFragment.java +++ b/app/src/main/java/com/hi/music/player/ui/fragmnt/HomeFragment.java @@ -1,6 +1,7 @@ package com.hi.music.player.ui.fragmnt; import android.content.Intent; +import android.content.RestrictionsManager; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; @@ -9,24 +10,33 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.hi.music.player.adapter.AdapterHome; -import com.hi.music.player.api.ClickSingerListener; +import com.hi.music.player.api.HomeItemClickListener; +import com.hi.music.player.api.OnHasUrlAction; +import com.hi.music.player.api.RequestListener; import com.hi.music.player.databinding.FragmentHomeBinding; import com.hi.music.player.helper.CommonUtils; import com.hi.music.player.helper.MyValue; import com.hi.music.player.javabean.response.ResponseHome; +import com.hi.music.player.javabean.response.child.ResponseCategory; import com.hi.music.player.javabean.response.child.ResponseHomeChild; import com.hi.music.player.javabean.response.child.ResponseSingle; +import com.hi.music.player.network.RetrofitManager; +import com.hi.music.player.ui.activity.CategoryListActivity; import com.hi.music.player.ui.activity.PlayActivity; import com.hi.music.player.ui.fragmnt.viewmodel.VMHome; +import org.json.JSONObject; + import java.util.ArrayList; import java.util.List; -public class HomeFragment extends BaseFragment implements ClickSingerListener { +import okhttp3.ResponseBody; + +public class HomeFragment extends BaseFragment implements HomeItemClickListener { private VMHome vmHome; - private AdapterHome adapterHome; + private int requestCount = 1; @@ -47,7 +57,8 @@ public class HomeFragment extends BaseFragment implements C // //标题导航栏颜色设置 // Vb.toolbar.setTitleTextColor(getResources().getColor(R.color.white)); AdapterHome adapterHome = new AdapterHome(); - adapterHome.setSingleClickSingerListener(this::onClickSingerItem); + adapterHome.setHomeItemClickListener(this); + vmHome = getFragmentScopeViewModel(VMHome.class); adapterHome.addLoadingFooter(); @@ -87,15 +98,24 @@ public class HomeFragment extends BaseFragment implements C } + @Override - public void onClickSingerItem(ResponseSingle data) { + public void onClickItemSinger(ResponseSingle data) { FragmentActivity activity = getActivity(); if(activity!= null){ Intent intent = new Intent(activity, PlayActivity.class); intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, data); startActivity(intent); } + } - + @Override + public void onClickItemCategory(ResponseCategory data) { + FragmentActivity activity = getActivity(); + if(activity!= null){ + Intent intent = new Intent(activity, CategoryListActivity.class); + intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY, data); + startActivity(intent); + } } } diff --git a/app/src/main/java/com/hi/music/player/ui/fragmnt/viewmodel/VMCategoryList.java b/app/src/main/java/com/hi/music/player/ui/fragmnt/viewmodel/VMCategoryList.java new file mode 100644 index 0000000..e5e061a --- /dev/null +++ b/app/src/main/java/com/hi/music/player/ui/fragmnt/viewmodel/VMCategoryList.java @@ -0,0 +1,48 @@ +package com.hi.music.player.ui.fragmnt.viewmodel; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +import com.hi.music.player.api.RequestListener; +import com.hi.music.player.helper.CommonUtils; +import com.hi.music.player.javabean.response.ResponseCategoryList; +import com.hi.music.player.javabean.response.ResponseHome; +import com.hi.music.player.javabean.response.ResponsePlayUrl; +import com.hi.music.player.network.JsonHelper; +import com.hi.music.player.network.RetrofitManager; + +import org.json.JSONObject; + +import okhttp3.ResponseBody; + +public class VMCategoryList extends ViewModel { + + + private MutableLiveData _data = new MutableLiveData<>(); + public LiveData data = _data; + + + public void getList(String browseId) { + + RetrofitManager.getInstance().getCategoryList(browseId, new RequestListener() { + @Override + public void onFail(String errorMsg) { + _data.setValue(null); + } + + @Override + public void onSuccess(ResponseBody data) { + JSONObject jsonObject = CommonUtils.toJsonObject(data); + if (jsonObject != null) { + ResponseCategoryList responseCategoryList = JsonHelper.ResolveCategoryList(jsonObject); + _data.setValue(responseCategoryList); + } + } + }); + + + } + + +} diff --git a/app/src/main/res/layout/activity_category_list.xml b/app/src/main/res/layout/activity_category_list.xml new file mode 100644 index 0000000..f0635d2 --- /dev/null +++ b/app/src/main/res/layout/activity_category_list.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_category_list.xml b/app/src/main/res/layout/item_category_list.xml new file mode 100644 index 0000000..aa8fe1f --- /dev/null +++ b/app/src/main/res/layout/item_category_list.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 4b24ff9..876f5f0 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -3,6 +3,7 @@