增加分类音乐合集列表页面
This commit is contained in:
parent
8f913bdac7
commit
186ac6b208
@ -56,6 +56,9 @@ dependencies {
|
|||||||
implementation("androidx.paging:paging-runtime-ktx:3.3.2")
|
implementation("androidx.paging:paging-runtime-ktx:3.3.2")
|
||||||
|
|
||||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
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")
|
||||||
|
|
||||||
|
|
||||||
//提取图片主色
|
//提取图片主色
|
||||||
|
|||||||
@ -6,13 +6,11 @@
|
|||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="32" />
|
android:maxSdkVersion="32" />
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MusicApplication"
|
android:name=".MusicApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@ -24,6 +22,9 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.MusicApp"
|
android:theme="@style/Theme.MusicApp"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
|
<activity
|
||||||
|
android:name=".ui.activity.CategoryListActivity"
|
||||||
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.A_PlayActivity"
|
android:name=".ui.activity.A_PlayActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
@ -46,18 +47,13 @@
|
|||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.A_HomeActivity"
|
android:name=".ui.activity.A_HomeActivity"
|
||||||
android:exported="false">
|
android:exported="false"></activity>
|
||||||
|
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.MainActivity"
|
android:name=".ui.activity.MainActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.A_SplashActivity"
|
android:name=".ui.activity.A_SplashActivity"
|
||||||
android:exported="true">
|
android:exported="true"></activity>
|
||||||
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".media3.PlaybackService"
|
android:name=".media3.PlaybackService"
|
||||||
@ -67,14 +63,11 @@
|
|||||||
<action android:name="androidx.media3.session.MediaSessionService" />
|
<action android:name="androidx.media3.session.MediaSessionService" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".service.MusicPlayerForegroundService"
|
android:name=".service.MusicPlayerForegroundService"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:foregroundServiceType="mediaPlayback" />
|
android:foregroundServiceType="mediaPlayback" />
|
||||||
|
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@ -2,6 +2,7 @@ package com.hi.music.player.adapter;
|
|||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@ -57,12 +58,14 @@ public class AdapterCategory extends BaseAdapter<ResponseCategory, ItemCategoryB
|
|||||||
.into(vb.header);
|
.into(vb.header);
|
||||||
vb.tvTitle.setText(responseCategory.getTwoTitle());
|
vb.tvTitle.setText(responseCategory.getTwoTitle());
|
||||||
vb.tvSubtitle.setText(responseCategory.getTwoSubtitle());
|
vb.tvSubtitle.setText(responseCategory.getTwoSubtitle());
|
||||||
|
vb.header.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (homeItemClickListener != null) {
|
||||||
|
homeItemClickListener.onClickItemCategory(responseCategory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,67 @@
|
|||||||
|
package com.hi.music.player.adapter;
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.OptIn;
|
||||||
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
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.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.api.onImageColorListener;
|
||||||
|
import com.hi.music.player.databinding.ItemCategoryListBinding;
|
||||||
|
import com.hi.music.player.databinding.ItemSingerBinding;
|
||||||
|
import com.hi.music.player.helper.CommonUtils;
|
||||||
|
import com.hi.music.player.javabean.response.child.ResponseCategoryListChild;
|
||||||
|
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
||||||
|
|
||||||
|
public class AdapterCategoryList extends BaseAdapter<ResponseCategoryListChild, ItemCategoryListBinding> {
|
||||||
|
|
||||||
|
@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<ItemCategoryListBinding> itemHolder = (VHolder<ItemCategoryListBinding>) 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<Drawable>() {
|
||||||
|
@Override
|
||||||
|
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
||||||
|
CommonUtils.LogMsg(e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(markerClass = UnstableApi.class)
|
||||||
|
@Override
|
||||||
|
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into(vb.image);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -43,7 +43,7 @@ public class AdapterHome extends BaseAdapter<ResponseHomeChild, ItemHomeBinding>
|
|||||||
vb.recyclerSinger.setVisibility(View.VISIBLE);
|
vb.recyclerSinger.setVisibility(View.VISIBLE);
|
||||||
CommonUtils.LogMsg("-----------singleList-=" + singleList.size());
|
CommonUtils.LogMsg("-----------singleList-=" + singleList.size());
|
||||||
AdapterSinger adapterSinger = new AdapterSinger();
|
AdapterSinger adapterSinger = new AdapterSinger();
|
||||||
adapterSinger.setSingleClickSingerListener(singleClickSingerListener);
|
adapterSinger.setHomeItemClickListener(homeItemClickListener);
|
||||||
adapterSinger.addData(singleList);
|
adapterSinger.addData(singleList);
|
||||||
vb.recyclerSinger.setLayoutManager(new GridLayoutManager(MusicApplication.myApplication, 4, RecyclerView.HORIZONTAL, false));
|
vb.recyclerSinger.setLayoutManager(new GridLayoutManager(MusicApplication.myApplication, 4, RecyclerView.HORIZONTAL, false));
|
||||||
vb.recyclerSinger.setAdapter(adapterSinger);
|
vb.recyclerSinger.setAdapter(adapterSinger);
|
||||||
@ -55,6 +55,7 @@ public class AdapterHome extends BaseAdapter<ResponseHomeChild, ItemHomeBinding>
|
|||||||
vb.recyclerCategory.setVisibility(View.VISIBLE);
|
vb.recyclerCategory.setVisibility(View.VISIBLE);
|
||||||
CommonUtils.LogMsg("-----------categoryList-=" + categoryList.size());
|
CommonUtils.LogMsg("-----------categoryList-=" + categoryList.size());
|
||||||
AdapterCategory adapterCategory = new AdapterCategory();
|
AdapterCategory adapterCategory = new AdapterCategory();
|
||||||
|
adapterCategory.setHomeItemClickListener(homeItemClickListener);
|
||||||
adapterCategory.addData(categoryList);
|
adapterCategory.addData(categoryList);
|
||||||
vb.recyclerCategory.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication, RecyclerView.HORIZONTAL, false));
|
vb.recyclerCategory.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication, RecyclerView.HORIZONTAL, false));
|
||||||
vb.recyclerCategory.setAdapter(adapterCategory);
|
vb.recyclerCategory.setAdapter(adapterCategory);
|
||||||
|
|||||||
@ -61,8 +61,8 @@ public class AdapterSinger extends BaseAdapter<ResponseSingle, ItemSingerBinding
|
|||||||
vb.getRoot().setOnClickListener(new View.OnClickListener() {
|
vb.getRoot().setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (singleClickSingerListener != null) {
|
if (homeItemClickListener != null) {
|
||||||
singleClickSingerListener.onClickSingerItem(responseSingle);
|
homeItemClickListener.onClickItemSinger(responseSingle);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,8 +7,9 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.viewbinding.ViewBinding;
|
import androidx.viewbinding.ViewBinding;
|
||||||
|
|
||||||
import com.hi.music.player.api.ClickSingerListener;
|
import com.hi.music.player.api.HomeItemClickListener;
|
||||||
import com.hi.music.player.databinding.ItemFooterLoadingBinding;
|
import com.hi.music.player.databinding.ItemFooterLoadingBinding;
|
||||||
|
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -24,10 +25,11 @@ abstract public class BaseAdapter<K, T extends ViewBinding> extends RecyclerView
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected ClickSingerListener<ResponseSingle> singleClickSingerListener;
|
protected HomeItemClickListener homeItemClickListener;
|
||||||
|
|
||||||
public void setSingleClickSingerListener(ClickSingerListener<ResponseSingle> singleClickSingerListener) {
|
|
||||||
this.singleClickSingerListener = singleClickSingerListener;
|
public void setHomeItemClickListener(HomeItemClickListener homeItemClickListener) {
|
||||||
|
this.homeItemClickListener = homeItemClickListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addData(List<K> data) {
|
public void addData(List<K> data) {
|
||||||
|
|||||||
@ -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) ;
|
||||||
|
}
|
||||||
@ -9,7 +9,9 @@ import android.graphics.drawable.GradientDrawable;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.palette.graphics.Palette;
|
import androidx.palette.graphics.Palette;
|
||||||
@ -170,7 +172,34 @@ public class CommonUtils {
|
|||||||
drawable.setCornerRadii(radii);
|
drawable.setCornerRadii(radii);
|
||||||
return drawable;
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前媒体项是否有有效的播放地址
|
* 当前媒体项是否有有效的播放地址
|
||||||
|
|||||||
@ -16,4 +16,15 @@ public class MyValue {
|
|||||||
|
|
||||||
|
|
||||||
//-----------------------------PlayActivity
|
//-----------------------------PlayActivity
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------CategoryListActivity
|
||||||
|
public static String KEY_PLAY_ACTIVITY_CATEGORY= "click_category";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------CategoryListActivity
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,15 @@ public class BodyHome implements Serializable {
|
|||||||
|
|
||||||
private String browseId = "FEmusic_home";
|
private String browseId = "FEmusic_home";
|
||||||
|
|
||||||
|
|
||||||
|
public String getBrowseId() {
|
||||||
|
return browseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrowseId(String browseId) {
|
||||||
|
this.browseId = browseId;
|
||||||
|
}
|
||||||
|
|
||||||
private ContextBody context = new ContextBody();
|
private ContextBody context = new ContextBody();
|
||||||
|
|
||||||
public ContextBody getContext() {
|
public ContextBody getContext() {
|
||||||
|
|||||||
@ -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<ResponseCategoryListChild> 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<ResponseCategoryListChild> getList() {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setList(List<ResponseCategoryListChild> list) {
|
||||||
|
this.list = list;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,8 @@
|
|||||||
package com.hi.music.player.javabean.response.child;
|
package com.hi.music.player.javabean.response.child;
|
||||||
|
|
||||||
public class ResponseCategory {
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class ResponseCategory implements Serializable {
|
||||||
|
|
||||||
//类别封面
|
//类别封面
|
||||||
private String covert;
|
private String covert;
|
||||||
@ -11,6 +13,17 @@ public class ResponseCategory {
|
|||||||
private String twoSubtitle;
|
private String twoSubtitle;
|
||||||
|
|
||||||
|
|
||||||
|
private String browseId;
|
||||||
|
|
||||||
|
|
||||||
|
public String getBrowseId() {
|
||||||
|
return browseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrowseId(String browseId) {
|
||||||
|
this.browseId = browseId;
|
||||||
|
}
|
||||||
|
|
||||||
public String getCovert() {
|
public String getCovert() {
|
||||||
return covert;
|
return covert;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,10 +1,12 @@
|
|||||||
package com.hi.music.player.network;
|
package com.hi.music.player.network;
|
||||||
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
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.ResponsePlayListInfo;
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
||||||
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
||||||
import com.hi.music.player.javabean.response.ResponseHome;
|
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.ResponseHomeChild;
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
||||||
|
|
||||||
@ -66,113 +68,6 @@ public class JsonHelper {
|
|||||||
return responseHome;
|
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<ResponseHomeChild> 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<ResponseCategory> categoryList = new ArrayList<>();
|
|
||||||
List<ResponseSingle> 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<ResponsePlayListInfo> ResolvePlayListJson(JSONObject jsonObject) {
|
public static List<ResponsePlayListInfo> ResolvePlayListJson(JSONObject jsonObject) {
|
||||||
List<ResponsePlayListInfo> list = new ArrayList<>();
|
List<ResponsePlayListInfo> list = new ArrayList<>();
|
||||||
@ -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<ResponseCategoryListChild> mList = new ArrayList<>();
|
||||||
|
for(int i = 0;i<jsonArray.length();i++){
|
||||||
|
JSONObject arrayJSONObject = jsonArray.getJSONObject(i).getJSONObject("musicResponsiveListItemRenderer");
|
||||||
|
|
||||||
|
String duration = getJsonTitle(arrayJSONObject.getJSONArray("fixedColumns").getJSONObject(0).getJSONObject("musicResponsiveListItemFixedColumnRenderer").getJSONObject("text"), 0);
|
||||||
|
|
||||||
|
String thumbnail = getJsonUrl(arrayJSONObject.getJSONObject("thumbnail"), true);
|
||||||
|
|
||||||
|
JSONArray flexColumns = arrayJSONObject
|
||||||
|
.getJSONArray("flexColumns");
|
||||||
|
|
||||||
|
|
||||||
|
//歌名、歌手名字、描述
|
||||||
|
String SongTitle = "";
|
||||||
|
String SingerName = "";
|
||||||
|
String Description = "";
|
||||||
|
for (int g = 0; g < flexColumns.length(); g++) {
|
||||||
|
String text = getJsonTitle(flexColumns.getJSONObject(g).getJSONObject("musicResponsiveListItemFlexColumnRenderer").getJSONObject("text"), 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;
|
||||||
|
}
|
||||||
|
ResponseCategoryListChild child = new ResponseCategoryListChild();
|
||||||
|
child.setSongCovert(thumbnail);
|
||||||
|
child.setSongDuration(duration);
|
||||||
|
child.setSingerName(SingerName);
|
||||||
|
child.setSongTitle(SongTitle);
|
||||||
|
mList.add(child);
|
||||||
|
|
||||||
|
CommonUtils.LogMsg("--歌曲"+i+"-------------SongTitle="+SongTitle+"--SingerName="+SingerName+"---Description="+Description+"---duration="+duration+"--thumbnail="+thumbnail);
|
||||||
|
}
|
||||||
|
responseCategoryList.setList(mList);
|
||||||
|
|
||||||
|
return responseCategoryList;
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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<ResponseHomeChild> 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<ResponseCategory> categoryList = new ArrayList<>();
|
||||||
|
List<ResponseSingle> 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) {
|
private static String[] getWatchEndPoint(JSONObject job) {
|
||||||
|
|
||||||
String[] strings = new String[4];
|
String[] strings = new String[4];
|
||||||
@ -303,9 +428,7 @@ public class JsonHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param jsonObject
|
* @param jsonObject
|
||||||
* @param maxBig 是否取最大的一张图片
|
* @param maxBig 是否取最大的一张图片
|
||||||
* @return
|
* @return
|
||||||
@ -318,7 +441,7 @@ public class JsonHelper {
|
|||||||
}
|
}
|
||||||
JSONArray jsonArray = jsonObject.getJSONObject("thumbnail").getJSONArray("thumbnails");
|
JSONArray jsonArray = jsonObject.getJSONObject("thumbnail").getJSONArray("thumbnails");
|
||||||
int length = jsonArray.length();
|
int length = jsonArray.length();
|
||||||
int index = 3;
|
int index = 0;
|
||||||
if (maxBig) {
|
if (maxBig) {
|
||||||
index = length - 1;
|
index = length - 1;
|
||||||
}
|
}
|
||||||
@ -346,6 +469,11 @@ public class JsonHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* runs 数组的字符串拼接
|
||||||
|
* @param jsonObject
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
private static String getJsonTextNew(JSONObject jsonObject) {
|
private static String getJsonTextNew(JSONObject jsonObject) {
|
||||||
StringBuilder text = new StringBuilder();
|
StringBuilder text = new StringBuilder();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -42,7 +42,7 @@ public interface MusicApi {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//获取播放音频资源url
|
||||||
@POST("youtubei/v1/player?prettyPrint=false")
|
@POST("youtubei/v1/player?prettyPrint=false")
|
||||||
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
|
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
|
||||||
"X-Goog-FieldMask:playabilityStatus.status,playerConfig.audioConfig,streamingData.adaptiveFormats,videoDetails.videoId"})
|
"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-")
|
@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<ResponseBody> getTest();
|
Observable<ResponseBody> getTest();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//首页分类项下的播放列表子页面
|
||||||
|
@POST("youtubei/v1/browse")
|
||||||
|
@Headers("X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8")
|
||||||
|
Observable<ResponseBody> getCategoryList(@Body RequestBody requestBody);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -150,4 +150,18 @@ public class RetrofitManager {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void getCategoryList(String browserId,RequestListener<ResponseBody> 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<ResponseBody>(requestListener));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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<ActivityCategoryListBinding> {
|
||||||
|
|
||||||
|
|
||||||
|
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<ResponseCategoryList>() {
|
||||||
|
@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<Drawable>() {
|
||||||
|
@Override
|
||||||
|
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> 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<Drawable>() {
|
||||||
|
@Override
|
||||||
|
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> 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<Drawable> 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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -91,6 +91,7 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
|||||||
responseSingle = (ResponseSingle) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER);
|
responseSingle = (ResponseSingle) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER);
|
||||||
vmPlay = getActivityScopeViewModel(VMPlay.class);
|
vmPlay = getActivityScopeViewModel(VMPlay.class);
|
||||||
initMediaController();
|
initMediaController();
|
||||||
|
vb.progressBarLoading.setVisibility(View.VISIBLE);
|
||||||
vmPlay.getPlayMusicList(responseSingle);
|
vmPlay.getPlayMusicList(responseSingle);
|
||||||
initPlayerView();
|
initPlayerView();
|
||||||
|
|
||||||
@ -108,7 +109,6 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
|||||||
if (playList.size() > 0) {
|
if (playList.size() > 0) {
|
||||||
mPlayList = playList;
|
mPlayList = playList;
|
||||||
musicInfo = playList.get(0);
|
musicInfo = playList.get(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.hi.music.player.ui.fragmnt;
|
package com.hi.music.player.ui.fragmnt;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.RestrictionsManager;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
@ -9,24 +10,33 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
|||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.hi.music.player.adapter.AdapterHome;
|
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.databinding.FragmentHomeBinding;
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
import com.hi.music.player.helper.CommonUtils;
|
||||||
import com.hi.music.player.helper.MyValue;
|
import com.hi.music.player.helper.MyValue;
|
||||||
import com.hi.music.player.javabean.response.ResponseHome;
|
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.ResponseHomeChild;
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
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.activity.PlayActivity;
|
||||||
import com.hi.music.player.ui.fragmnt.viewmodel.VMHome;
|
import com.hi.music.player.ui.fragmnt.viewmodel.VMHome;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class HomeFragment extends BaseFragment<FragmentHomeBinding> implements ClickSingerListener<ResponseSingle> {
|
import okhttp3.ResponseBody;
|
||||||
|
|
||||||
|
public class HomeFragment extends BaseFragment<FragmentHomeBinding> implements HomeItemClickListener {
|
||||||
|
|
||||||
|
|
||||||
private VMHome vmHome;
|
private VMHome vmHome;
|
||||||
private AdapterHome adapterHome;
|
|
||||||
|
|
||||||
private int requestCount = 1;
|
private int requestCount = 1;
|
||||||
|
|
||||||
@ -47,7 +57,8 @@ public class HomeFragment extends BaseFragment<FragmentHomeBinding> implements C
|
|||||||
// //标题导航栏颜色设置
|
// //标题导航栏颜色设置
|
||||||
// Vb.toolbar.setTitleTextColor(getResources().getColor(R.color.white));
|
// Vb.toolbar.setTitleTextColor(getResources().getColor(R.color.white));
|
||||||
AdapterHome adapterHome = new AdapterHome();
|
AdapterHome adapterHome = new AdapterHome();
|
||||||
adapterHome.setSingleClickSingerListener(this::onClickSingerItem);
|
adapterHome.setHomeItemClickListener(this);
|
||||||
|
|
||||||
|
|
||||||
vmHome = getFragmentScopeViewModel(VMHome.class);
|
vmHome = getFragmentScopeViewModel(VMHome.class);
|
||||||
adapterHome.addLoadingFooter();
|
adapterHome.addLoadingFooter();
|
||||||
@ -87,15 +98,24 @@ public class HomeFragment extends BaseFragment<FragmentHomeBinding> implements C
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClickSingerItem(ResponseSingle data) {
|
public void onClickItemSinger(ResponseSingle data) {
|
||||||
FragmentActivity activity = getActivity();
|
FragmentActivity activity = getActivity();
|
||||||
if(activity!= null){
|
if(activity!= null){
|
||||||
Intent intent = new Intent(activity, PlayActivity.class);
|
Intent intent = new Intent(activity, PlayActivity.class);
|
||||||
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, data);
|
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, data);
|
||||||
startActivity(intent);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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<ResponseCategoryList> _data = new MutableLiveData<>();
|
||||||
|
public LiveData<ResponseCategoryList> data = _data;
|
||||||
|
|
||||||
|
|
||||||
|
public void getList(String browseId) {
|
||||||
|
|
||||||
|
RetrofitManager.getInstance().getCategoryList(browseId, new RequestListener<ResponseBody>() {
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
121
app/src/main/res/layout/activity_category_list.xml
Normal file
121
app/src/main/res/layout/activity_category_list.xml
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<FrameLayout 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"
|
||||||
|
android:background="@color/black"
|
||||||
|
android:id="@+id/root_layout"
|
||||||
|
tools:context=".ui.activity.CategoryListActivity">
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/im_bg"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="200dp" />
|
||||||
|
|
||||||
|
<!-- <com.google.android.material.appbar.AppBarLayout-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="60dp"-->
|
||||||
|
<!-- app:statusBarForeground="@color/color_transparent"-->
|
||||||
|
<!-- android:background="@color/color_transparent">-->
|
||||||
|
|
||||||
|
<!-- <com.google.android.material.appbar.CollapsingToolbarLayout-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="60dp"-->
|
||||||
|
<!-- app:contentScrim="@color/black"-->
|
||||||
|
<!-- app:layout_scrollFlags="scroll|exitUntilCollapsed">-->
|
||||||
|
|
||||||
|
<!-- </com.google.android.material.appbar.CollapsingToolbarLayout>-->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- </com.google.android.material.appbar.AppBarLayout>-->
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/layout_covert"
|
||||||
|
android:layout_marginTop="60dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imCovert"
|
||||||
|
android:layout_width="250dp"
|
||||||
|
android:layout_height="220dp"
|
||||||
|
android:layout_centerHorizontal="true" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/imCovert"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvSubTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/tvTitle"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/btn_play"
|
||||||
|
android:layout_width="66dp"
|
||||||
|
android:layout_height="66dp"
|
||||||
|
android:layout_below="@id/tvSubTitle"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
android:src="@drawable/selector_icon_play" />
|
||||||
|
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:indeterminateTint="@color/white"
|
||||||
|
android:id="@+id/pb_loading"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:background="@color/black"
|
||||||
|
android:layout_height="60dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/im_back"
|
||||||
|
android:layout_width="42dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:padding="9dp"
|
||||||
|
android:src="@drawable/arrow_bottom" />
|
||||||
|
</FrameLayout>
|
||||||
|
</FrameLayout>
|
||||||
40
app/src/main/res/layout/item_category_list.xml
Normal file
40
app/src/main/res/layout/item_category_list.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="70dp"
|
||||||
|
android:paddingStart="15dp"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:paddingBottom="5dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="60dp" />
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_toEndOf="@id/image"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_song_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:text="@string/app_name"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_singer_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/white_60_color"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
@ -3,6 +3,7 @@
|
|||||||
<style name="Base.Theme.MusicApp" parent="Theme.Material3.DayNight.NoActionBar">
|
<style name="Base.Theme.MusicApp" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
<!-- Customize your light theme here. -->
|
<!-- Customize your light theme here. -->
|
||||||
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
|
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
|
||||||
|
<item name="android:windowBackground">@color/black</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="Theme.MusicApp" parent="Base.Theme.MusicApp" />
|
<style name="Theme.MusicApp" parent="Base.Theme.MusicApp" />
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user