播放列表
This commit is contained in:
parent
0f59e337be
commit
129680cb45
@ -57,8 +57,13 @@ dependencies {
|
||||
|
||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||
|
||||
|
||||
//提取图片主色
|
||||
implementation ("androidx.palette:palette:1.0.0")
|
||||
|
||||
//动画
|
||||
implementation ("com.airbnb.android:lottie:5.2.0")
|
||||
|
||||
//----------media3
|
||||
implementation("androidx.media3:media3-exoplayer:1.4.1")
|
||||
implementation("androidx.media3:media3-exoplayer-dash:1.4.1")
|
||||
|
||||
51
app/src/main/assets/music_bounce.json
Normal file
51
app/src/main/assets/music_bounce.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"v": "5.5.7",
|
||||
"fr": 60,
|
||||
"ip": 0,
|
||||
"op": 90,
|
||||
"w": 500,
|
||||
"h": 500,
|
||||
"nm": "Audio Wave",
|
||||
"ddd": 0,
|
||||
"assets": [],
|
||||
"layers": [
|
||||
{
|
||||
"ddd": 0,
|
||||
"ind": 1,
|
||||
"ty": 4,
|
||||
"nm": "Wave Layer",
|
||||
"sr": 1,
|
||||
"ks": {
|
||||
"o": { "a": 0, "k": 100, "ix": 11 },
|
||||
"r": { "a": 0, "k": 0, "ix": 10 },
|
||||
"p": { "a": 0, "k": [250, 250, 0], "ix": 2 },
|
||||
"a": { "a": 0, "k": [0, 0, 0], "ix": 1 },
|
||||
"s": {
|
||||
"a": 1,
|
||||
"k": [
|
||||
{ "i": { "x": [0.667], "y": [1] }, "o": { "x": [0.333], "y": [0] }, "t": 0, "s": [100, 100, 100] },
|
||||
{ "i": { "x": [0.667], "y": [1] }, "o": { "x": [0.333], "y": [0] }, "t": 45, "s": [100, 150, 100] },
|
||||
{ "t": 90, "s": [100, 100, 100] }
|
||||
],
|
||||
"ix": 6
|
||||
}
|
||||
},
|
||||
"ao": 0,
|
||||
"shapes": [
|
||||
{
|
||||
"ty": "rc",
|
||||
"d": 1,
|
||||
"s": { "a": 0, "k": [100, 300], "ix": 2 },
|
||||
"p": { "a": 0, "k": [0, 0], "ix": 3 },
|
||||
"nm": "Rectangle Path 1",
|
||||
"mn": "ADBE Vector Shape - Rect",
|
||||
"hd": false
|
||||
}
|
||||
],
|
||||
"ip": 0,
|
||||
"op": 90,
|
||||
"st": 0,
|
||||
"bm": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -9,13 +9,11 @@ import com.hi.music.player.media3.MyMediaControllerManager;
|
||||
|
||||
public class MusicApplication extends Application {
|
||||
|
||||
// private final static MusicApplication sInstance = new MusicApplication();
|
||||
|
||||
|
||||
|
||||
public static Context myApplication;
|
||||
// public static MusicApplication getInstance() {
|
||||
// return sInstance;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
package com.hi.music.player.adapter;
|
||||
|
||||
import static androidx.media3.session.legacy.MediaControllerCompat.getMediaController;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.hi.music.player.MusicApplication;
|
||||
import com.hi.music.player.R;
|
||||
import com.hi.music.player.databinding.ItemPlayListBinding;
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
||||
|
||||
public class AdapterPlayList extends BaseAdapter<ResponsePlayListInfo, ItemPlayListBinding> {
|
||||
@Override
|
||||
protected ItemPlayListBinding getViewBinding(ViewGroup parent) {
|
||||
return ItemPlayListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
ResponsePlayListInfo listInfo = data.get(position);
|
||||
VHolder<ItemPlayListBinding> itemHolder = (VHolder<ItemPlayListBinding>) holder;
|
||||
ItemPlayListBinding vb = itemHolder.getVb();
|
||||
Glide.with(MusicApplication.myApplication)
|
||||
.asDrawable()
|
||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(10))))
|
||||
.load(listInfo.getSmallCovert())
|
||||
.placeholder(R.mipmap.ic_launcher)
|
||||
.into(vb.imCovert);
|
||||
vb.songName.setText(listInfo.getSongTitle());
|
||||
vb.artistName.setText(listInfo.getSingerName());
|
||||
MyMediaControllerManager instance = MyMediaControllerManager.getInstance();
|
||||
MediaItem currentMediaItem = instance.getMediaController().getCurrentMediaItem();
|
||||
if (currentMediaItem != null && currentMediaItem.mediaId.equals(listInfo.getVideoId())) {
|
||||
vb.lottieAnimationView.setVisibility(View.VISIBLE);
|
||||
if (instance.getMediaController().isPlaying()) {
|
||||
vb.lottieAnimationView.playAnimation();
|
||||
CommonUtils.LogMsg("-------playAnimation");
|
||||
} else {
|
||||
vb.lottieAnimationView.pauseAnimation();
|
||||
CommonUtils.LogMsg("-------pauseAnimation");
|
||||
}
|
||||
} else {
|
||||
vb.lottieAnimationView.setVisibility(View.GONE);
|
||||
CommonUtils.LogMsg("-------GONE");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,9 @@
|
||||
package com.hi.music.player.dialog;
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
@ -12,48 +14,80 @@ import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.hi.music.player.MusicApplication;
|
||||
import com.hi.music.player.R;
|
||||
|
||||
|
||||
public abstract class BaseDialog<T extends ViewBinding> extends DialogFragment {
|
||||
|
||||
protected T vb;
|
||||
|
||||
|
||||
protected abstract T getViewBinding(LayoutInflater inflater, ViewGroup container);
|
||||
protected abstract T getViewBinding(LayoutInflater inflater, ViewGroup container);
|
||||
|
||||
protected abstract void initView();
|
||||
|
||||
protected abstract void initView();
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
vb = getViewBinding(inflater,container);
|
||||
vb = getViewBinding(inflater, container);
|
||||
init();
|
||||
initView();
|
||||
return vb.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("ResourceType")
|
||||
private void init() {
|
||||
|
||||
Dialog dialog = getDialog();
|
||||
setCancelable(true);
|
||||
|
||||
if (dialog != null) {
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
// window.setBackgroundDrawableResource();
|
||||
window.getDecorView().setPadding(0, 0, 0, 0);
|
||||
|
||||
WindowManager.LayoutParams attributes = window.getAttributes();
|
||||
attributes.gravity = Gravity.BOTTOM;
|
||||
attributes.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
attributes.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
window.setAttributes(attributes);
|
||||
if (isFullScreen()) {
|
||||
window.setStatusBarColor(Color.YELLOW); // 设置状态栏为透明,或其他颜色
|
||||
// 设置 dialog 占据全屏并延伸到状态栏
|
||||
// window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
|
||||
|
||||
// 允许内容绘制到状态栏
|
||||
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
|
||||
window.setBackgroundDrawableResource(R.color.color_transparent);
|
||||
window.getDecorView().setPadding(0, 0, 0, 0);
|
||||
WindowManager.LayoutParams attributes = window.getAttributes();
|
||||
attributes.gravity = Gravity.BOTTOM;
|
||||
attributes.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
attributes.height = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
window.setAttributes(attributes);
|
||||
} else {
|
||||
window.setBackgroundDrawableResource(R.color.color_transparent);
|
||||
window.getDecorView().setPadding(0, 0, 0, 0);
|
||||
|
||||
WindowManager.LayoutParams attributes = window.getAttributes();
|
||||
attributes.gravity = Gravity.BOTTOM;
|
||||
attributes.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
attributes.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
window.setAttributes(attributes);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public abstract boolean isFullScreen();
|
||||
|
||||
public void closeDialog() {
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@ -1,19 +1,126 @@
|
||||
package com.hi.music.player.dialog;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.net.Uri;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.hi.music.player.databinding.DialogPlayListBinding;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.OptIn;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
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.adapter.AdapterPlayList;
|
||||
import com.hi.music.player.api.onImageColorListener;
|
||||
import com.hi.music.player.databinding.DialogPlayListBinding;
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
||||
import com.hi.music.player.media3.MyControllerView;
|
||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DialogPlayList extends BaseDialog<DialogPlayListBinding> {
|
||||
private MyMediaControllerManager instance;
|
||||
|
||||
public class DialogPlayList extends BaseDialog<DialogPlayListBinding>{
|
||||
@Override
|
||||
protected DialogPlayListBinding getViewBinding(LayoutInflater inflater, ViewGroup container) {
|
||||
return DialogPlayListBinding.inflate(inflater,container,false);
|
||||
return DialogPlayListBinding.inflate(inflater, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
|
||||
instance = MyMediaControllerManager.getInstance();
|
||||
initPlayListUi();
|
||||
|
||||
MediaItem currentMediaItem = instance.getMediaController().getCurrentMediaItem();
|
||||
if (currentMediaItem != null) {
|
||||
Uri artworkUri = currentMediaItem.mediaMetadata.artworkUri;
|
||||
vb.topSongName.setText(currentMediaItem.mediaMetadata.title);
|
||||
vb.topSingerName.setText(currentMediaItem.mediaMetadata.artist);
|
||||
|
||||
Glide.with(MusicApplication.myApplication)
|
||||
.asDrawable()
|
||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(10))))
|
||||
.load(artworkUri)
|
||||
.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) {
|
||||
CommonUtils.getDominantDarkColor1(resource, new onImageColorListener() {
|
||||
@Override
|
||||
public void onImageColor(int color) {
|
||||
if (color == -1) {
|
||||
return;
|
||||
}
|
||||
int lighterColor = CommonUtils.adjustBrightness(color, 1.2f); // 比原始颜色亮 20%
|
||||
int darkerColor = CommonUtils.adjustBrightness(color, 0.8f); // 比原始颜色暗 20%
|
||||
// GradientDrawable gradientDrawable = new GradientDrawable(
|
||||
// GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
// new int[]{lighterColor, darkerColor} // 浅到深渐变
|
||||
// );
|
||||
vb.topLayout.setBackgroundColor(darkerColor);
|
||||
Drawable newDrawable = CommonUtils.getNewDrawable(lighterColor, 24f, 24f, 0, 0);
|
||||
vb.listLayout.setBackground(newDrawable);
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(vb.topIm);
|
||||
}
|
||||
vb.imPlay.setSelected(instance.getMediaController().isPlaying());
|
||||
|
||||
vb.imPlay.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
vb.imPlay.setSelected(!vb.imPlay.isSelected());
|
||||
if (vb.imPlay.isSelected()) {
|
||||
instance.play();
|
||||
} else {
|
||||
instance.pause();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullScreen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void initPlayListUi() {
|
||||
List<ResponsePlayListInfo> playList = instance.getPlayList();
|
||||
AdapterPlayList adapterPlayList = new AdapterPlayList();
|
||||
vb.recyclerList.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication));
|
||||
adapterPlayList.addData(playList);
|
||||
vb.recyclerList.setAdapter(adapterPlayList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -2,8 +2,10 @@ package com.hi.music.player.helper;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView;
|
||||
@ -17,6 +19,8 @@ import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
@ -88,42 +92,74 @@ public class CommonUtils {
|
||||
return String.format("%d:%02d", minutes, seconds); // 格式化为 mm:ss
|
||||
}
|
||||
|
||||
/**
|
||||
* 从图片中提取主色调
|
||||
* @param imDraw
|
||||
*/
|
||||
public static void extractDominantColor(Drawable imDraw, onImageColorListener listener) {
|
||||
BitmapDrawable drawable = (BitmapDrawable)imDraw;
|
||||
if (drawable != null) {
|
||||
Bitmap bitmap = drawable.getBitmap();
|
||||
|
||||
// 使用 Palette 提取颜色
|
||||
Palette.from(bitmap).generate(palette -> {
|
||||
if (palette != null) {
|
||||
int dominantColor = palette.getDominantColor(0);
|
||||
int suitableDarkColor = getSuitableDarkColor(dominantColor);
|
||||
listener.onImageColor(suitableDarkColor);
|
||||
// 使用 Palette 提取深色主色调
|
||||
public static void getDominantDarkColor1(Drawable imDraw, onImageColorListener listener) {
|
||||
// 异步生成 Palette
|
||||
BitmapDrawable drawable = (BitmapDrawable)imDraw;
|
||||
if(drawable!=null){
|
||||
Bitmap bitmap = drawable.getBitmap();
|
||||
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
|
||||
@Override
|
||||
public void onGenerated(Palette palette) {
|
||||
// 首先尝试获取深色活力色
|
||||
Palette.Swatch darkVibrantSwatch = palette.getDarkVibrantSwatch();
|
||||
|
||||
// 如果没有深色活力色,尝试获取深色柔和色
|
||||
if (darkVibrantSwatch == null) {
|
||||
darkVibrantSwatch = palette.getDarkMutedSwatch();
|
||||
}
|
||||
|
||||
// 如果存在深色样本,则获取其 RGB 颜色值
|
||||
if (darkVibrantSwatch != null) {
|
||||
int dominantDarkColor = darkVibrantSwatch.getRgb();
|
||||
listener.onImageColor(dominantDarkColor);
|
||||
String dominantColorHex = String.format("#%06X", (0xFFFFFF & dominantDarkColor));
|
||||
Log.d("Dominant Dark Color", "主色调: " + dominantColorHex); // 打印主色调
|
||||
} else {
|
||||
Log.d("Dominant Dark Color", "未找到深色主色调");
|
||||
listener.onImageColor(-1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}else {
|
||||
listener.onImageColor(-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 调整颜色的亮度,factor > 1 表示变亮,factor < 1 表示变暗
|
||||
public static int adjustBrightness(int color, float factor) {
|
||||
// 将 RGB 颜色转换为 HSV
|
||||
float[] hsv = new float[3];
|
||||
Color.colorToHSV(color, hsv);
|
||||
|
||||
// 调整亮度(V 值)
|
||||
hsv[2] = Math.min(1.0f, hsv[2] * factor); // 亮度值最多是 1.0
|
||||
|
||||
// 返回调整后的颜色(HSV 转回 RGB)
|
||||
return Color.HSVToColor(hsv);
|
||||
}
|
||||
|
||||
|
||||
private static int getSuitableDarkColor(int color) {
|
||||
// 提取颜色的 R, G, B 值
|
||||
int r = (color >> 16) & 0xff;
|
||||
int g = (color >> 8) & 0xff;
|
||||
int b = color & 0xff;
|
||||
public static Drawable getNewDrawable(int color,float RadiusTopLeft,float RadiusTopRight,float RadiusBottomRight,float RadiusBottomLeft){
|
||||
// 创建 GradientDrawable
|
||||
GradientDrawable drawable = new GradientDrawable();
|
||||
|
||||
// 计算亮度
|
||||
double luminance = 0.299 * r + 0.587 * g + 0.114 * b;
|
||||
// 设置形状为矩形
|
||||
drawable.setShape(GradientDrawable.RECTANGLE);
|
||||
|
||||
// 如果亮度较高,则选择更深的颜色
|
||||
if (luminance > 128) {
|
||||
return 0xFF000000; // 黑色
|
||||
} else {
|
||||
// 如果颜色较暗,选择一种深色调
|
||||
return 0xFF1F1F1F; // 深灰色作为替代
|
||||
}
|
||||
// 设置背景颜色
|
||||
drawable.setColor(color);
|
||||
|
||||
// 设置顶部圆角 (top-left and top-right)
|
||||
float[] radii = new float[]{
|
||||
RadiusTopLeft, RadiusTopLeft, // top-left radius
|
||||
RadiusTopRight, RadiusTopRight, // top-right radius
|
||||
RadiusBottomRight, RadiusBottomRight, // bottom-right radius
|
||||
RadiusBottomLeft, RadiusBottomLeft // bottom-left radius
|
||||
};
|
||||
drawable.setCornerRadii(radii);
|
||||
return drawable;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,13 @@ public class MyValue {
|
||||
public static String KEY_PLAY_ACTIVITY_SINGER = "click_singer";
|
||||
|
||||
//播放错误
|
||||
public static int PLAY_STATUS_CODE = -1;
|
||||
public final static int PLAY_STATUS_CODE_ERROR = -1;
|
||||
|
||||
//正在播放
|
||||
public final static int PLAY_STATUS_CODE_PLAYING = -2;
|
||||
|
||||
|
||||
//暂停或者停止
|
||||
public final static int PLAY_STATUS_CODE_PAUSE = -3;
|
||||
//-----------------------------PlayActivity
|
||||
}
|
||||
|
||||
@ -24,10 +24,7 @@ import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
||||
import com.hi.music.player.network.RetrofitManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class MyMediaControllerManager {
|
||||
@ -82,7 +79,7 @@ public class MyMediaControllerManager {
|
||||
@Override
|
||||
public void onPlayerError(PlaybackException error) {
|
||||
CommonUtils.LogMsg("=-----PlaybackException+" + error.getMessage());
|
||||
mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE);
|
||||
mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -99,7 +96,7 @@ public class MyMediaControllerManager {
|
||||
public void onIsPlayingChanged(boolean isPlaying) {
|
||||
|
||||
if (isPlaying) {
|
||||
|
||||
mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_PLAYING);
|
||||
// TODO: 2024/9/26 自动播放完成切歌到下一首播放没有触发这里请求下一首
|
||||
// 播放器开始播放
|
||||
MediaItem currentItem = mediaController.getCurrentMediaItem();
|
||||
@ -116,7 +113,7 @@ public class MyMediaControllerManager {
|
||||
}
|
||||
} else {
|
||||
// 播放器暂停或停止
|
||||
|
||||
mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_PAUSE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,6 +182,10 @@ public class MyMediaControllerManager {
|
||||
this.playList = playList;
|
||||
}
|
||||
|
||||
public List<ResponsePlayListInfo> getPlayList() {
|
||||
return playList;
|
||||
}
|
||||
|
||||
public void resetPlayList(){
|
||||
mediaController.clearMediaItems();
|
||||
}
|
||||
@ -278,7 +279,10 @@ public class MyMediaControllerManager {
|
||||
if (mediaController.isPlaying())
|
||||
mediaController.pause();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (mediaController.isPlaying())
|
||||
mediaController.stop();
|
||||
}
|
||||
public void playNext() {
|
||||
if (mediaController.hasNextMediaItem()) {
|
||||
mediaController.seekToNextMediaItem();
|
||||
|
||||
@ -319,7 +319,7 @@ public class JsonHelper {
|
||||
}
|
||||
JSONArray jsonArray = jsonObject.getJSONObject("thumbnail").getJSONArray("thumbnails");
|
||||
int length = jsonArray.length();
|
||||
int index = 0;
|
||||
int index = 3;
|
||||
if(maxBig){
|
||||
index = length - 1;
|
||||
}
|
||||
|
||||
@ -2,9 +2,13 @@ package com.hi.music.player.ui.activity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -16,6 +20,7 @@ import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.MediaMetadata;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
@ -26,9 +31,11 @@ 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.AdapterPlayList;
|
||||
import com.hi.music.player.api.MediaControllerListener;
|
||||
import com.hi.music.player.api.onImageColorListener;
|
||||
import com.hi.music.player.databinding.ActivityPlayBinding;
|
||||
import com.hi.music.player.dialog.DialogPlayList;
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.helper.MyValue;
|
||||
import com.hi.music.player.javabean.CustomerUrlInfo;
|
||||
@ -60,10 +67,12 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
private MyMediaControllerManager mediaControllerManager;
|
||||
|
||||
|
||||
//请求播放列表是否成功
|
||||
private boolean requestPlayList = false;
|
||||
//请求第一首歌曲url是否成功
|
||||
private boolean requestPlayUrl = false;
|
||||
//播放列表ui初始化
|
||||
private boolean initPlayList = false;
|
||||
|
||||
private GradientDrawable gradientDrawable;
|
||||
private int lighterColor,darkerColor;
|
||||
|
||||
|
||||
@Override
|
||||
protected ActivityPlayBinding getViewBinding() {
|
||||
@ -85,10 +94,10 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
@Override
|
||||
public void onChanged(List<ResponsePlayListInfo> playList) {
|
||||
if (playList == null) {
|
||||
CommonUtils.LogMsg("---------playList = null");
|
||||
return;
|
||||
}
|
||||
if (playList.size() > 0) {
|
||||
requestPlayList = true;
|
||||
mPlayList = playList;
|
||||
musicInfo = playList.get(0);
|
||||
|
||||
@ -105,7 +114,7 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
CommonUtils.LogMsg("-------------需要马上播放这首歌曲,但是此次网络请求失败");
|
||||
return;
|
||||
}
|
||||
requestPlayUrl = true;
|
||||
|
||||
mCurPlayInfo = customerUrlInfo.getPlayUrl();
|
||||
int second = customerUrlInfo.getPlayMusicIndex();
|
||||
boolean needPlayNow = customerUrlInfo.isNeedPlayNow();
|
||||
@ -126,7 +135,19 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
|
||||
private void initMediaController() {
|
||||
mediaControllerManager = MyMediaControllerManager.getInstance();
|
||||
mediaControllerManager.resetPlayList();
|
||||
String videoId = responseSingle.getVideoId();
|
||||
MediaItem currentMediaItem = mediaControllerManager.getMediaController().getCurrentMediaItem();
|
||||
if(currentMediaItem != null){
|
||||
if(currentMediaItem.mediaId.equals(videoId)){
|
||||
// TODO: 2024/9/27 正在播放当前歌曲,又点进来
|
||||
// mediaControllerManager.getMediaController().seekTo(0);
|
||||
}
|
||||
if(mediaControllerManager.getMediaController().isPlaying()){
|
||||
mediaControllerManager.stop();
|
||||
}
|
||||
mediaControllerManager.resetPlayList();
|
||||
}
|
||||
|
||||
mediaControllerManager.addListener(new MediaControllerListener() {
|
||||
@Override
|
||||
public void onPlayStatus(int playStatus) {
|
||||
@ -156,6 +177,12 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
mediaControllerManager.playNext();
|
||||
break;
|
||||
|
||||
case MyValue.PLAY_STATUS_CODE_PAUSE:
|
||||
vb.btnPlay.setSelected(false);
|
||||
break;
|
||||
case MyValue.PLAY_STATUS_CODE_PLAYING:
|
||||
vb.btnPlay.setSelected(true);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
@ -172,6 +199,7 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
|
||||
@Override
|
||||
public void onChangeMusic(MediaItem mediaItem) {
|
||||
CommonUtils.LogMsg("111111111-------22222---"+mediaItem.mediaMetadata.title +"---id="+mediaItem.mediaId);
|
||||
loadInfo(mediaItem);
|
||||
}
|
||||
|
||||
@ -185,6 +213,7 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
vb.btnNext.setOnClickListener(this);
|
||||
vb.btnPrevious.setOnClickListener(this);
|
||||
vb.imBack.setOnClickListener(this);
|
||||
vb.btnMusicList.setOnClickListener(this);
|
||||
}
|
||||
|
||||
|
||||
@ -221,7 +250,7 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
private void loadInfo(MediaItem mediaItem) {
|
||||
|
||||
MediaMetadata mediaMetadata = mediaItem.mediaMetadata;
|
||||
CommonUtils.LogMsg("--------------加载当前播放歌曲信息 "+mediaMetadata.description);
|
||||
CommonUtils.LogMsg("--------------加载当前播放歌曲信息 " + mediaMetadata.description);
|
||||
if (mediaMetadata.artworkUri != null) {
|
||||
loadCovert(mediaMetadata.artworkUri.toString());
|
||||
}
|
||||
@ -238,15 +267,6 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 更新音频url到播放列表
|
||||
*/
|
||||
private void updateAudioUrl(ResponsePlayUrl playUrl) {
|
||||
// mediaControllerManager.UpdateAudioUrl(playUrl);
|
||||
}
|
||||
|
||||
|
||||
private void loadCovert(String url) {
|
||||
Glide.with(MusicApplication.myApplication)
|
||||
.asDrawable()
|
||||
@ -263,10 +283,19 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
@Override
|
||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
||||
CommonUtils.extractDominantColor(resource, new onImageColorListener() {
|
||||
CommonUtils.getDominantDarkColor1(resource, new onImageColorListener() {
|
||||
@Override
|
||||
public void onImageColor(int color) {
|
||||
vb.rootLayout.setBackgroundColor(color);
|
||||
if (color == -1) {
|
||||
return;
|
||||
}
|
||||
lighterColor = CommonUtils.adjustBrightness(color, 1.2f); // 比原始颜色亮 20%
|
||||
darkerColor = CommonUtils.adjustBrightness(color, 0.8f); // 比原始颜色暗 20%
|
||||
gradientDrawable = new GradientDrawable(
|
||||
GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
new int[]{lighterColor, darkerColor} // 浅到深渐变
|
||||
);
|
||||
vb.rootLayout.setBackground(gradientDrawable);
|
||||
|
||||
}
|
||||
});
|
||||
@ -317,10 +346,94 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
mediaControllerManager.playPrevious();
|
||||
} else if (v.equals(vb.imBack)) {
|
||||
finish();
|
||||
} else if (v.equals(vb.btnMusicList)) {
|
||||
initShowPlayList(true);
|
||||
} else if (v.equals(vb.layoutPlayList.imPlay)) {
|
||||
vb.layoutPlayList.imPlay.setSelected(!vb.layoutPlayList.imPlay.isSelected());
|
||||
if (vb.layoutPlayList.imPlay.isSelected()) {
|
||||
mediaControllerManager.play();
|
||||
} else {
|
||||
mediaControllerManager.pause();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 控制播放列表的显示
|
||||
*
|
||||
* @param show
|
||||
*/
|
||||
private void initShowPlayList(boolean show) {
|
||||
if (show) {
|
||||
Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_up);
|
||||
vb.layoutPlayList.linearLayout.startAnimation(animation);
|
||||
vb.layoutPlayList.linearLayout.setVisibility(View.VISIBLE);
|
||||
vb.contentLayout.setVisibility(View.GONE);
|
||||
|
||||
if (!initPlayList) {
|
||||
List<ResponsePlayListInfo> playList = mediaControllerManager.getPlayList();
|
||||
AdapterPlayList adapterPlayList = new AdapterPlayList();
|
||||
vb.layoutPlayList.recyclerList.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication));
|
||||
adapterPlayList.addData(playList);
|
||||
vb.layoutPlayList.recyclerList.setAdapter(adapterPlayList);
|
||||
vb.layoutPlayList.imPlay.setOnClickListener(this);
|
||||
initPlayList = true;
|
||||
}
|
||||
|
||||
MediaItem currentMediaItem = mediaControllerManager.getMediaController().getCurrentMediaItem();
|
||||
if (currentMediaItem != null) {
|
||||
Uri artworkUri = currentMediaItem.mediaMetadata.artworkUri;
|
||||
vb.layoutPlayList.topSongName.setText(currentMediaItem.mediaMetadata.title);
|
||||
vb.layoutPlayList.topSingerName.setText(currentMediaItem.mediaMetadata.artist);
|
||||
|
||||
|
||||
vb.layoutPlayList.topLayout.setBackgroundColor(darkerColor);
|
||||
GradientDrawable gradientDrawable = new GradientDrawable(
|
||||
GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
new int[]{darkerColor, darkerColor}
|
||||
);
|
||||
vb.rootLayout.setBackground(gradientDrawable);
|
||||
Drawable newDrawable = CommonUtils.getNewDrawable(lighterColor, 24f, 24f, 0, 0);
|
||||
vb.layoutPlayList.listLayout.setBackground(newDrawable);
|
||||
|
||||
|
||||
Glide.with(MusicApplication.myApplication)
|
||||
.asDrawable()
|
||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(10))))
|
||||
.load(artworkUri)
|
||||
.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.layoutPlayList.topIm);
|
||||
}
|
||||
vb.layoutPlayList.imPlay.setSelected(mediaControllerManager.getMediaController().isPlaying());
|
||||
|
||||
} else {
|
||||
|
||||
vb.rootLayout.setBackground(gradientDrawable);
|
||||
vb.contentLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_down);
|
||||
vb.layoutPlayList.linearLayout.startAnimation(animation);
|
||||
vb.layoutPlayList.linearLayout.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
@ -328,6 +441,14 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
mHandler.removeCallbacks(mRunnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (vb.layoutPlayList.linearLayout.getVisibility()==View.VISIBLE) {
|
||||
initShowPlayList(false);
|
||||
} else {
|
||||
super.onBackPressed(); // 调用系统默认的返回行为
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
package com.hi.music.player.ui.activity.viewmodel;
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
@ -40,6 +38,8 @@ public class VMPlay extends ViewModel {
|
||||
String params = responseSingle.getParams();
|
||||
String musicVideoType = responseSingle.getMusicVideoType();
|
||||
|
||||
CommonUtils.LogMsg("111111111-------0000---"+responseSingle.getSongTitle() +"---id="+videoId);
|
||||
|
||||
RetrofitManager.getInstance().getPlayList(params, playlistId, videoId, musicVideoType, new RequestListener<ResponseBody>() {
|
||||
|
||||
@Override
|
||||
@ -54,6 +54,7 @@ public class VMPlay extends ViewModel {
|
||||
List<ResponsePlayListInfo> responsePlayListInfos = JsonHelper.ResolvePlayListJson(jsonObject);
|
||||
MyMediaControllerManager.getInstance().setPlayList(responsePlayListInfos);
|
||||
_playList.setValue(responsePlayListInfos);
|
||||
CommonUtils.LogMsg("111111111-------1111----"+responsePlayListInfos.get(0).getSongTitle() +"---id="+responsePlayListInfos.get(0).getVideoId());
|
||||
getPlayUrl(responseSingle.getVideoId(),0,true);
|
||||
} else {
|
||||
_playList.setValue(null);
|
||||
@ -78,6 +79,10 @@ public class VMPlay extends ViewModel {
|
||||
JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
||||
if (jsonObject != null) {
|
||||
ResponsePlayUrl responsePlayUrl = JsonHelper.ResolvePlayUrlJson(jsonObject);
|
||||
if(responsePlayUrl == null){
|
||||
// TODO: 2024/9/27
|
||||
return;
|
||||
}
|
||||
MyMediaControllerManager.getInstance().addMusicToPlayList(responsePlayUrl,playListIndex);
|
||||
customerUrlInfo.setPlayUrl(responsePlayUrl);
|
||||
customerUrlInfo.setPlayMusicIndex(playListIndex);
|
||||
|
||||
7
app/src/main/res/anim/slide_down.xml
Normal file
7
app/src/main/res/anim/slide_down.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:fromYDelta="0%"
|
||||
android:toYDelta="100%"
|
||||
android:duration="500"/>
|
||||
</set>
|
||||
7
app/src/main/res/anim/slide_up.xml
Normal file
7
app/src/main/res/anim/slide_up.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:fromYDelta="100%"
|
||||
android:toYDelta="0%"
|
||||
android:duration="500"/>
|
||||
</set>
|
||||
7
app/src/main/res/drawable/rec_bg_18.xml
Normal file
7
app/src/main/res/drawable/rec_bg_18.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:topLeftRadius="18dp" android:topRightRadius="18dp"/>
|
||||
<solid android:color="@color/default_play_list_color"/>
|
||||
|
||||
</shape>
|
||||
6
app/src/main/res/drawable/selector_small_play.xml
Normal file
6
app/src/main/res/drawable/selector_small_play.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_selected="false" android:drawable="@drawable/small_play"/>
|
||||
<item android:state_selected="true" android:drawable="@drawable/small_pause"/>
|
||||
|
||||
</selector>
|
||||
22
app/src/main/res/drawable/small_pause.xml
Normal file
22
app/src/main/res/drawable/small_pause.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h24v24h-24z"/>
|
||||
<path
|
||||
android:pathData="M17.571,2.57V21.57"
|
||||
android:strokeWidth="5"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#ffffff"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M6.429,2.57V21.57"
|
||||
android:strokeWidth="5"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeColor="#ffffff"
|
||||
android:strokeLineCap="round"/>
|
||||
</group>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/small_play.xml
Normal file
9
app/src/main/res/drawable/small_play.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="26dp"
|
||||
android:height="26dp"
|
||||
android:viewportWidth="26"
|
||||
android:viewportHeight="26">
|
||||
<path
|
||||
android:pathData="M22.779,15.16L10.982,23.069C9.789,23.869 8.174,23.55 7.374,22.358C7.087,21.93 6.934,21.426 6.934,20.91V5.09C6.934,3.654 8.098,2.49 9.534,2.49C10.049,2.49 10.553,2.643 10.982,2.931L22.779,10.84C23.972,11.64 24.291,13.255 23.491,14.448C23.302,14.729 23.06,14.971 22.779,15.16Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
@ -1,103 +1,89 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<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:id="@+id/root_layout"
|
||||
android:background="@color/black"
|
||||
tools:context=".ui.activity.PlayActivity">
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/im_back"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="25dp"
|
||||
android:padding="9dp"
|
||||
android:src="@drawable/arrow_bottom"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/im_covert"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="300dp"
|
||||
android:layout_marginStart="40dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="40dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/im_back" />
|
||||
android:id="@+id/content_layout"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/im_back"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="42dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="25dp"
|
||||
android:padding="9dp"
|
||||
android:src="@drawable/arrow_bottom"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/im_covert"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="300dp"
|
||||
android:layout_marginStart="40dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="40dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/im_back" />
|
||||
|
||||
|
||||
<androidx.media3.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/im_back"
|
||||
app:show_buffering="when_playing"
|
||||
app:show_shuffle_button="true" />
|
||||
<androidx.media3.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/im_back"
|
||||
app:show_buffering="when_playing"
|
||||
app:show_shuffle_button="true" />
|
||||
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBarLoading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminateTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@id/im_covert"
|
||||
app:layout_constraintLeft_toLeftOf="@id/im_covert"
|
||||
app:layout_constraintRight_toRightOf="@id/im_covert"
|
||||
app:layout_constraintTop_toTopOf="@id/im_covert" />
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBarLoading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminateTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="@id/im_covert"
|
||||
app:layout_constraintLeft_toLeftOf="@id/im_covert"
|
||||
app:layout_constraintRight_toRightOf="@id/im_covert"
|
||||
app:layout_constraintTop_toTopOf="@id/im_covert" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_song_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="25dp"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/text_color_1"
|
||||
android:textSize="19sp"
|
||||
app:layout_constraintLeft_toLeftOf="@id/im_covert"
|
||||
app:layout_constraintTop_toBottomOf="@id/im_covert" />
|
||||
<TextView
|
||||
android:id="@+id/tv_song_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="25dp"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/text_color_1"
|
||||
android:textSize="19sp"
|
||||
app:layout_constraintLeft_toLeftOf="@id/im_covert"
|
||||
app:layout_constraintTop_toBottomOf="@id/im_covert" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_singer_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="7dp"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/white_60_color"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintLeft_toLeftOf="@id/tv_song_name"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_song_name" />
|
||||
<TextView
|
||||
android:id="@+id/tv_singer_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="7dp"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/white_60_color"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintLeft_toLeftOf="@id/tv_song_name"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_song_name" />
|
||||
|
||||
|
||||
<!-- <com.google.android.material.slider.Slider-->
|
||||
<!-- android:id="@+id/play_progress"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:value="0"-->
|
||||
<!-- android:valueFrom="0"-->
|
||||
<!-- android:valueTo="100"-->
|
||||
<!-- app:labelBehavior="gone"-->
|
||||
<!-- app:layout_constraintLeft_toLeftOf="parent"-->
|
||||
<!-- app:layout_constraintRight_toRightOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toBottomOf="@id/tv_singer_name"-->
|
||||
<!-- app:thumbColor="@color/white"-->
|
||||
<!-- app:thumbElevation="0dp"-->
|
||||
<!-- android:paddingStart="0dp"-->
|
||||
<!-- android:paddingEnd="0dp"-->
|
||||
<!-- app:thumbRadius="4dp"-->
|
||||
<!-- app:trackColorActive="@color/white"-->
|
||||
<!-- app:trackColorInactive="@color/seek_bg_color"-->
|
||||
<!-- app:trackHeight="3dp" />-->
|
||||
<SeekBar
|
||||
android:id="@+id/play_progress"
|
||||
android:layout_width="0dp"
|
||||
@ -106,10 +92,10 @@
|
||||
android:layout_marginTop="25dp"
|
||||
android:layout_marginEnd="35dp"
|
||||
android:maxHeight="3dp"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingStart="5dp"
|
||||
android:progress="30"
|
||||
android:progressDrawable="@drawable/seekbar_progress_drawable"
|
||||
android:thumb="@drawable/seekbar_thumb"
|
||||
@ -118,82 +104,86 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_singer_name" />
|
||||
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar_buffer"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="3dp"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:progress="100"
|
||||
android:progressDrawable="@drawable/horizontal_progressbar"
|
||||
app:layout_constraintBottom_toBottomOf="@id/play_progress"
|
||||
app:layout_constraintLeft_toLeftOf="@id/play_progress"
|
||||
app:layout_constraintRight_toRightOf="@id/play_progress"
|
||||
app:layout_constraintTop_toTopOf="@id/play_progress" />
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar_buffer"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="3dp"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:progress="100"
|
||||
android:progressDrawable="@drawable/horizontal_progressbar"
|
||||
app:layout_constraintBottom_toBottomOf="@id/play_progress"
|
||||
app:layout_constraintLeft_toLeftOf="@id/play_progress"
|
||||
app:layout_constraintRight_toRightOf="@id/play_progress"
|
||||
app:layout_constraintTop_toTopOf="@id/play_progress" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_current"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:paddingStart="5dp"
|
||||
android:text="0:00"
|
||||
android:textColor="@color/white_60_color"
|
||||
app:layout_constraintStart_toStartOf="@id/play_progress"
|
||||
app:layout_constraintTop_toBottomOf="@id/play_progress" />
|
||||
<TextView
|
||||
android:id="@+id/tv_current"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:paddingStart="5dp"
|
||||
android:text="0:00"
|
||||
android:textColor="@color/white_60_color"
|
||||
app:layout_constraintStart_toStartOf="@id/play_progress"
|
||||
app:layout_constraintTop_toBottomOf="@id/play_progress" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="0:00"
|
||||
android:textColor="@color/white_60_color"
|
||||
app:layout_constraintEnd_toEndOf="@id/play_progress"
|
||||
app:layout_constraintTop_toBottomOf="@id/play_progress" />
|
||||
<TextView
|
||||
android:id="@+id/tv_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="0:00"
|
||||
android:textColor="@color/white_60_color"
|
||||
app:layout_constraintEnd_toEndOf="@id/play_progress"
|
||||
app:layout_constraintTop_toBottomOf="@id/play_progress" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_play"
|
||||
android:layout_width="66dp"
|
||||
android:layout_height="66dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:src="@drawable/selector_icon_play"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_duration" />
|
||||
<ImageView
|
||||
android:id="@+id/btn_play"
|
||||
android:layout_width="66dp"
|
||||
android:layout_height="66dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:src="@drawable/selector_icon_play"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_duration" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_previous"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginEnd="36dp"
|
||||
android:src="@mipmap/icon_previous_true"
|
||||
app:layout_constraintBottom_toBottomOf="@id/btn_play"
|
||||
app:layout_constraintEnd_toStartOf="@id/btn_play"
|
||||
app:layout_constraintTop_toTopOf="@id/btn_play" />
|
||||
<ImageView
|
||||
android:id="@+id/btn_previous"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginEnd="36dp"
|
||||
android:src="@mipmap/icon_previous_true"
|
||||
app:layout_constraintBottom_toBottomOf="@id/btn_play"
|
||||
app:layout_constraintEnd_toStartOf="@id/btn_play"
|
||||
app:layout_constraintTop_toTopOf="@id/btn_play" />
|
||||
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_next"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="36dp"
|
||||
android:src="@mipmap/icon_next_true"
|
||||
app:layout_constraintBottom_toBottomOf="@id/btn_play"
|
||||
app:layout_constraintStart_toEndOf="@id/btn_play"
|
||||
app:layout_constraintTop_toTopOf="@id/btn_play" />
|
||||
<ImageView
|
||||
android:id="@+id/btn_next"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="36dp"
|
||||
android:src="@mipmap/icon_next_true"
|
||||
app:layout_constraintBottom_toBottomOf="@id/btn_play"
|
||||
app:layout_constraintStart_toEndOf="@id/btn_play"
|
||||
app:layout_constraintTop_toTopOf="@id/btn_play" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_music_list"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@mipmap/icon_list"
|
||||
app:layout_constraintTop_toTopOf="@id/btn_play"
|
||||
app:layout_constraintBottom_toBottomOf="@id/btn_play"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@id/btn_next" />
|
||||
<ImageView
|
||||
android:id="@+id/btn_music_list"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@mipmap/icon_list"
|
||||
app:layout_constraintBottom_toBottomOf="@id/btn_play"
|
||||
app:layout_constraintLeft_toRightOf="@id/btn_next"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/btn_play" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<include
|
||||
android:id="@+id/layout_playList"
|
||||
layout="@layout/dialog_play_list" />
|
||||
</FrameLayout>
|
||||
@ -1,9 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linear_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/top_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/black"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:paddingBottom="25dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/top_im"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/top_im"
|
||||
android:layout_alignBottom="@id/top_im"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_toStartOf="@id/im_play"
|
||||
android:layout_toEndOf="@id/top_im"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:paddingEnd="15dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/top_song_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/text_color_1"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/top_singer_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/white_60_color"
|
||||
android:textSize="11sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/im_play"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="42dp"
|
||||
android:src="@drawable/selector_small_play" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/list_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="-15dp"
|
||||
android:background="@drawable/rec_bg_18">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@id/tv_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:textSize="17sp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginStart="15dp"
|
||||
android:textColor="@color/white"
|
||||
android:text="@string/play_next" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/tv_title" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
55
app/src/main/res/layout/item_play_list.xml
Normal file
55
app/src/main/res/layout/item_play_list.xml
Normal file
@ -0,0 +1,55 @@
|
||||
<?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="80dp"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:paddingStart="20dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="60dp"
|
||||
android:id="@+id/im_covert"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_height="60dp" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottieAnimationView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center"
|
||||
android:padding="5dp"
|
||||
android:layout_alignTop="@id/im_covert"
|
||||
android:layout_alignBottom="@id/im_covert"
|
||||
android:layout_alignStart="@id/im_covert"
|
||||
android:layout_alignEnd="@id/im_covert"
|
||||
app:lottie_fileName="music_bounce.json"
|
||||
app:lottie_autoPlay="false"
|
||||
app:lottie_loop="true"/>
|
||||
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toEndOf="@id/im_covert"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/song_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/text_color_1"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/artist_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/white_60_color"
|
||||
android:textSize="11sp" />
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
@ -9,6 +9,7 @@
|
||||
<color name="seek_bg_color">#4DFFFFFF</color>
|
||||
<color name="white_60_color">#99FFFFFF</color>
|
||||
<color name="progress_buffer_color">#59FFFFFF</color>
|
||||
<color name="default_play_list_color">#1A1A1A</color>
|
||||
|
||||
<color name="test">#2D9C31</color>
|
||||
</resources>
|
||||
@ -21,4 +21,5 @@
|
||||
<string name="share">Share</string>
|
||||
<string name="privacy_policy">Privacy Policy</string>
|
||||
<string name="terms_of_service">Terms of Service</string>
|
||||
<string name="play_next">Play next</string>
|
||||
</resources>
|
||||
Loading…
Reference in New Issue
Block a user