Revert "和并A到main"

This reverts commit 238ddf48fe, reversing
changes made to f1cd9ec8ca.
This commit is contained in:
lihongwei 2024-11-18 15:14:45 +08:00
parent 238ddf48fe
commit 9d7a136173
44 changed files with 8 additions and 6219 deletions

View File

@ -1,57 +0,0 @@
package com.hi.music.player;
import android.app.Application;
import android.content.Context;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.database.StandaloneDatabaseProvider;
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor;
import androidx.media3.datasource.cache.SimpleCache;
import com.hi.music.player.api.MediaControllerStatusListener;
import com.hi.music.player.firebase.RemoteConfigJava;
import com.hi.music.player.firebase.Sp;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.media3.MyDownloadService;
import com.hi.music.player.media3.MyMediaControllerManager;
import com.hi.music.player.objectbox.ObjectBoxManager;
public class MusicApplication extends Application {
public static Context myApplication;
public static String visitorData;
public static void setVisitorData(String visitorData) {
MusicApplication.visitorData = visitorData;
}
public static String getVisitorData() {
return visitorData;
}
@OptIn(markerClass = UnstableApi.class)
@Override
public void onCreate() {
super.onCreate();
myApplication = this;
Sp.init(this);
RemoteConfigJava.getInstance().init(this);
ObjectBoxManager.init(this);
StandaloneDatabaseProvider databaseProvider = new StandaloneDatabaseProvider(this);
MyDownloadService.init(this,databaseProvider);
MyMediaControllerManager.getInstance().init(new MediaControllerStatusListener() {
@Override
public void onMediaControllerComplete(boolean isOk) {
CommonUtils.LogMsg("=-----mediaController+" + isOk);
}
});
}
}

View File

@ -1,78 +0,0 @@
package com.hi.music.player.adapter;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.databinding.ItemCategoryBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue;
import com.hi.music.player.javabean.response.child.ResponseCategory;
public class AdapterCategory extends BaseAdapter<ResponseCategory, ItemCategoryBinding>{
@Override
protected ItemCategoryBinding getViewBinding(ViewGroup parent) {
return ItemCategoryBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
int itemViewType = getItemViewType(position);
if (itemViewType == TYPE_ITEM) {
VHolder<ItemCategoryBinding> itemHolder = (VHolder<ItemCategoryBinding>) holder;
ItemCategoryBinding vb = itemHolder.getVb();
ResponseCategory responseCategory = data.get(position);
String pageType = responseCategory.getPageType();
Glide.with(MusicApplication.myApplication)
.asDrawable()
.load(responseCategory.getCovert())
.placeholder(R.mipmap.im_placeholder)
.into(vb.header);
vb.tvTitle.setText(responseCategory.getTwoTitle());
vb.tvSubtitle.setText(responseCategory.getTwoSubtitle());
CommonUtils.LogMsg("title="+responseCategory.getTwoTitle()+"----------pageType="+pageType
+"---browserId="+responseCategory.getBrowseId()+"---videoId="+responseCategory.getVideoId()+"---playListId="+responseCategory.getPlayListId());
if(pageType == null){
return;
}
// if(pageType.equals(MyValue.PAGE_TYPE_MV)||pageType.equals(MyValue.PAGE_TYPE_MV_LIST)){
// ViewGroup.LayoutParams layoutParams = vb.header.getLayoutParams();
// layoutParams.width = CommonUtils.dpToPx(280);
// vb.header.setLayoutParams(layoutParams);
// vb.header.setBackgroundResource(R.drawable.bg_black_13);
//
// }else {
// ViewGroup.LayoutParams layoutParams = vb.header.getLayoutParams();
// layoutParams.width = CommonUtils.dpToPx(170);
// vb.header.setLayoutParams(layoutParams);
// vb.header.setBackground(null);
// }
vb.header.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (homeItemClickListener != null) {
homeItemClickListener.onClickItemCategory(responseCategory);
}
}
});
}
}
}

View File

@ -1,105 +0,0 @@
package com.hi.music.player.adapter;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
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.helper.MyValue;
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.child.ResponseCategoryListChild;
import com.hi.music.player.javabean.response.child.ResponseSingle;
public class AdapterCategoryList extends BaseAdapter<ResponsePlayListInfo, ItemCategoryListBinding> {
private String mPageType;
public void setPageType(String mPageType) {
this.mPageType = mPageType;
}
@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;
ResponsePlayListInfo child = data.get(position);
ItemCategoryListBinding vb = itemHolder.getVb();
vb.tvSongName.setText(child.getSongTitle());
vb.tvDuration.setText(child.getDuration());
String singerName = child.getSingerName();
String describe = child.getDescribe();
switch (mPageType){
case MyValue.PAGE_TYPE_ALBUM:
vb.tvSingerName.setText(describe);
vb.imCard.setVisibility(View.GONE);
vb.tvPosition.setVisibility(View.VISIBLE);
vb.tvPosition.setText(String.valueOf(position+1));
break;
default:
vb.tvSingerName.setText(singerName);
vb.imCard.setVisibility(View.VISIBLE);
vb.tvPosition.setVisibility(View.GONE);
Glide.with(MusicApplication.myApplication)
.asDrawable()
.load(child.getSmallCovert())
.placeholder(R.mipmap.im_placeholder)
.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);
break;
}
vb.getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
homeItemClickListener.onClickItemCategoryList(child, itemHolder.getAbsoluteAdapterPosition());
}
});
if(position == data.size() - 1){
vb.place.setVisibility(View.VISIBLE);
}else {
vb.place.setVisibility(View.GONE);
}
}
}

View File

@ -1,81 +0,0 @@
package com.hi.music.player.adapter;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.media3.exoplayer.offline.Download;
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.databinding.ItemLikeSongBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.BoxDownloadSong;
import com.hi.music.player.javabean.BoxLikeSong;
public class AdapterDownloadSong extends BaseAdapter<Download, ItemLikeSongBinding> {
@Override
protected ItemLikeSongBinding getViewBinding(ViewGroup parent) {
return ItemLikeSongBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
VHolder<ItemLikeSongBinding> itemHolder = (VHolder<ItemLikeSongBinding>) holder;
ItemLikeSongBinding vb = itemHolder.getVb();
Download download = data.get(position);
BoxDownloadSong boxDownloadSong = CommonUtils.downloadToBean(download);
if (position == data.size()-1){
vb.place.setVisibility(View.VISIBLE);
}else {
vb.place.setVisibility(View.GONE);
}
vb.layoutDownload.setVisibility(View.GONE);
Glide.with(MusicApplication.myApplication)
.asDrawable()
.load(boxDownloadSong.getCovert())
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
.placeholder(R.mipmap.im_placeholder)
.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;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(vb.imCovert);
vb.tvTitle.setText(boxDownloadSong.getSongName());
vb.tvSingerName.setText(boxDownloadSong.getSingerName());
vb.getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(homeItemClickListener!= null){
int absoluteAdapterPosition = itemHolder.getAbsoluteAdapterPosition();
homeItemClickListener.onClickDownloadSong(download,absoluteAdapterPosition);
}
}
});
}
}

View File

@ -1,84 +0,0 @@
package com.hi.music.player.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.hi.music.player.MusicApplication;
import com.hi.music.player.databinding.ItemFooterLoadingBinding;
import com.hi.music.player.databinding.ItemHomeBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.response.child.ResponseCategory;
import com.hi.music.player.javabean.response.child.ResponseHomeChild;
import com.hi.music.player.javabean.response.child.ResponseSingle;
import java.util.List;
public class AdapterHome extends BaseAdapter<ResponseHomeChild, ItemHomeBinding> {
@Override
protected ItemHomeBinding getViewBinding(ViewGroup parent) {
return ItemHomeBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
int itemViewType = getItemViewType(position);
if (itemViewType == TYPE_ITEM) {
VHolder<ItemHomeBinding> itemHolder = (VHolder<ItemHomeBinding>) holder;
ItemHomeBinding vb = itemHolder.getVb();
ResponseHomeChild responseHomeChild = data.get(position);
vb.headTitle.setText(responseHomeChild.getHeaderTitle());
List<ResponseSingle> singleList = responseHomeChild.getSingleList();
List<ResponseCategory> categoryList = responseHomeChild.getCategoryList();
CommonUtils.LogMsg("position="+position+"-----------headTitle-=" + responseHomeChild.getHeaderTitle()+"--singleList="+singleList+"---categoryList="+categoryList);
if (singleList != null && singleList.size() > 0) {
vb.recyclerSinger.setVisibility(View.VISIBLE);
AdapterSinger adapterSinger = new AdapterSinger();
adapterSinger.setHomeItemClickListener(homeItemClickListener);
adapterSinger.addData(singleList);
vb.recyclerSinger.setLayoutManager(new GridLayoutManager(MusicApplication.myApplication, 4, RecyclerView.HORIZONTAL, false));
vb.recyclerSinger.setAdapter(adapterSinger);
} else {
vb.recyclerSinger.setVisibility(View.GONE);
}
if (categoryList != null && categoryList.size() > 0) {
vb.recyclerCategory.setVisibility(View.VISIBLE);
AdapterCategory adapterCategory = new AdapterCategory();
adapterCategory.setHomeItemClickListener(homeItemClickListener);
adapterCategory.addData(categoryList);
vb.recyclerCategory.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication, RecyclerView.HORIZONTAL, false));
vb.recyclerCategory.setAdapter(adapterCategory);
} else {
vb.recyclerCategory.setVisibility(View.GONE);
}
if(position == data.size() - 1){
vb.place.setVisibility(View.VISIBLE);
}else {
vb.place.setVisibility(View.GONE);
}
} else {
VHolder<ItemFooterLoadingBinding> footerHolder = (VHolder<ItemFooterLoadingBinding>) holder;
FrameLayout root = footerHolder.getVb().getRoot();
if (isLoadingAdded) {
root.setVisibility(View.VISIBLE);
} else {
root.setVisibility(View.GONE);
}
}
}
}

View File

@ -1,215 +0,0 @@
package com.hi.music.player.adapter;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.lifecycle.Observer;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.offline.Download;
import androidx.media3.exoplayer.offline.DownloadRequest;
import androidx.media3.exoplayer.offline.DownloadService;
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.google.gson.Gson;
import com.hi.music.player.MusicApplication;
import com.hi.music.player.R;
import com.hi.music.player.api.onCheckDownload;
import com.hi.music.player.databinding.ItemLikeSongBinding;
import com.hi.music.player.databinding.ItemSingerBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.BoxDownloadSong;
import com.hi.music.player.javabean.BoxLikeSong;
import com.hi.music.player.javabean.CustomerDownload;
import com.hi.music.player.javabean.response.ResponsePlayUrl;
import com.hi.music.player.javabean.response.child.ResponseSingle;
import com.hi.music.player.media3.MyDownloadService;
import com.hi.music.player.media3.MyMediaControllerManager;
import com.hi.music.player.network.JsonHelper;
import com.hi.music.player.network.RetrofitManager;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
import org.json.JSONObject;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import okhttp3.ResponseBody;
public class AdapterLikeSong extends BaseAdapter<BoxLikeSong, ItemLikeSongBinding> {
private VMApplication vmApplication;
private List<Pair<Boolean, String>> status = new ArrayList<>();
@Override
protected ItemLikeSongBinding getViewBinding(ViewGroup parent) {
return ItemLikeSongBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
}
public AdapterLikeSong(Context mContext, VMApplication vm) {
super(mContext);
vmApplication = vm;
}
public void updateDownloadStatus(boolean isSuccess, int position, String videoId) {
status.add(new Pair<>(isSuccess, videoId));
notifyItemChanged(position);
}
@OptIn(markerClass = UnstableApi.class)
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
VHolder<ItemLikeSongBinding> itemHolder = (VHolder<ItemLikeSongBinding>) holder;
ItemLikeSongBinding vb = itemHolder.getVb();
BoxLikeSong boxLikeSong = data.get(position);
String videoId = boxLikeSong.getVideoId();
if (position == data.size()-1){
vb.place.setVisibility(View.VISIBLE);
}else {
vb.place.setVisibility(View.GONE);
}
for(Pair<Boolean,String> pair:status){
if(pair.second.equals(videoId)){
vb.imDownload.setSelected(pair.first);
vb.imDownload.setVisibility(View.VISIBLE);
vb.downloadPb.setVisibility(View.GONE);
CommonUtils.LogMsg("--------------------状态更新");
}
}
MyDownloadService.queryIsDownload(videoId, new onCheckDownload() {
@Override
public void onHasDownload(CustomerDownload customerDownload) {
boolean download = customerDownload.isDownload();
if (download) {
vb.imDownload.setSelected(true);
} else {
vb.imDownload.setSelected(false);
}
}
});
vb.layoutDownload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (vb.imDownload.isSelected()) {
//已经下载
Toast.makeText(mContext,mContext.getText(R.string.text_has_downloaded),Toast.LENGTH_SHORT).show();
return;
}
vb.imDownload.setVisibility(View.GONE);
vb.downloadPb.setVisibility(View.VISIBLE);
RetrofitManager.getInstance().getPlayUrl(videoId, new com.hi.music.player.api.RequestListener<ResponseBody>() {
@Override
public void onFail(String errorMsg) {
CommonUtils.LogMsg("-------------onFail");
}
@Override
public void onSuccess(JSONObject data) {
// JSONObject jsonObject = CommonUtils.toJsonObject(data);
if (data != null) {
ResponsePlayUrl responsePlayUrl = JsonHelper.ResolvePlayUrlJson(data);
if (responsePlayUrl == null) {
// TODO: 2024/9/27
return;
}
String videoUrlMedium = responsePlayUrl.getVideoUrlMedium();
BoxDownloadSong downloadSong = new BoxDownloadSong();
downloadSong.setVideoId(videoId);
downloadSong.setCovert(String.valueOf(boxLikeSong.getCovert()));
downloadSong.setSongName((String) boxLikeSong.getSongName());
downloadSong.setSingerName((String) boxLikeSong.getSingerName());
downloadSong.setDuration((String) boxLikeSong.getDuration());
downloadSong.setDurationMs(boxLikeSong.getDurationMs());
downloadSong.setVideoUrl(videoUrlMedium);
Gson gson = new Gson();
String info = gson.toJson(downloadSong);
byte[] bytes = info.getBytes(StandardCharsets.UTF_8);
DownloadRequest downloadRequest = new DownloadRequest.Builder(videoId, Uri.parse(videoUrlMedium))
.setMimeType("video/mp4")
.setData(bytes)
.build();
DownloadService.sendAddDownload(
mContext,
MyDownloadService.class, // 上面定义的下载服务类
downloadRequest,
true // 是否在前台运行
);
if (homeItemClickListener != null) {
homeItemClickListener.onDownloadSong(videoId, itemHolder.getAbsoluteAdapterPosition());
}
}
}
});
}
});
Glide.with(MusicApplication.myApplication)
.asDrawable()
.load(boxLikeSong.getCovert())
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
.placeholder(R.mipmap.im_placeholder)
.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;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(vb.imCovert);
vb.tvTitle.setText(boxLikeSong.getSongName());
vb.tvSingerName.setText(boxLikeSong.getSingerName());
vb.getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (homeItemClickListener != null) {
int absoluteAdapterPosition = itemHolder.getAbsoluteAdapterPosition();
homeItemClickListener.onClickLikeSong(boxLikeSong, absoluteAdapterPosition);
}
}
});
}
}

View File

@ -1,118 +0,0 @@
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.api.MediaControllerListener;
import com.hi.music.player.databinding.ItemPlayListBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue;
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.media3.MyMediaControllerManager;
public class AdapterPlayList extends BaseAdapter<ResponsePlayListInfo, ItemPlayListBinding> {
private String mCurVideId;
private String lastVideId;
// private int curMusicPos = 0;
private MyMediaControllerManager instance = MyMediaControllerManager.getInstance();
@Override
protected ItemPlayListBinding getViewBinding(ViewGroup parent) {
return ItemPlayListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
}
public void setCurVideId(String curVideId) {
lastVideId = mCurVideId;
this.mCurVideId = curVideId;
for (int i = 0; i < data.size(); i++) {
ResponsePlayListInfo listInfo = data.get(i);
if (listInfo.getVideoId().equals(curVideId)) {
notifyItemChanged(i);
}
if (listInfo.getVideoId().equals(lastVideId)) {
notifyItemChanged(i);
}
}
}
public void updateCurMusicAnimation() {
int curIndex = instance.getCurIndex();
CommonUtils.LogMsg("--curIndex=" + curIndex);
notifyItemChanged(curIndex);
}
@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();
vb.songName.setText(listInfo.getSongTitle());
String singerName = listInfo.getSingerName();
String describe = listInfo.getDescribe();
if (singerName != null && !singerName.isEmpty()) {
vb.artistName.setText(singerName);
} else if (describe != null && !describe.isEmpty()) {
vb.artistName.setText(describe);
}
String covert;
String small = listInfo.getSmallCovert();
String covert1 = listInfo.getCovert();
if (small == null || small.isEmpty()) {
covert = covert1;
} else {
covert = small;
}
Glide.with(MusicApplication.myApplication)
.asDrawable()
// .apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(10))))
.load(covert)
.placeholder(R.mipmap.im_placeholder)
.into(vb.imCovert);
MediaItem currentMediaItem = instance.getCurMediaItem();
if (currentMediaItem != null && currentMediaItem.mediaId.equals(listInfo.getVideoId())) {
vb.viewPlaying.setVisibility(View.VISIBLE);
vb.itemLayout.setBackgroundColor(CommonUtils.getMyColor(R.color.cur_play_music));
if (instance.getIsPlaying()) {
vb.viewPlaying.startAnimating();
lastVideId = listInfo.getVideoId();
CommonUtils.LogMsg("-------playAnimation " + itemHolder.getAbsoluteAdapterPosition());
} else {
vb.viewPlaying.pauseAnimating();
CommonUtils.LogMsg("-------pauseAnimation " + itemHolder.getAbsoluteAdapterPosition());
}
} else {
vb.viewPlaying.setVisibility(View.GONE);
vb.itemLayout.setBackgroundColor(CommonUtils.getMyColor(R.color.color_transparent));
}
vb.itemLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CommonUtils.LogMsg("-------onClick curMusicPos=" + itemHolder.getAbsoluteAdapterPosition());
setCurVideId(listInfo.getVideoId());
instance.playPositionMusic(itemHolder.getAbsoluteAdapterPosition());
}
});
}
}

View File

@ -1,81 +0,0 @@
package com.hi.music.player.adapter;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.databinding.ItemResultListAlbumBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.response.child.ResponseResultListChild;
public class AdapterResultListAlbum extends BaseAdapter<ResponseResultListChild, ItemResultListAlbumBinding>{
@Override
protected ItemResultListAlbumBinding getViewBinding(ViewGroup parent) {
return ItemResultListAlbumBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ResponseResultListChild listChild = data.get(position);
VHolder<ItemResultListAlbumBinding> itemHolder = (VHolder<ItemResultListAlbumBinding>) holder;
ItemResultListAlbumBinding vb = itemHolder.getVb();
if(position == data.size()-1){
vb.view.setVisibility(View.VISIBLE);
}else {
vb.view.setVisibility(View.GONE);
}
Glide.with(MusicApplication.myApplication)
.asDrawable()
.load(listChild.getThumbnail())
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
.placeholder(R.mipmap.im_placeholder)
.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;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(vb.header);
vb.tvTitle.setText(listChild.getSongName());
vb.tvSubtitle.setText(listChild.getSubTitle());
vb.header.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(homeItemClickListener != null){
int absoluteAdapterPosition = itemHolder.getAbsoluteAdapterPosition();
String videoId = listChild.getVideoId();
String browserId = listChild.getBrowserId();
homeItemClickListener.onClickResultSong(listChild,absoluteAdapterPosition);
// if(videoId == null||videoId.isEmpty()){
// homeItemClickListener.onClickResultAlbum(listChild,absoluteAdapterPosition);
// }else if(browserId!= null&&!browserId.isEmpty()){
// homeItemClickListener.onClickResultSong(listChild,absoluteAdapterPosition);
// }
}
}
});
CommonUtils.LogMsg("-------Album getBrowserId="+listChild.getBrowserId()+"---getPlayListId= "+listChild.getPlayListId()+"---getVideoId="+listChild.getVideoId());
}
}

View File

@ -1,83 +0,0 @@
package com.hi.music.player.adapter;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.databinding.ItemResultListSongBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.response.child.ResponseResultListChild;
public class AdapterResultListSong extends BaseAdapter<ResponseResultListChild, ItemResultListSongBinding> {
@Override
protected ItemResultListSongBinding getViewBinding(ViewGroup parent) {
return ItemResultListSongBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ResponseResultListChild listChild = data.get(position);
VHolder<ItemResultListSongBinding> itemHolder = (VHolder<ItemResultListSongBinding>) holder;
ItemResultListSongBinding vb = itemHolder.getVb();
Glide.with(MusicApplication.myApplication)
.asDrawable()
.load(listChild.getThumbnail())
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
.placeholder(R.mipmap.im_placeholder)
.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;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(vb.imCovert);
vb.tvSongName.setText(listChild.getSongName());
String playCount = listChild.getPlayCount();
String subTitle = listChild.getSubTitle();
if (playCount == null){
vb.tvSubtitle.setText(subTitle);
}else {
String s = subTitle + "" + playCount;
vb.tvSubtitle.setText(s);
}
vb.getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (homeItemClickListener != null) {
int absoluteAdapterPosition = itemHolder.getAbsoluteAdapterPosition();
String videoId = listChild.getVideoId();
String browserId = listChild.getBrowserId();
homeItemClickListener.onClickResultSong(listChild, absoluteAdapterPosition);
}
}
});
CommonUtils.LogMsg("-------Song getBrowserId=" + listChild.getBrowserId() + "---getPlayListId= " + listChild.getPlayListId() + "---getVideoId=" + listChild.getVideoId());
}
}

View File

@ -1,71 +0,0 @@
package com.hi.music.player.adapter;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.databinding.ItemSearchBinding;
import com.hi.music.player.databinding.ItemSearchChildBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.response.ResponseSearch;
import com.hi.music.player.javabean.response.child.ResponseSearchChild;
public class AdapterSearchChild extends BaseAdapter<ResponseSearchChild, ItemSearchChildBinding> {
@Override
protected ItemSearchChildBinding getViewBinding(ViewGroup parent) {
return ItemSearchChildBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ResponseSearchChild responseSearchChild = data.get(position);
VHolder<ItemSearchChildBinding> itemHolder = (VHolder<ItemSearchChildBinding>) holder;
ItemSearchChildBinding vb = itemHolder.getVb();
Glide.with(MusicApplication.myApplication)
.asDrawable()
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(13))))
.load(responseSearchChild.getSongCovert())
.placeholder(R.mipmap.im_placeholder)
.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;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(vb.imCovert);
vb.tvTitle.setText(responseSearchChild.getSongTitle());
vb.tvSubtitle.setText(responseSearchChild.getSongDescribe());
vb.getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (homeItemClickListener != null) {
homeItemClickListener.onClickSearchResult(responseSearchChild);
}
}
});
}
}

View File

@ -1,77 +0,0 @@
package com.hi.music.player.adapter;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.databinding.ItemSingerBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.response.child.ResponseSingle;
public class AdapterSinger extends BaseAdapter<ResponseSingle, ItemSingerBinding> {
@Override
protected ItemSingerBinding getViewBinding(ViewGroup parent) {
return ItemSingerBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
int itemViewType = getItemViewType(position);
if (itemViewType == TYPE_ITEM) {
VHolder<ItemSingerBinding> itemHolder = (VHolder<ItemSingerBinding>) holder;
ItemSingerBinding vb = itemHolder.getVb();
ResponseSingle responseSingle = data.get(position);
Glide.with(MusicApplication.myApplication)
.asDrawable()
.load(responseSingle.getSingerHead())
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
.placeholder(R.mipmap.im_placeholder)
.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;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(vb.header);
vb.tvSingerName.setText(responseSingle.getSingerName());
vb.tvSongName.setText(responseSingle.getSongTitle());
// vb.tvDescribe.setText(responseSingle.getDescription());
vb.getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (homeItemClickListener != null) {
homeItemClickListener.onClickItemSinger(responseSingle);
}
}
});
}
}
}

View File

@ -1,127 +0,0 @@
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 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;
@Override
protected DialogPlayListBinding getViewBinding(LayoutInflater inflater, ViewGroup container) {
return DialogPlayListBinding.inflate(inflater, container, false);
}
@Override
protected void initView() {
instance = MyMediaControllerManager.getInstance();
initPlayListUi();
MediaItem currentMediaItem = instance.getCurMediaItem();
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.im_placeholder)
.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.getIsPlaying());
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);
}
}

View File

@ -1,36 +0,0 @@
package com.hi.music.player.javabean.requestbody.child;
import java.io.Serializable;
import java.util.Locale;
public class ContextBody {
private Client client = new Client();
private ThirdParty thirdParty = new ThirdParty();
// public ThirdParty getThirdParty() {
// return thirdParty;
// }
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public static class ThirdParty{
//https://www.youtube.com/watch?v=UqyT8IEBkvY
private String embedUrl;
public void setEmbedUrl(String embedUrl) {
this.embedUrl = embedUrl;
}
}
}

View File

@ -1,199 +0,0 @@
package com.hi.music.player.media3;
import android.app.Notification;
import android.content.Context;
import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.database.StandaloneDatabaseProvider;
import androidx.media3.datasource.DefaultHttpDataSource;
import androidx.media3.datasource.cache.SimpleCache;
import androidx.media3.exoplayer.offline.Download;
import androidx.media3.exoplayer.offline.DownloadCursor;
import androidx.media3.exoplayer.offline.DownloadIndex;
import androidx.media3.exoplayer.offline.DownloadManager;
import androidx.media3.exoplayer.offline.DownloadNotificationHelper;
import androidx.media3.exoplayer.offline.DownloadService;
import androidx.media3.exoplayer.scheduler.Scheduler;
import com.hi.music.player.R;
import com.hi.music.player.api.onCheckDownload;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.CustomerDownload;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
@UnstableApi
public class MyDownloadService extends DownloadService {
private static final int FOREGROUND_NOTIFICATION_ID = 1;
private static final String CHANNEL_ID = "download_song_channel_id";
private static DownloadManager mDownloadManager;
private static SimpleCache downloadCache;
public MyDownloadService() {
super(FOREGROUND_NOTIFICATION_ID,
DEFAULT_FOREGROUND_NOTIFICATION_UPDATE_INTERVAL,
CHANNEL_ID, // 通知渠道 ID
R.string.app_name, // 通知渠道名称
0
);
}
public static SimpleCache getDownloadCache() {
return downloadCache;
}
public static void init(Context context, StandaloneDatabaseProvider databaseProvider) {
if (mDownloadManager == null) {
downloadCache = MyDownloadCacheManager.getMyCache(databaseProvider);
DefaultHttpDataSource.Factory factory = new DefaultHttpDataSource.Factory();
Executor downloadExecutor = Runnable::run;
mDownloadManager = new DownloadManager(
context,
databaseProvider, // 数据库提供者
downloadCache,
factory, // 数据源工厂
downloadExecutor // 线程池
);
mDownloadManager.setMaxParallelDownloads(3); // 设置最大并行下载数
}
}
public static synchronized DownloadManager getMyDownloadManager() {
return mDownloadManager;
}
public static void addDownloadListener(VMApplication vmApplication) {
mDownloadManager.addListener(new DownloadManager.Listener() {
@Override
public void onDownloadChanged(@NonNull DownloadManager downloadManager, Download download, @Nullable Exception finalException) {
String id = download.request.id;
if (download.state == Download.STATE_COMPLETED) {
// 下载完成
vmApplication.setDownloadChange(new Pair<>(true, download));
CommonUtils.LogMsg("----------------下载完成 id=" + id + "--thread=" + Thread.currentThread().getName());
updateDownloadUi(vmApplication);
} else if (download.state == Download.STATE_FAILED) {
// 下载失败
CommonUtils.LogMsg("----------------下载失败 id=" + id + "---finalException=" + finalException.getMessage());
vmApplication.setDownloadChange(new Pair<>(false, download));
}
}
@Override
public void onDownloadRemoved(DownloadManager downloadManager, Download download) {
String id = download.request.id;
CommonUtils.LogMsg("----------------onDownloadRemoved id=" + id);
}
});
}
public static void queryIsDownload(String videoId, onCheckDownload listener) {
Disposable subscribe = Observable.fromCallable(() -> {
// 不允许返回null所以采用CustomerDownload类包装
DownloadIndex downloadIndex = mDownloadManager.getDownloadIndex();
Download download = downloadIndex.getDownload(videoId);
return new CustomerDownload(download, download != null);
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(listener::onHasDownload);
}
/**
* 下载完成的数量增加
*
* @param vmApplication
*/
@UnstableApi
public static void updateDownloadUi(VMApplication vmApplication) {
Disposable subscribe = Observable.fromCallable(() -> {
// 第一部分操作在IO线程
DownloadIndex downloadIndex = mDownloadManager.getDownloadIndex();
DownloadCursor downloads = downloadIndex.getDownloads(Download.STATE_COMPLETED);
return downloads;
})
.subscribeOn(Schedulers.io())
// .observeOn(Schedulers.computation()) // 切换到计算线程
// .map(result -> {
// // 第二部分操作在computation线程
// return result + " -> Step 2 completed";
// })
.observeOn(AndroidSchedulers.mainThread()) // 切换到主线程
.subscribe(finalResult -> {
// 最终结果处理在主线程
Download curDownload = null;
// int count = finalResult.getCount();
// if (finalResult.moveToLast()) {
// curDownload = finalResult.getDownload();
// }
List<Download> downloadList = new ArrayList<>();
while (finalResult.moveToNext()) {
Download download = finalResult.getDownload();
downloadList.add(download);
}
CommonUtils.LogMsg("----------------下载总数量 -count=" + downloadList.size());
vmApplication.setDownloadData(downloadList);
});
}
@NonNull
@Override
protected DownloadManager getDownloadManager() {
return getMyDownloadManager();
}
@Nullable
@Override
protected Scheduler getScheduler() {
// 返回 null 表示不需要使用调度器
return null;
}
@Override
protected Notification getForegroundNotification(List<Download> downloads, int notMetRequirements) {
// 构建用于显示下载进度的通知
return buildNotification(downloads, notMetRequirements);
}
private Notification buildNotification(
List<Download> downloads, int notMetRequirements) {
return new DownloadNotificationHelper(this, CHANNEL_ID)
.buildProgressNotification(this, R.drawable.ic_download, null, null, downloads, notMetRequirements);
}
}

View File

@ -1,421 +0,0 @@
package com.hi.music.player.media3;
import android.content.ComponentName;
import android.net.Uri;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MediaMetadata;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.session.MediaController;
import androidx.media3.session.SessionToken;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import com.hi.music.player.MusicApplication;
import com.hi.music.player.api.MediaControllerListener;
import com.hi.music.player.api.MediaControllerStatusListener;
import com.hi.music.player.api.OnHasUrlAction;
import com.hi.music.player.api.onCheckDownload;
import com.hi.music.player.api.onPlayNextListener;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue;
import com.hi.music.player.javabean.CustomerDownload;
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.ResponsePlayUrl;
import com.hi.music.player.network.RetrofitManager;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class MyMediaControllerManager {
private static volatile MyMediaControllerManager myMediaControllerManagerInstance;
private MediaController mediaController;
private MediaControllerListener mListener;
private VMApplication mVmApplication;
//播放列表总数量
private List<ResponsePlayListInfo> playList;
public static MyMediaControllerManager getInstance() {
if (myMediaControllerManagerInstance == null) {
synchronized (RetrofitManager.class) {
if (myMediaControllerManagerInstance == null) {
myMediaControllerManagerInstance = new MyMediaControllerManager();
}
}
}
return myMediaControllerManagerInstance;
}
public void init(MediaControllerStatusListener statusListener) {
SessionToken sessionToken =
new SessionToken(MusicApplication.myApplication, new ComponentName(MusicApplication.myApplication, PlaybackService.class));
ListenableFuture<MediaController> controllerFuture =
new MediaController.Builder(MusicApplication.myApplication, sessionToken).buildAsync();
controllerFuture.addListener(() -> {
// Call controllerFuture.get() to retrieve the MediaController.
// MediaController implements the Player interface, so it can be
// attached to the PlayerView UI component.
// playerView.setPlayer(controllerFuture.get());
try {
mediaController = controllerFuture.get();
statusListener.onMediaControllerComplete(true);
CommonUtils.LogMsg("=-----mediaController+" + mediaController);
} catch (ExecutionException | InterruptedException e) {
CommonUtils.LogErrorMsg(e.getMessage());
statusListener.onMediaControllerComplete(false);
}
}, MoreExecutors.directExecutor());
}
public void addListener(VMApplication vmApplication, MediaControllerListener listener) {
mVmApplication = vmApplication;
mListener = listener;
mediaController.addListener(new Player.Listener() {
@Override
public void onPlayerError(PlaybackException error) {
mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_ERROR);
mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CODE_ERROR);
}
@Override
public void onPlaylistMetadataChanged(MediaMetadata mediaMetadata) {
}
@Override
public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
//当前媒体项发生变化切歌
if (mediaItem == null) {
//第二次进入PlayActitivity 调用resetPlayList这里为null
return;
}
mListener.onChangeMusic(mediaItem);
mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CHANGE_MUSIC);
}
@Override
public void onIsPlayingChanged(boolean isPlaying) {
if (isPlaying) {
mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_PLAYING);
mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CODE_PLAYING);
// TODO: 2024/10/15 自动播放完成切歌到下一首播放没有触发这里请求下一首
checkUrl(false);
} else {
// 播放器暂停或停止
mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_PAUSE);
mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CODE_PAUSE);
}
}
@Override
public void onPlaybackStateChanged(int playbackState) {
mListener.onPlayStatus(playbackState);
mVmApplication.setPlayStatus(playbackState);
}
@Override
public void onPositionDiscontinuity(Player.PositionInfo oldPosition, Player.PositionInfo newPosition, int reason) {
// 快进快退等操作
// CommonUtils.LogMsg("=-----快进、快退+" + newPosition.positionMs);
// mediaControllerListener.onPlayStatus(playbackState);
}
});
}
public void checkUrl(boolean playNextNow) {
if (mediaController.hasNextMediaItem()) {
int nextMediaItemIndex = mediaController.getNextMediaItemIndex();
onCallRequestUrl(nextMediaItemIndex, playNextNow, new OnHasUrlAction() {
@Override
public void onHasUrl() {
CommonUtils.LogMsg("-------------有有效URl--播放检查下一首 位置=" + nextMediaItemIndex);
}
});
}
if (mediaController.hasPreviousMediaItem()) {
int previousMediaItemIndex = mediaController.getPreviousMediaItemIndex();
onCallRequestUrl(previousMediaItemIndex, false, new OnHasUrlAction() {
@Override
public void onHasUrl() {
CommonUtils.LogMsg("-------------有有效URl--播放检查上一首 位置=" + previousMediaItemIndex);
}
});
}
}
public MediaController getMediaController() {
return mediaController;
}
/**
* 针对已经下载过的数据从download构造出MediaItem 直接替换
* @param index
* @param mediaItem
*/
public void replaceMediaItem(int index, MediaItem mediaItem) {
mediaController.replaceMediaItem(index, mediaItem);
}
public long getContentPos() {
if (mediaController == null) return 0;
return mediaController.getContentPosition();
}
public long getBufferPos() {
if (mediaController == null) return 0;
return mediaController.getBufferedPosition();
}
public MediaItem getCurMediaItem() {
return mediaController.getCurrentMediaItem();
}
public Boolean getIsPlaying() {
return mediaController.isPlaying();
}
public int getCurIndex() {
return mediaController.getCurrentMediaItemIndex();
}
/**
* //0 不循环1 单曲循环2 列表循环
*
* @param mode
*/
public void setMode(int mode) {
switch (mode) {
case 0:
mediaController.setRepeatMode(Player.REPEAT_MODE_OFF);
break;
case 1:
mediaController.setRepeatMode(Player.REPEAT_MODE_ONE);
break;
case 2:
mediaController.setRepeatMode(Player.REPEAT_MODE_ALL);
break;
}
}
public int getRepeatMode() {
return mediaController.getRepeatMode();
}
public String getCurVideoId() {
MediaItem currentMediaItem = mediaController.getCurrentMediaItem();
if (currentMediaItem != null) {
return currentMediaItem.mediaId;
} else {
return null;
}
}
/**
* 更新播放列表中的音频url
*
* @param playUrl
*/
@OptIn(markerClass = UnstableApi.class)
public void UpdateAudioUrl(ResponsePlayUrl playUrl, int index) {
for (int i = 0; i < mediaController.getMediaItemCount(); i++) {
MediaItem mediaItemAt = mediaController.getMediaItemAt(i);
if (mediaItemAt.mediaId.equals(playUrl.getVideoId())) {
MediaItem.Builder builder = mediaItemAt.buildUpon();
builder.setMediaId(playUrl.getVideoId());
builder.setUri(playUrl.getVideoUrlMedium());
// builder.setCustomCacheKey(playUrl.getVideoUrlMedium());
//针对于已经从分类合集列表页面进入播放页面的数据(只有小的封面图)
if (mediaItemAt.mediaMetadata.artworkUri == null) {
MediaMetadata.Builder builder1 = mediaItemAt.mediaMetadata.buildUpon();
builder1.setArtworkUri(Uri.parse(playUrl.getBigCovert()));
builder.setMediaMetadata(builder1.build());
}
CharSequence title = mediaController.getMediaItemAt(i).mediaMetadata.title;
CommonUtils.LogMsg("-------------更新播放列表中的音频--id=" + playUrl.getVideoId());
mediaController.replaceMediaItem(i, builder.build());
break;
}
}
}
public void setPlayList(List<ResponsePlayListInfo> playList) {
this.playList = playList;
addMusicPlayList(playList);
}
public List<ResponsePlayListInfo> getPlayList() {
return playList;
}
public void resetPlayList() {
mediaController.clearMediaItems();
}
/**
* 添加播放列表不带音频url
* 注意没有setUri的不会被实际添加到mediaController(mediaController.getMediaItemCount())
* 这里setUri 一个占位
*
* @param listInfo
*/
@OptIn(markerClass = UnstableApi.class)
public void addMusicPlayList(List<ResponsePlayListInfo> listInfo) {
playList = listInfo;
for (int i = 0; i < listInfo.size(); i++) {
ResponsePlayListInfo playInfo = listInfo.get(i);
MediaItem.Builder builder = new MediaItem.Builder();
String videoId = playInfo.getVideoId();
//唯一标识符
builder.setMediaId(videoId);
builder.setUri("-------test-----");
builder.setCustomCacheKey(videoId);
MediaMetadata.Builder MediaMetadata_builder = new MediaMetadata.Builder();
MediaMetadata_builder.setArtist(playInfo.getSingerName());
MediaMetadata_builder.setDescription(playInfo.getDuration());
MediaMetadata_builder.setDurationMs(playInfo.getDurationMs());
if (playInfo.getCovert() != null && !playInfo.getCovert().isEmpty())
MediaMetadata_builder.setArtworkUri(Uri.parse(playInfo.getCovert()));
MediaMetadata_builder.setTitle(playInfo.getSongTitle());
CommonUtils.LogMsg("----------添加播放列表 i=" + i + "---" + playInfo.getSingerName() + "-------VideoId=" + videoId + "---playInfo.getDuration()=" + playInfo.getDuration());
// MediaMetadata_builder.setRecordingYear(Integer.parseInt(playInfo.getYear()));
builder.setMediaMetadata(MediaMetadata_builder.build());
mediaController.addMediaItem(builder.build());
}
}
public void addMusicPlayList(MediaItem mediaItem) {
mediaController.addMediaItem(mediaItem);
}
public void play() {
if (!mediaController.isPlaying()) {
CommonUtils.LogMsg("-----------prepare");
mediaController.prepare();
mediaController.play();
}
}
public void pause() {
if (mediaController.isPlaying())
mediaController.pause();
}
public void stop() {
if (mediaController.isPlaying())
mediaController.stop();
}
public void playNext(onPlayNextListener listener) {
if (mediaController.hasNextMediaItem()) {
int nextMediaItemIndex = mediaController.getNextMediaItemIndex();
onCallRequestUrl(nextMediaItemIndex, true, new OnHasUrlAction() {
@Override
public void onHasUrl() {
mediaController.seekToNextMediaItem();
mediaController.play();
}
});
} else {
listener.onPlayNext(false);
}
}
public void playPrevious() {
if (mediaController.hasPreviousMediaItem()) {
int previousMediaItemIndex = mediaController.getPreviousMediaItemIndex();
onCallRequestUrl(previousMediaItemIndex, true, new OnHasUrlAction() {
@Override
public void onHasUrl() {
mediaController.seekToPreviousMediaItem();
mediaController.play();
}
});
} else {
mediaController.seekTo(0);
mediaController.play();
}
}
/**
* 播放指定播放列表位置的歌曲
*
* @param index
*/
public void playPositionMusic(int index) {
if (index >= mediaController.getMediaItemCount()) {
CommonUtils.LogErrorMsg("-------------数组越界");
return;
}
stop();
mediaController.seekTo(index, 0);
onCallRequestUrl(index, true, new OnHasUrlAction() {
@Override
public void onHasUrl() {
mediaController.play();
CommonUtils.LogMsg("-------------有有效URl--播放指定播放列表位置的歌曲 index=" + index);
}
});
}
@OptIn(markerClass = UnstableApi.class)
private void onCallRequestUrl(int index, boolean playNow, OnHasUrlAction action) {
MediaItem mediaItemAt = mediaController.getMediaItemAt(index);
boolean b = CommonUtils.hasValidUri(mediaItemAt);
if (!b) {
//查看
MyDownloadService.queryIsDownload(mediaItemAt.mediaId, new onCheckDownload() {
@Override
public void onHasDownload(CustomerDownload customerDownload) {
if (customerDownload.isDownload()) {
MediaItem mediaItem = CommonUtils.downloadToMediaItem(customerDownload.getDownloadData());
mediaController.replaceMediaItem(index, mediaItem);
CommonUtils.LogMsg("-------------请求URl 已经下载过 index" + index + "---playNow=" + playNow);
} else {
CommonUtils.LogMsg("-------------请求URl index" + index + "---playNow=" + playNow);
mListener.onRequestNextUri(mediaItemAt.mediaId, index, playNow);
}
}
});
} else {
action.onHasUrl();
}
}
}

View File

@ -1,36 +0,0 @@
package com.hi.music.player.media3;
import android.content.Context;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.database.StandaloneDatabaseProvider;
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor;
import androidx.media3.datasource.cache.SimpleCache;
import java.io.File;
/**
* 播放缓存
*/
public class MyPlayCacheManager {
private static SimpleCache playCache;
@OptIn(markerClass = UnstableApi.class)
public static SimpleCache getInitPlayCache(Context context) {
if (playCache == null) {
File cacheDir = new File(context.getCacheDir(), "media_cache");
long maxCacheSize = 100 * 1024 * 1024; // 缓存大小 100MB
StandaloneDatabaseProvider databaseProvider = new StandaloneDatabaseProvider(context);
playCache = new SimpleCache(cacheDir, new LeastRecentlyUsedCacheEvictor(maxCacheSize), databaseProvider);
// MyDownloadService.init(context,databaseProvider);
}
return playCache;
}
public static SimpleCache getPlayCache() {
return playCache;
}
}

View File

@ -1,176 +0,0 @@
package com.hi.music.player.media3;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DataSpec;
import androidx.media3.datasource.DefaultDataSource;
import androidx.media3.datasource.DefaultHttpDataSource;
import androidx.media3.datasource.ResolvingDataSource;
import androidx.media3.datasource.TransferListener;
import androidx.media3.datasource.cache.CacheDataSource;
import androidx.media3.datasource.cache.SimpleCache;
import androidx.media3.exoplayer.DefaultLoadControl;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.media3.session.MediaSession;
import androidx.media3.session.MediaSessionService;
import com.hi.music.player.helper.CommonUtils;
import java.io.IOException;
public class PlaybackService extends MediaSessionService {
private MediaSession mediaSession = null;
private ExoPlayer player;
private SimpleCache playCache, downloadCache;
@OptIn(markerClass = UnstableApi.class)
@Override
public void onCreate() {
super.onCreate();
DynamicMediaSourceFactory customMediaSourceFactory = new DynamicMediaSourceFactory(getCacheDataSourceFactory(this));
ProgressiveMediaSource.Factory factory = new ProgressiveMediaSource.Factory(getUrlFactory());
// 创建 DefaultLoadControl配置缓冲参数
DefaultLoadControl loadControl = new DefaultLoadControl.Builder()
.setBufferDurationsMs(3000, // minBufferMs: 播放前的最小缓冲时间毫秒
300000, // maxBufferMs: 最大缓冲时间毫秒
3000, // bufferForPlaybackMs: 播放时的目标缓冲时间毫秒
2000) // bufferForPlaybackAfterRebufferMs: 重新缓冲后的缓冲时间毫秒)
.build();
CacheDataSource.Factory cacheDataSourceFactory = getCacheDataSourceFactory(this);
MediaSource.Factory mediaSourceFactory = new ProgressiveMediaSource.Factory(cacheDataSourceFactory);
CacheDataSource dataSource = cacheDataSourceFactory.createDataSource();
player = new ExoPlayer.Builder(this)
.setMediaSourceFactory(factory)
.setLoadControl(loadControl)
.build();
mediaSession = new MediaSession.Builder(this, player)
.build();
}
// 创建带缓存的数据源工厂
@OptIn(markerClass = UnstableApi.class)
private CacheDataSource.Factory getCacheDataSourceFactory(Context context) {
DefaultDataSource.Factory factory = new DefaultDataSource.Factory(this);
playCache = MyPlayCacheManager.getInitPlayCache(context);
CacheDataSource.Factory factory1 = new CacheDataSource.Factory().setCache(playCache)
.setUpstreamDataSourceFactory(new DefaultHttpDataSource.Factory()
.setConnectTimeoutMs(16000)
.setReadTimeoutMs(8000)
.setUserAgent("Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0"))
.setEventListener(new CacheDataSource.EventListener() {
@Override
public void onCachedBytesRead(long cacheSizeBytes, long cachedBytesRead) {
CommonUtils.LogMsg("-----------缓存2 -PlayCache-" + cacheSizeBytes + "----cacheSizeBytes=" + cachedBytesRead);
}
@Override
public void onCacheIgnored(int reason) {
CommonUtils.LogMsg("-----------缓存2忽略 PlayCache=" + reason);
}
});
downloadCache = MyDownloadService.getDownloadCache();
return new CacheDataSource.Factory()
.setCache(downloadCache)
.setUpstreamDataSourceFactory(factory1)
.setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
.setEventListener(new CacheDataSource.EventListener() {
@Override
public void onCachedBytesRead(long cacheSizeBytes, long cachedBytesRead) {
CommonUtils.LogMsg("-----------缓存1 DownloadCache --" + cacheSizeBytes + "----cacheSizeBytes=" + cachedBytesRead);
}
@Override
public void onCacheIgnored(int reason) {
CommonUtils.LogMsg("-----------缓存1忽略DownloadCache =" + reason);
}
});
// .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
}
@OptIn(markerClass = UnstableApi.class)
private DataSource.Factory getUrlFactory() {
long chunkLength = 512 * 1024L;
return new ResolvingDataSource.Factory(getCacheDataSourceFactory(this), new ResolvingDataSource.Resolver() {
@Override
public DataSpec resolveDataSpec(DataSpec dataSpec) {
CommonUtils.LogMsg("--------resolveDataSpec dataSpec.key=" + dataSpec.key+"---dataSpec.uri="+dataSpec.uri);
return dataSpec;
// long length = 1L;
// String videoId = dataSpec.key;
// long position = dataSpec.position;
// if (dataSpec.length >= 0) {
// length = dataSpec.length;
// }
//
// if (downloadCache.isCached(videoId,position,length)){
// CommonUtils.LogMsg("--------resolveDataSpec downloadCache" );
// return dataSpec;
// }else if(playCache.isCached(videoId,position,chunkLength)){
// CommonUtils.LogMsg("--------resolveDataSpec playCache" );
// return dataSpec;
// }else {
// CommonUtils.LogMsg("--------resolveDataSpec uri" );
// return dataSpec;
// }
}
@Override
public Uri resolveReportedUri(Uri uri) {
CommonUtils.LogMsg("--------resolveDataSpec uri=" + uri);
return ResolvingDataSource.Resolver.super.resolveReportedUri(Uri.parse("---"));
}
});
}
@Nullable
@Override
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
return mediaSession;
}
@Override
public void onTaskRemoved(@Nullable Intent rootIntent) {
Player player = mediaSession.getPlayer();
if (!player.getPlayWhenReady()
|| player.getMediaItemCount() == 0
|| player.getPlaybackState() == Player.STATE_ENDED) {
// Stop the service if not playing, continue playing in the background
// otherwise.
stopSelf();
}
}
@Override
public void onDestroy() {
mediaSession.getPlayer().release();
mediaSession.release();
mediaSession = null;
super.onDestroy();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,207 +0,0 @@
package com.hi.music.player.network;
import com.google.gson.Gson;
import com.hi.music.player.MusicApplication;
import com.hi.music.player.api.RequestListener;
import com.hi.music.player.javabean.requestbody.BodyHome;
import com.hi.music.player.javabean.requestbody.BodyPlay;
import com.hi.music.player.javabean.requestbody.BodyPlayUrl;
import com.hi.music.player.javabean.requestbody.BodySearch;
import com.hi.music.player.javabean.requestbody.BodySearchSuggestion;
import com.hi.music.player.javabean.requestbody.child.Client;
import com.hi.music.player.javabean.requestbody.child.ContextBody;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitManager {
private String base_Host = "https://music.youtube.com/";
private String base_Host_test = "https://rr2---sn-tt1e7nlz.googlevideo.com/";
private static volatile RetrofitManager REQUEST_MANAGER;
private Retrofit retrofit;
public MediaType JSON = MediaType.get("application/json; charset=utf-8");
private MusicApi musicApi;
private String header1 = "playlistPanelVideoRenderer(title,navigationEndpoint,longBylineText,shortBylineText,thumbnail,lengthText)";
private String header = "contents.singleColumnMusicWatchNextResultsRenderer.tabbedRenderer.watchNextTabbedResultsRenderer.tabs.tabRenderer.content.musicQueueRenderer.content.playlistPanelRenderer(continuations,contents(automixPreviewVideoRenderer," + header1 + "))";
private RetrofitManager() {
musicApi = getRetrofit().create(MusicApi.class);
}
private synchronized Retrofit getRetrofit() {
if (retrofit == null) {
long DEFAULT_TIMEOUT = 5;
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.addInterceptor(httpLoggingInterceptor)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(base_Host)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
return retrofit;
}
public static RetrofitManager getInstance() {
if (REQUEST_MANAGER == null) {
synchronized (RetrofitManager.class) { //,防止线程问题
if (REQUEST_MANAGER == null) {
REQUEST_MANAGER = new RetrofitManager();
}
}
}
return REQUEST_MANAGER;
}
public void getHomeData(RequestListener<ResponseBody> requestListener) {
BodyHome bodyHome = new BodyHome();
Gson gson = new Gson();
String s = gson.toJson(bodyHome);
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
musicApi.getHomeData(requestBody)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
}
public void getHomeMoreData(String continuation, String itct, String visitorData, RequestListener<ResponseBody> requestListener) {
BodyHome bodyHome = new BodyHome();
bodyHome.getContext().getClient().setVisitorData(visitorData);
Gson gson = new Gson();
String s = gson.toJson(bodyHome);
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
HashMap<String, String> stringHashMap = new HashMap<>();
stringHashMap.put("ctoken", continuation);
stringHashMap.put("continuation", continuation);
stringHashMap.put("type", "next");
stringHashMap.put("itct", itct);
stringHashMap.put("prettyPrint", "false");
musicApi.getHomeMoreData(continuation, continuation, "next", itct, false, requestBody)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
}
public void getPlayList(String params, String playlistId, String videoId, String musicVideoType, RequestListener<ResponseBody> requestListener) {
BodyPlay bodyPlay = new BodyPlay();
bodyPlay.setParams(params);
bodyPlay.setPlaylistId(playlistId);
bodyPlay.setVideoId(videoId);
bodyPlay.getWatchEndpointMusicSupportedConfigs().setMusicVideoType(musicVideoType);
Gson gson = new Gson();
String s = gson.toJson(bodyPlay);
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
musicApi.getMusicPlayPage(header, requestBody)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
}
public void getPlayUrl(String videoId, RequestListener<ResponseBody> requestListener) {
BodyPlayUrl bodyPlay = new BodyPlayUrl();
bodyPlay.setVideoId(videoId);
Client client = bodyPlay.getContext().getClient();
client.setClientName("ANDROID");
client.setClientVersion("19.05.36");
client.setPlatform("DESKTOP");
String visitorData = MusicApplication.getVisitorData();
// client.setVisitorData("CgtWN1RXaURPN3LNZyiZK9e4BjIKCgJVUXIEGgAgPW%3D%3D");
client.setVisitorData(visitorData);
// bodyPlay.getContext().getThirdParty().setEmbedUrl("https://www.youtube.com/watch?v="+videoId);
Gson gson = new Gson();
String s = gson.toJson(bodyPlay);
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
musicApi.getMusicPlayUrl(requestBody)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
}
public void getCategoryList(String browserId, RequestListener<ResponseBody> requestListener) {
BodyHome bodyHome = new BodyHome();
bodyHome.setBrowseId(browserId);
// bodyHome.setBrowseId("VLPLI-asvmHZWNo_xjMMfD_v2O2lTyCdrjaK");
Client client = bodyHome.getContext().getClient();
client.setClientVersion("1.20240506.01.00");
Gson gson = new Gson();
String s = gson.toJson(bodyHome);
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
musicApi.getCategoryList(requestBody)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new ObserverWrapper<>(requestListener));
}
public void getSearchSuggestion(String input, RequestListener<ResponseBody> requestListener) {
BodySearchSuggestion body = new BodySearchSuggestion();
body.setInput(input);
Client client = body.getContext().getClient();
client.setClientVersion("1.20240506.01.00");
Gson gson = new Gson();
String s = gson.toJson(body);
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
musicApi.getSearchSuggestion(requestBody)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new ObserverWrapper<>(requestListener));
}
public void getSearch(String query, RequestListener<ResponseBody> requestListener) {
BodySearch body = new BodySearch();
body.setQuery(query);
Client client = body.getContext().getClient();
client.setClientVersion("1.20240506.01.00");
Gson gson = new Gson();
String s = gson.toJson(body);
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
musicApi.getSearch(requestBody)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new ObserverWrapper<>(requestListener));
}
}

View File

@ -1,252 +0,0 @@
package com.hi.music.player.ui.activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsControllerCompat;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModel;
import androidx.media3.common.MediaItem;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.viewbinding.ViewBinding;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.hi.music.player.MusicApplication;
import com.hi.music.player.R;
import com.hi.music.player.api.onPlayNextListener;
import com.hi.music.player.databinding.ActivityBaseBinding;
import com.hi.music.player.databinding.LayoutPanelBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue;
import com.hi.music.player.helper.ViewModelScope;
import com.hi.music.player.media3.MyMediaControllerManager;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
public abstract class BaseActivity<T extends ViewBinding> extends AppCompatActivity implements View.OnClickListener {
private final ViewModelScope mViewModelScope = new ViewModelScope();
protected T vb;
private Window window;
private View decorView;
protected View mView;
private ActivityBaseBinding rootVb;
protected VMApplication vmApplication;
protected MyMediaControllerManager mediaControllerManager;
private Handler mHandler;
private Runnable mRunnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vb = getViewBinding();
View root = vb.getRoot();
rootVb = ActivityBaseBinding.inflate(getLayoutInflater(), null, false);
rootVb.frameLayout.addView(root);
setContentView(rootVb.getRoot());
window = getWindow();
decorView = window.getDecorView();
mView = decorView.getRootView();
vmApplication = getApplicationScopeViewModel(VMApplication.class);
mediaControllerManager = MyMediaControllerManager.getInstance();
if (showPanel())
initPanel();
setStatusBar();
if (isFullScreen()) {
// ImmersionBar.with(this).init();//设置沉浸式效果
// ImmersionBar.setStatusBarView(this,0);
initFullScreen();
}
onCreateInit();
onInitClick();
}
protected abstract T getViewBinding();
protected abstract void onCreateInit();
protected abstract void onInitClick();
public abstract boolean isFullScreen();
public abstract boolean statusBarLight();
public abstract boolean showPanel();
private void initPanel() {
LayoutPanelBinding panelVb = LayoutPanelBinding.inflate(getLayoutInflater());
View panelView = panelVb.getRoot();
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
CommonUtils.dpToPx(74)
);
initProgressHandler(panelVb);
panelVb.imPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
panelVb.imPlay.setSelected(!panelVb.imPlay.isSelected());
if (panelVb.imPlay.isSelected()) {
mediaControllerManager.play();
} else {
mediaControllerManager.pause();
}
}
});
panelVb.imNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mediaControllerManager.playNext(new onPlayNextListener() {
@Override
public void onPlayNext(boolean hasNext) {
if (!hasNext) {
Toast.makeText(MusicApplication.myApplication, getString(R.string.no_next_song_yet), Toast.LENGTH_SHORT).show();
}
}
});
}
});
panelVb.layoutPanel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MusicApplication.myApplication, PlayActivity.class);
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_PANEL);
startActivity(intent);
}
});
if (this instanceof HomeActivity) {
layoutParams.setMargins(CommonUtils.dpToPx(22), 0, CommonUtils.dpToPx(22), CommonUtils.dpToPx(82));
} else {
layoutParams.setMargins(CommonUtils.dpToPx(22), 0, CommonUtils.dpToPx(22), CommonUtils.dpToPx(10));
}
layoutParams.gravity = Gravity.BOTTOM;
vmApplication.playStatus.observe(this, new Observer<Integer>() {
@OptIn(markerClass = UnstableApi.class)
@Override
public void onChanged(Integer integer) {
CommonUtils.LogMsg("----------面板 播放状态更新=" + integer);
if (panelView.getParent() == null) {
CommonUtils.LogMsg("----------显示面板");
rootVb.frameLayout.addView(panelView, layoutParams);
mHandler.post(mRunnable);
}
MediaItem currentMediaItem = mediaControllerManager.getCurMediaItem();
if(currentMediaItem!= null){
Uri artworkUri = currentMediaItem.mediaMetadata.artworkUri;
CharSequence title = currentMediaItem.mediaMetadata.title;
CharSequence artist = currentMediaItem.mediaMetadata.artist;
if (currentMediaItem.mediaMetadata.durationMs != null) {
long durationMs = currentMediaItem.mediaMetadata.durationMs;
panelVb.circularPb.setMaxProgress((int) durationMs);
}
if(artworkUri!= null){
CommonUtils.LogMsg("----------artworkUri="+artworkUri.toString());
Glide.with(MusicApplication.myApplication)
.load(artworkUri.toString())
.placeholder(R.mipmap.im_placeholder)
.transform(new CircleCrop())
.into(panelVb.image);
}
panelVb.title.setText(title);
panelVb.singer.setText(artist);
}
switch (integer) {
case Player.STATE_IDLE:
case Player.STATE_ENDED:
case Player.STATE_READY:
case MyValue.PLAY_STATUS_CODE_PAUSE:
case Player.STATE_BUFFERING:
case MyValue.PLAY_STATUS_CODE_ERROR:
//快进没有缓冲的时候触发
//播放完成
panelVb.imPlay.setSelected(false);
break;
case MyValue.PLAY_STATUS_CHANGE_MUSIC:
case MyValue.PLAY_STATUS_CODE_PLAYING:
panelVb.imPlay.setSelected(true);
break;
}
}
});
}
private void initProgressHandler(LayoutPanelBinding panelBinding) {
mHandler = new Handler();
mRunnable = new Runnable() {
@Override
public void run() {
updatePlaybackProgress(panelBinding);
mHandler.postDelayed(this, 1000);
}
};
}
private void updatePlaybackProgress(LayoutPanelBinding panelBinding) {
// 获取当前播放位置
long contentPos = mediaControllerManager.getContentPos();
long bufferPos = mediaControllerManager.getBufferPos();
// CommonUtils.LogMsg("---------播放进度-----contentPos=" + contentPos + "-----缓冲进度=" + bufferPos);
panelBinding.circularPb.setProgress((int) contentPos);
}
private void setStatusBar() {
//深色模式
WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView());
insetsController.setAppearanceLightStatusBars(statusBarLight());
}
private void initFullScreen() {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
protected <K extends ViewModel> K getActivityScopeViewModel(@NonNull Class<K> modelClass) {
return mViewModelScope.getActivityScopeViewModel(this, modelClass);
}
protected <K extends ViewModel> K getApplicationScopeViewModel(@NonNull Class<K> modelClass) {
return mViewModelScope.getApplicationScopeViewModel(modelClass);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mHandler != null && mRunnable != null)
mHandler.removeCallbacks(mRunnable);
}
}

View File

@ -1,259 +0,0 @@
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.Context;
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.HomeItemClickListener;
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.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.child.ResponseCategory;
import com.hi.music.player.javabean.response.child.ResponseSingle;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
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> implements HomeItemClickListener {
private VMCategoryList vm;
// private VMApplication vmApplication;
private ResponseCategoryList mCategoryList;
private String mPageType;
private String twoSubtitle;
private String browseId;
@Override
protected ActivityCategoryListBinding getViewBinding() {
return ActivityCategoryListBinding.inflate(getLayoutInflater());
}
@Override
protected void onCreateInit() {
vm = getActivityScopeViewModel(VMCategoryList.class);
// vmApplication = getApplicationScopeViewModel(VMApplication.class);
Intent intent = getIntent();
if (intent == null) {
return;
}
mPageType= intent.getStringExtra(MyValue.KEY_CATEGORY_LIST_TYPE);
twoSubtitle = intent.getStringExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME);
browseId = intent.getStringExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID);
vb.pbLoading.setVisibility(View.VISIBLE);
vm.getList(browseId);
vm.data.observe(this, new Observer<ResponseCategoryList>() {
@Override
public void onChanged(ResponseCategoryList responseCategoryList) {
if (responseCategoryList == null) {
vb.pbLoading.setVisibility(View.GONE);
updateErrorLayout(getString(R.string.playList_loading_failed),true);
return;
}
mCategoryList = responseCategoryList;
loadInfo(mCategoryList);
}
});
}
private void updateErrorLayout(String msg, boolean isShow) {
if (isShow)
vb.layoutError.linearRetry.setVisibility(View.VISIBLE);
else vb.layoutError.linearRetry.setVisibility(View.GONE);
if(msg!= null&&!msg.isEmpty()){
vb.layoutError.tvErrorMsg.setText(msg);
}
}
@Override
protected void onInitClick() {
vb.imBack.setOnClickListener(this);
vb.btnPlay.setOnClickListener(this);
vb.layoutError.tvRetry.setOnClickListener(this);
}
@Override
public boolean isFullScreen() {
return true;
}
@Override
public boolean statusBarLight() {
return false;
}
@Override
public boolean showPanel() {
return true;
}
@Override
public void onClick(View v) {
if (v.equals(vb.imBack)) {
finish();
} else if (v.equals(vb.btnPlay)) {
int musicIndex = 0;
Intent intent = new Intent(this, PlayActivity.class);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST, mCategoryList.getList().get(musicIndex));
// intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX,musicIndex);
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_CATEGORY);
startActivity(intent);
vmApplication.reSetPlayList(mCategoryList.getList());
}else if(v.equals(vb.layoutError.tvRetry)){
vb.pbLoading.setVisibility(View.VISIBLE);
updateErrorLayout(null,false);
vm.getList(browseId);
}
}
private void loadInfo(ResponseCategoryList info) {
vb.btnPlay.setVisibility(View.VISIBLE);
switch (mPageType) {
case MyValue.PAGE_TYPE_LIST:
vb.tvSingerName.setVisibility(View.GONE);
break;
case MyValue.PAGE_TYPE_ALBUM:
vb.tvSingerName.setVisibility(View.VISIBLE);
String singNameValue = "";
String singName = info.getSingName();
if(singName!= null&&!singName.isEmpty()){
singNameValue= singName;
}else {
String[] split = twoSubtitle.split("");
if (split != null && split.length > 1) {
singNameValue = split[1];
}
}
CommonUtils.LogMsg("singNameValue=" + singNameValue);
vb.tvSingerName.setText(singNameValue);
for (ResponsePlayListInfo playListInfo : info.getList()) {
playListInfo.setSingerName(singNameValue);
}
break;
}
vb.tvTitle.setText(info.getTitle());
vb.tvSubTitle.setText(info.getDescription());
AdapterCategoryList adapterCategoryList = new AdapterCategoryList();
adapterCategoryList.setHomeItemClickListener(this);
adapterCategoryList.setPageType(mPageType);
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.im_placeholder)
.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);
}
@Override
public void onClickItemCategoryList(ResponsePlayListInfo data, int musicIndex) {
Intent intent = new Intent(this, PlayActivity.class);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST, data);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX, musicIndex);
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_CATEGORY);
startActivity(intent);
vmApplication.reSetPlayList(mCategoryList.getList());
}
@Override
protected void onResume() {
super.onResume();
}
}

View File

@ -1,862 +0,0 @@
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.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.SeekBar;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Observer;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MediaMetadata;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.cache.SimpleCache;
import androidx.media3.exoplayer.offline.Download;
import androidx.media3.exoplayer.offline.DownloadManager;
import androidx.media3.exoplayer.offline.DownloadRequest;
import androidx.media3.exoplayer.offline.DownloadService;
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.google.gson.Gson;
import com.hi.music.player.MusicApplication;
import com.hi.music.player.R;
import com.hi.music.player.adapter.AdapterDownloadSong;
import com.hi.music.player.adapter.AdapterPlayList;
import com.hi.music.player.api.LikeSongListener;
import com.hi.music.player.api.MediaControllerListener;
import com.hi.music.player.api.onCheckDownload;
import com.hi.music.player.api.onImageColorListener;
import com.hi.music.player.api.onPlayNextListener;
import com.hi.music.player.databinding.ActivityPlayBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue;
import com.hi.music.player.javabean.BoxDownloadSong;
import com.hi.music.player.javabean.BoxLikeSong;
import com.hi.music.player.javabean.CustomerDownload;
import com.hi.music.player.javabean.CustomerUrlInfo;
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.ResponsePlayUrl;
import com.hi.music.player.javabean.response.child.ResponseCategory;
import com.hi.music.player.javabean.response.child.ResponseSingle;
import com.hi.music.player.media3.MyDownloadService;
import com.hi.music.player.media3.MyMediaControllerManager;
import com.hi.music.player.media3.MyPlayCacheManager;
import com.hi.music.player.objectbox.ObjectBoxManager;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
import com.hi.music.player.ui.activity.viewmodel.VMPlay;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements SeekBar.OnSeekBarChangeListener {
//单曲进入传递的数据
private ResponseSingle responseSingle;
private VMPlay vmPlay;
private Handler mHandler;
private Runnable mRunnable;
private AdapterPlayList adapterPlayList;
//播放列表ui初始化
private boolean initPlayList = false;
private GradientDrawable gradientDrawable;
private int lighterColor, darkerColor;
// 0 播放列表请求失败 1 立即播放的歌曲请求失败 2 封面图加载失败
private int netError = 0;
// 请求失败的立即播放的歌曲信息
private CustomerUrlInfo mCustomerUrlInfo;
private int mEnterType;
//-------单曲进入播放列表接口请求需要的参数
private String playlistId, videoId, params, musicVideoType = "";
//-------单曲进入播放列表接口请求需要的参数
private int mDefaultPlayStartIndex = 0;
private int[] imageStates = {
R.drawable.icon_looper_no,
R.drawable.icon_looper_1,
R.drawable.icon_looper
};
//0 不循环1 列表循环2 单曲循环
private int currentMode = 0;
private List<BoxDownloadSong> downloadSongList = new ArrayList<>();
@Override
protected ActivityPlayBinding getViewBinding() {
return ActivityPlayBinding.inflate(getLayoutInflater());
}
@Override
protected void onCreateInit() {
// vb.progressBarLoading.setVisibility(View.VISIBLE);
vmPlay = getActivityScopeViewModel(VMPlay.class);
initMediaController();
Intent intent = getIntent();
mEnterType = intent.getIntExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_SINGLE);
initPlayerView();
initProgressHandler();
CommonUtils.LogMsg("--------mEnterType=" + mEnterType);
switch (mEnterType) {
case MyValue.TYPE_ENTER_SOURCE_SINGLE:
// 0--首页单曲进入
updateMediaPlayList();
responseSingle = (ResponseSingle) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER);
playlistId = responseSingle.getPlaylistId();
videoId = responseSingle.getVideoId();
params = responseSingle.getParams();
musicVideoType = responseSingle.getMusicVideoType();
mDefaultPlayStartIndex = intent.getIntExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX, mDefaultPlayStartIndex);
SimpleCache playCache = MyPlayCacheManager.getPlayCache();
// boolean songCached = CommonUtils.isSongCached(playCache, videoId);
// CommonUtils.LogMsg("---------------是否有播放缓存--songCached="+songCached +"--name="+responseSingle.getSongTitle());
vmPlay.getPlayMusicList(playlistId, videoId, params, musicVideoType);
vmPlay.playList.observe(this, new Observer<List<ResponsePlayListInfo>>() {
@Override
public void onChanged(List<ResponsePlayListInfo> listInfos) {
vmApplication.reSetPlayList(listInfos);
}
});
break;
case MyValue.TYPE_ENTER_SOURCE_CATEGORY:
// 1--首页音乐分类合集列表进入
updateMediaPlayList();
ResponsePlayListInfo playListInfo = (ResponsePlayListInfo) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST);
mDefaultPlayStartIndex = intent.getIntExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX, mDefaultPlayStartIndex);
videoId = playListInfo.getVideoId();
break;
case MyValue.TYPE_ENTER_SOURCE_MV:
// 2--首页单个视频mv进入
updateMediaPlayList();
ResponseCategory responseCategory = (ResponseCategory) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_MV);
videoId = responseCategory.getVideoId();
playlistId = responseCategory.getPlayListId();
params = responseCategory.getParams();
musicVideoType = responseCategory.getMusicVideoType();
vmPlay.getPlayMusicList(playlistId, videoId, params, musicVideoType);
vmPlay.playList.observe(this, new Observer<List<ResponsePlayListInfo>>() {
@Override
public void onChanged(List<ResponsePlayListInfo> listInfos) {
vmApplication.reSetPlayList(listInfos);
}
});
break;
case MyValue.TYPE_ENTER_PANEL:
// 3--控制面板进入
MediaItem curMediaItem = mediaControllerManager.getCurMediaItem();
loadInfo(curMediaItem);
mHandler.post(mRunnable);
vb.progressBarLoading.setVisibility(View.GONE);
vb.btnPlay.setSelected(mediaControllerManager.getIsPlaying());
break;
case MyValue.TYPE_ENTER_LIKE:
// 4--从喜爱歌曲进入
updateMediaPlayList();
videoId = intent.getStringExtra(MyValue.KEY_PLAY_VIDEO_ID);
mDefaultPlayStartIndex = intent.getIntExtra(MyValue.KEY_PLAY_INDEX, mDefaultPlayStartIndex);
CommonUtils.LogMsg("-------------like进入 videoId= " + videoId + "---mDefaultPlayStartIndex=" + mDefaultPlayStartIndex);
break;
case MyValue.TYPE_ENTER_DOWNLOAD:
// 5--从下载歌曲进入
videoId = intent.getStringExtra(MyValue.KEY_PLAY_VIDEO_ID);
mDefaultPlayStartIndex = intent.getIntExtra(MyValue.KEY_PLAY_INDEX, mDefaultPlayStartIndex);
CommonUtils.LogMsg("-------------下载歌曲 videoId= " + videoId + "---mDefaultPlayStartIndex=" + mDefaultPlayStartIndex);
break;
}
addDownloadListener();
vmPlay.playUrlLiveData.observe(this, new Observer<CustomerUrlInfo>() {
@Override
public void onChanged(CustomerUrlInfo customerUrlInfo) {
if (customerUrlInfo.isNeedPlayNow() && customerUrlInfo.getPlayUrl() == null) {
// TODO: 2024/9/26 需要马上播放这首歌曲但是此次网络请求失败
CommonUtils.LogErrorMsg("-------------需要马上播放这首歌曲,但是此次网络请求失败");
updateErrorLayout(getString(R.string.song_loading_failed), true);
netError = 1;
mCustomerUrlInfo = customerUrlInfo;
initShowPlayList(false);
vb.progressBarLoading.setVisibility(View.GONE);
mediaControllerManager.pause();
return;
}
int second = customerUrlInfo.getPlayMusicIndex();
if (customerUrlInfo.isNeedPlayNow()) {
mediaControllerManager.playPositionMusic(second);
// mediaControllerManager.play();
}
}
});
}
/**
* 更新播放列表
*/
private void updateMediaPlayList() {
vmApplication.playList.observe(this, new Observer<List<ResponsePlayListInfo>>() {
@Override
public void onChanged(List<ResponsePlayListInfo> playList) {
if (playList == null) {
CommonUtils.LogErrorMsg("--------更新-playList null");
netError = 0;
updateErrorLayout(getString(R.string.playList_loading_failed), true);
vb.progressBarLoading.setVisibility(View.GONE);
return;
}
CommonUtils.LogMsg("--------更新-playList " + playList.size() + "--videoId=" + videoId);
if (playList.size() > 0) {
updateErrorLayout(null, false);
setPlayListAndGetUrl(playList, videoId, mDefaultPlayStartIndex);
}
}
});
}
private void updateErrorLayout(String msg, boolean isShow) {
if (isShow)
vb.layoutError.linearRetry.setVisibility(View.VISIBLE);
else vb.layoutError.linearRetry.setVisibility(View.GONE);
if (msg != null && !msg.isEmpty()) {
vb.layoutError.tvErrorMsg.setText(msg);
}
}
/**
* 设置播放列表并请求当前需要播放的音乐url
*
* @param list
* @param id
* @param index
*/
@OptIn(markerClass = UnstableApi.class)
private void setPlayListAndGetUrl(List<ResponsePlayListInfo> list, String id, int index) {
mediaControllerManager.resetPlayList();
MyMediaControllerManager.getInstance().setPlayList(list);
MyDownloadService.queryIsDownload(id, new onCheckDownload() {
@Override
public void onHasDownload(CustomerDownload customerDownload) {
if(customerDownload.isDownload()){
MediaItem mediaItem = CommonUtils.downloadToMediaItem(customerDownload.getDownloadData());
mediaControllerManager.replaceMediaItem(index,mediaItem);
CommonUtils.LogMsg("-------------setPlayListAndGetUrl已经下载过 index" + index + "---playNow=" + true);
mediaControllerManager.playPositionMusic(index);
}else {
CommonUtils.LogMsg("-------------setPlayListAndGetUrl index" + index + "---playNow=" + true);
vmPlay.getPlayUrl(id, index, true);
}
}
});
}
@OptIn(markerClass = UnstableApi.class)
private void initPlayerView() {
vb.playerView.setShowRewindButton(false);
vb.playerView.setShowPreviousButton(false);
vb.playerView.setPlayer(mediaControllerManager.getMediaController());
}
private void initMediaController() {
int repeatMode = mediaControllerManager.getRepeatMode();
CommonUtils.LogMsg("-------------repeatMode=" + repeatMode);
vb.btnLoop.setImageResource(imageStates[repeatMode]);
mediaControllerManager.addListener(vmApplication, new MediaControllerListener() {
@Override
public void onPlayStatus(int playStatus) {
switch (playStatus) {
case Player.STATE_IDLE:
CommonUtils.LogMsg("-------------IDLE");
break;
case Player.STATE_BUFFERING:
//快进没有缓冲的时候触发
vb.btnPlay.setSelected(false);
// vb.progressBarLoading.setVisibility(View.VISIBLE);
CommonUtils.LogMsg("-------------缓冲");
break;
case Player.STATE_READY:
vb.btnPlay.setSelected(true);
mHandler.post(mRunnable);
vb.progressBarLoading.setVisibility(View.GONE);
CommonUtils.LogMsg("-------------准备");
break;
case Player.STATE_ENDED:
//播放完成
vb.btnPlay.setSelected(false);
CommonUtils.LogMsg("------------- 播放完成");
mHandler.removeCallbacks(mRunnable); // 停止更新
updatePlayComplete();
break;
case MyValue.PLAY_STATUS_CODE_PAUSE:
CommonUtils.LogMsg("------------- 暂停");
vb.btnPlay.setSelected(false);
vb.layoutPlayList.imPlay.setSelected(false);
break;
case MyValue.PLAY_STATUS_CODE_PLAYING:
CommonUtils.LogMsg("------------- 播放ing getCurIndex=" + mediaControllerManager.getCurIndex());
vb.progressBarLoading.setVisibility(View.GONE);
updateErrorLayout(null, false);
vb.btnPlay.setSelected(true);
vb.layoutPlayList.imPlay.setSelected(true);
break;
case MyValue.PLAY_STATUS_CODE_ERROR:
vb.progressBarLoading.setVisibility(View.GONE);
int currentMediaItemIndex = mediaControllerManager.getMediaController().getCurrentMediaItemIndex();
CommonUtils.LogMsg("------------- 播放错误 currentMediaItemIndex=" + currentMediaItemIndex);
mediaControllerManager.playPositionMusic(currentMediaItemIndex);
// TODO: 2024/10/16
break;
}
}
@Override
public void onRequestNextUri(String videoId, int playListIndex, boolean playNow) {
if (playNow) {
// vb.progressBarLoading.setVisibility(View.VISIBLE);
}
vmPlay.getPlayUrl(videoId, playListIndex, playNow);
}
@Override
public void onChangeMusic(MediaItem mediaItem) {
CommonUtils.LogMsg("歌曲切换-" + mediaItem.mediaMetadata.title + "---id=" + mediaItem.mediaId);
loadInfo(mediaItem);
}
});
}
@Override
protected void onInitClick() {
vb.btnPlay.setOnClickListener(this);
vb.playProgress.setOnSeekBarChangeListener(this);
vb.btnNext.setOnClickListener(this);
vb.btnPrevious.setOnClickListener(this);
vb.imBack.setOnClickListener(this);
vb.btnMusicList.setOnClickListener(this);
vb.layoutError.tvRetry.setOnClickListener(this);
vb.btnLoop.setOnClickListener(this);
vb.layoutLike.setOnClickListener(this);
vb.layoutDownload.setOnClickListener(this);
}
/**
* 更新播放进度Ui缓冲进度
*/
private void updatePlaybackProgress() {
// 获取当前播放位置
long contentPos = mediaControllerManager.getContentPos();
long bufferPos = mediaControllerManager.getBufferPos();
String s = CommonUtils.convertMillisToTime(contentPos);
vb.tvCurrent.setText(s);
vb.playProgress.setProgress((int) contentPos);
vb.progressBarBuffer.setProgress((int) bufferPos);
}
/**
* 播放完成 更新播放进度Ui
*/
private void updatePlayComplete() {
vb.tvCurrent.setText(vb.tvDuration.getText().toString());
}
/**
* 加载当前播放歌曲信息
*/
@OptIn(markerClass = UnstableApi.class)
private void loadInfo(MediaItem mediaItem) {
MediaMetadata mediaMetadata = mediaItem.mediaMetadata;
CommonUtils.LogMsg("--------------加载当前播放歌曲信息 title=" + mediaMetadata.title);
if (mediaMetadata.artworkUri != null) {
loadCovert(mediaMetadata.artworkUri.toString());
}
vb.tvSongName.setText(mediaMetadata.title);
vb.tvSingerName.setText(mediaMetadata.artist);
vb.tvDuration.setText(mediaMetadata.description);
if (mediaMetadata.durationMs != null) {
long durationMs = mediaMetadata.durationMs;
vb.playProgress.setMax((int) durationMs);
vb.progressBarBuffer.setMax((int) durationMs);
}
if (vb.layoutPlayList.linearLayout.getVisibility() == View.VISIBLE) {
updatePlayListUi();
}
//刷新当前歌曲的喜爱状态
boolean isLike = ObjectBoxManager.queryIsLike(mediaItem.mediaId);
vb.imLike.setSelected(isLike);
//刷新当前歌曲的下载状态
String mediaId = mediaItem.mediaId;
MyDownloadService.queryIsDownload(mediaId, new onCheckDownload() {
@Override
public void onHasDownload(CustomerDownload customerDownload) {
vb.imDownload.setSelected(customerDownload.isDownload());
}
});
}
private void loadCovert(String url) {
Glide.with(MusicApplication.myApplication)
.asDrawable()
.load(url)
.placeholder(R.mipmap.im_placeholder)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
CommonUtils.LogMsg(e.getMessage());
// netError = 2;
// vb.tvErrorMsg.setText(getString(R.string.image_loading_failed));
// vb.linearRetry.setVisibility(View.VISIBLE);
return false;
}
@OptIn(markerClass = UnstableApi.class)
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
vb.imCovert.setImageDrawable(resource);
CommonUtils.getMainColor(resource, new onImageColorListener() {
@Override
public void onImageColor(int color) {
if (color == -1) {
return;
}
lighterColor = CommonUtils.adjustBrightness(color, 0.8f); // 比原始颜色亮 20%
darkerColor = CommonUtils.adjustBrightness(color, 0.6f); // 比原始颜色暗 20%
gradientDrawable = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
new int[]{lighterColor, darkerColor} // 浅到深渐变
);
vb.rootLayout.setBackground(gradientDrawable);
if (vb.layoutPlayList.linearLayout.getVisibility() == View.VISIBLE) {
updatePlayListColor();
}
}
});
return false;
}
})
.preload();
}
private void initProgressHandler() {
mHandler = new Handler();
mRunnable = new Runnable() {
@Override
public void run() {
updatePlaybackProgress();
mHandler.postDelayed(this, 1000);
}
};
}
@Override
public boolean isFullScreen() {
return true;
}
@Override
public boolean statusBarLight() {
return false;
}
@Override
public boolean showPanel() {
return false;
}
@OptIn(markerClass = UnstableApi.class)
@Override
public void onClick(View v) {
if (v.equals(vb.btnPlay)) {
vb.btnPlay.setSelected(!vb.btnPlay.isSelected());
if (vb.btnPlay.isSelected()) {
mediaControllerManager.play();
} else {
mediaControllerManager.pause();
}
} else if (v.equals(vb.btnNext)) {
mediaControllerManager.playNext(new onPlayNextListener() {
@Override
public void onPlayNext(boolean hasNext) {
if (!hasNext) {
Toast.makeText(PlayActivity.this, getString(R.string.no_next_song_yet), Toast.LENGTH_SHORT).show();
}
}
});
} else if (v.equals(vb.btnPrevious)) {
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();
}
if (adapterPlayList != null) {
adapterPlayList.updateCurMusicAnimation();
}
} else if (v.equals(vb.layoutError.tvRetry)) {
//重试按钮
updateErrorLayout(null, false);
switch (netError) {
case 0:
switch (mEnterType) {
case MyValue.TYPE_ENTER_SOURCE_SINGLE:
vmPlay.getPlayMusicList(playlistId, videoId, params, musicVideoType);
break;
}
break;
case 1:
vb.progressBarLoading.setVisibility(View.VISIBLE);
int curIndex = mediaControllerManager.getCurIndex();
String curVideoId = mediaControllerManager.getCurVideoId();
String videoId1 = mCustomerUrlInfo.getVideoId();
int playMusicIndex = mCustomerUrlInfo.getPlayMusicIndex();
CommonUtils.LogMsg("-------重试 curIndex=" + curIndex + "----curVideoId=" + curVideoId + "---videoId1=" + videoId1 + "---playMusicIndex=" + playMusicIndex);
vmPlay.getPlayUrl(mCustomerUrlInfo.getVideoId(), mCustomerUrlInfo.getPlayMusicIndex(), true);
break;
case 2:
MediaItem curMediaItem = mediaControllerManager.getCurMediaItem();
MediaMetadata mediaMetadata = curMediaItem.mediaMetadata;
if (mediaMetadata.artworkUri != null) {
loadCovert(mediaMetadata.artworkUri.toString());
}
break;
}
} else if (v.equals(vb.btnLoop)) {
currentMode = (currentMode + 1) % imageStates.length;
vb.btnLoop.setImageResource(imageStates[currentMode]);
CommonUtils.LogMsg("----currentMode=" + currentMode);
mediaControllerManager.setMode(currentMode);
} else if (v.equals(vb.layoutLike)) {
boolean selected = vb.imLike.isSelected();
vb.imLike.setSelected(!selected);
boolean newSelect = vb.imLike.isSelected();
MediaItem curMediaItem = mediaControllerManager.getCurMediaItem();
MediaMetadata mediaMetadata = curMediaItem.mediaMetadata;
if (mediaMetadata.title != null && mediaMetadata.artist != null && mediaMetadata.durationMs != null && mediaMetadata.description != null) {
BoxLikeSong boxLikeSong = new BoxLikeSong(mediaMetadata.title.toString(),
mediaMetadata.artist.toString(),
curMediaItem.mediaId,
String.valueOf(mediaMetadata.artworkUri),
mediaMetadata.durationMs, mediaMetadata.description.toString());
if (newSelect) {
ObjectBoxManager.insertOrUpdateLike(boxLikeSong);
} else {
ObjectBoxManager.deleteLike(boxLikeSong);
}
}
} else if (v.equals(vb.layoutDownload)) {
if (vb.imDownload.isSelected()) {
//已经下载
Toast.makeText(this,getText(R.string.text_has_downloaded),Toast.LENGTH_SHORT).show();
return;
}
vb.downloadPb.setVisibility(View.VISIBLE);
vb.imDownload.setVisibility(View.INVISIBLE);
BoxDownloadSong curMediaItemInfo = getCurMediaItemInfo();
if (curMediaItemInfo != null) {
Gson gson = new Gson();
String info = gson.toJson(curMediaItemInfo);
byte[] data = info.getBytes(StandardCharsets.UTF_8);
String videoId1 = curMediaItemInfo.getVideoId();
CommonUtils.LogMsg("----------------开始下载 id=" + videoId1);
DownloadRequest downloadRequest = new DownloadRequest.Builder(videoId1, Uri.parse(curMediaItemInfo.getVideoUrl()))
.setMimeType("video/mp4")
.setData(data)
.build();
// 启动 DownloadService 进行下载
DownloadService.sendAddDownload(
this,
MyDownloadService.class, // 上面定义的下载服务类
downloadRequest,
true // 是否在前台运行
);
}
}
}
@OptIn(markerClass = UnstableApi.class)
private BoxDownloadSong getCurMediaItemInfo() {
MediaItem curMediaItem = mediaControllerManager.getCurMediaItem();
if (curMediaItem == null) {
return null;
}
MediaMetadata mediaMetadata = curMediaItem.mediaMetadata;
if (mediaMetadata.title == null || mediaMetadata.artist == null || mediaMetadata.description == null
|| mediaMetadata.durationMs == null || curMediaItem.localConfiguration == null) {
return null;
}
BoxDownloadSong boxDownloadSong = new BoxDownloadSong();
boxDownloadSong.setVideoId(curMediaItem.mediaId);
boxDownloadSong.setCovert(String.valueOf(mediaMetadata.artworkUri));
boxDownloadSong.setSongName((String) mediaMetadata.title);
boxDownloadSong.setSingerName((String) mediaMetadata.artist);
boxDownloadSong.setDuration((String) mediaMetadata.description);
boxDownloadSong.setDurationMs(mediaMetadata.durationMs);
boxDownloadSong.setVideoUrl(String.valueOf(curMediaItem.localConfiguration.uri));
return boxDownloadSong;
}
/**
* 控制播放列表的显示
*
* @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;
if (mEnterType == MyValue.TYPE_ENTER_DOWNLOAD){
playList = new ArrayList<>();
for(BoxDownloadSong data:downloadSongList){
ResponsePlayListInfo playListInfo = new ResponsePlayListInfo();
playListInfo.setSongTitle(data.getSongName());
playListInfo.setSingerName(data.getSingerName());
playListInfo.setCovert(data.getCovert());
playListInfo.setSmallCovert(data.getCovert());
playListInfo.setVideoId(data.getVideoId());
playListInfo.setDuration(data.getDuration());
playListInfo.setDurationMs(data.getDurationMs());
playList.add(playListInfo);
}
}else {
playList = mediaControllerManager.getPlayList();
}
adapterPlayList = new AdapterPlayList();
vb.layoutPlayList.recyclerList.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication));
adapterPlayList.setData(playList);
// TODO: 2024/10/16 播放列表显示
vb.layoutPlayList.recyclerList.setAdapter(adapterPlayList);
vb.layoutPlayList.imPlay.setOnClickListener(this);
initPlayList = true;
}
updatePlayListUi();
} 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);
}
}
/**
* 更新播放列表的显示
*/
private void updatePlayListUi() {
CommonUtils.LogMsg("----------更新播放列表的显示");
MediaItem currentMediaItem = mediaControllerManager.getCurMediaItem();
if (currentMediaItem != null) {
if (adapterPlayList != null) {
adapterPlayList.setCurVideId(currentMediaItem.mediaId);
}
Uri artworkUri = currentMediaItem.mediaMetadata.artworkUri;
vb.layoutPlayList.topSongName.setText(currentMediaItem.mediaMetadata.title);
vb.layoutPlayList.topSingerName.setText(currentMediaItem.mediaMetadata.artist);
updatePlayListColor();
Glide.with(MusicApplication.myApplication)
.asDrawable()
// .apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(10))))
.load(artworkUri)
.placeholder(R.mipmap.im_placeholder)
.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.getIsPlaying());
}
private void updatePlayListColor() {
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);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mHandler != null && mRunnable != null)
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) {
if (fromUser) {
mediaControllerManager.getMediaController().seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@OptIn(markerClass = UnstableApi.class)
private void addDownloadListener() {
MyDownloadService.addDownloadListener(vmApplication);
vmApplication.downloadData.observe(this, new Observer<List<Download>>() {
@Override
public void onChanged(List<Download> downloads) {
if (downloads == null || downloads.size() == 0) {
return;
}
String id = downloads.get(downloads.size() - 1).request.id;
MediaItem curMediaItem = mediaControllerManager.getCurMediaItem();
if (curMediaItem != null) {
String mediaId = mediaControllerManager.getCurMediaItem().mediaId;
if (mediaId.equals(id)) {
vb.downloadPb.setVisibility(View.GONE);
vb.imDownload.setVisibility(View.VISIBLE);
vb.imDownload.setSelected(true);
}
}
CommonUtils.LogMsg("-------onChanged id=" + id);
if (mEnterType == MyValue.TYPE_ENTER_DOWNLOAD) {
//下载进入播放这里进行重置播放列表并播放
mediaControllerManager.resetPlayList();
for (Download data : downloads) {
BoxDownloadSong boxDownloadSong = CommonUtils.downloadToBean(data);
downloadSongList.add(boxDownloadSong);
MediaItem mediaItem = CommonUtils.downloadToMediaItem(data);
mediaControllerManager.addMusicPlayList(mediaItem);
}
mediaControllerManager.playPositionMusic(mDefaultPlayStartIndex);
mediaControllerManager.play();
}
}
});
}
}

View File

@ -1,169 +0,0 @@
package com.hi.music.player.ui.activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
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.AdapterResult;
import com.hi.music.player.api.HomeItemClickListener;
import com.hi.music.player.databinding.ActivityResultListBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue;
import com.hi.music.player.javabean.response.ResponseResult;
import com.hi.music.player.javabean.response.child.ResponseResultListChild;
import com.hi.music.player.javabean.response.child.ResponseSingle;
import com.hi.music.player.ui.fragmnt.viewmodel.VMCategoryList;
import com.hi.music.player.ui.fragmnt.viewmodel.VMResultList;
public class ResultListActivity extends BaseActivity<ActivityResultListBinding> implements HomeItemClickListener {
private VMResultList vm;
private String key;
@Override
protected ActivityResultListBinding getViewBinding() {
return ActivityResultListBinding.inflate(getLayoutInflater());
}
@Override
protected void onCreateInit() {
vm = getActivityScopeViewModel(VMResultList.class);
key = getIntent().getStringExtra(MyValue.KEY_SEARCH_RESULT_BROWSER_ID);
vm.getList(key);
vm.data.observe(this, new Observer<ResponseResult>() {
@Override
public void onChanged(ResponseResult responseResult) {
vb.pbLoading.setVisibility(View.GONE);
if (responseResult == null) {
vb.layoutError.linearRetry.setVisibility(View.VISIBLE);
return;
}
vb.pbLoading.setVisibility(View.GONE);
loadInfo(responseResult);
}
});
}
private void loadInfo(ResponseResult result) {
Glide.with(this)
.asDrawable()
.load(result.getMainCovert())
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
.placeholder(R.mipmap.im_placeholder)
.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;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(vb.covert);
vb.mainTitle.setText(result.getMainTitle());
AdapterResult adapterResult = new AdapterResult(this);
adapterResult.setHomeItemClickListener(this);
adapterResult.setData(result.getList());
vb.listRecycler.setAdapter(adapterResult);
vb.listRecycler.setLayoutManager(new LinearLayoutManager(this));
}
@Override
protected void onInitClick() {
vb.imBack.setOnClickListener(this);
vb.layoutError.tvRetry.setOnClickListener(this);
}
@Override
public boolean isFullScreen() {
return true;
}
@Override
public boolean statusBarLight() {
return false;
}
@Override
public boolean showPanel() {
return true;
}
@Override
public void onClick(View v) {
if (v.equals(vb.imBack)) {
finish();
} else if (v.equals(vb.layoutError.tvRetry)) {
vm.getList(key);
}
}
@Override
public void onClickResultSong(ResponseResultListChild child, int index) {
String videoId = child.getVideoId();
String playListId = child.getPlayListId();
String browserId = child.getBrowserId();
String pageType = child.getPageType();
String thumbnail = child.getThumbnail();
String songName = child.getSongName();
String subTitle = child.getSubTitle();
if (videoId != null && !videoId.isEmpty()) {
ResponseSingle responseSingle = new ResponseSingle();
responseSingle.setSongTitle(songName);
responseSingle.setSingerHead(thumbnail);
responseSingle.setVideoId(videoId);
responseSingle.setPlaylistId(playListId);
Intent intent = new Intent(this, PlayActivity.class);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, responseSingle);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX, index);
CommonUtils.LogMsg("-------------index=" + index);
startActivity(intent);
} else {
switch (pageType) {
case "MUSIC_PAGE_TYPE_ALBUM":
//专辑
CommonUtils.LogMsg("------------专辑-index=" + index + "--subTitle=" + subTitle);
case "MUSIC_PAGE_TYPE_PLAYLIST":
//精选
Intent intent1 = new Intent(this, CategoryListActivity.class);
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_TYPE, pageType);
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME, subTitle);
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID, browserId);
startActivity(intent1);
break;
case "MUSIC_PAGE_TYPE_ARTIST":
//粉丝可能还喜欢
Intent intent = new Intent(this, ResultListActivity.class);
intent.putExtra(MyValue.KEY_SEARCH_RESULT_BROWSER_ID, browserId);
startActivity(intent);
finish();
break;
}
}
}
}

View File

@ -1,168 +0,0 @@
package com.hi.music.player.ui.fragmnt;
import android.content.Intent;
import android.content.RestrictionsManager;
import android.graphics.drawable.Drawable;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.LinearLayoutManager;
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.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.hi.music.player.R;
import com.hi.music.player.adapter.AdapterHome;
import com.hi.music.player.api.HomeItemClickListener;
import com.hi.music.player.api.OnHasUrlAction;
import com.hi.music.player.databinding.FragmentHomeBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue;
import com.hi.music.player.javabean.response.ResponseHome;
import com.hi.music.player.javabean.response.child.ResponseCategory;
import com.hi.music.player.javabean.response.child.ResponseHomeChild;
import com.hi.music.player.javabean.response.child.ResponseSingle;
import com.hi.music.player.network.RetrofitManager;
import com.hi.music.player.ui.activity.CategoryListActivity;
import com.hi.music.player.ui.activity.PlayActivity;
import com.hi.music.player.ui.fragmnt.viewmodel.VMHome;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import okhttp3.ResponseBody;
public class HomeFragment extends BaseFragment<FragmentHomeBinding> implements HomeItemClickListener {
private VMHome vmHome;
private int requestCount = 1;
private int totalPage = 3;
private List<ResponseHomeChild> childList = new ArrayList<>();
@Override
protected FragmentHomeBinding getFragmentVb() {
// 返回正确的 ViewBinding 实例
return FragmentHomeBinding.inflate(getLayoutInflater());
}
@Override
protected void initView() {
// //标题导航栏颜色设置
// Vb.toolbar.setTitleTextColor(getResources().getColor(R.color.white));
AdapterHome adapterHome = new AdapterHome();
adapterHome.setHomeItemClickListener(this);
vmHome = getFragmentScopeViewModel(VMHome.class);
adapterHome.addLoadingFooter();
vmHome.getHome();
Vb.tvRetry.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
adapterHome.addLoadingFooter();
vmHome.getHome();
}
});
vmHome.data.observe(getViewLifecycleOwner(), new Observer<ResponseHome>() {
@Override
public void onChanged(ResponseHome responseHome) {
if (responseHome == null) {
adapterHome.removeLoadingFooter();
requestCount--;
if(requestCount == 0){
Vb.layoutError.setVisibility(View.VISIBLE);
Vb.recyclerSongOfTheDay.setVisibility(View.GONE);
}
return;
}
Vb.layoutError.setVisibility(View.GONE);
Vb.recyclerSongOfTheDay.setVisibility(View.VISIBLE);
List<ResponseHomeChild> childList1 = responseHome.getChildList();
if (childList1 == null) return;
childList.addAll(childList1);
adapterHome.removeLoadingFooter();
adapterHome.addData(childList1);
if (requestCount == 1) {
adapterHome.addLoadingFooter();
vmHome.getHomeMore();
requestCount++;
}
}
});
Vb.recyclerSongOfTheDay.setLayoutManager(new LinearLayoutManager(requireContext()));
Vb.recyclerSongOfTheDay.setAdapter(adapterHome);
Vb.recyclerSongOfTheDay.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (layoutManager != null && layoutManager.findLastVisibleItemPosition() == childList.size() - 1) {
if (requestCount < totalPage && !adapterHome.isLoadingAdded()) {
CommonUtils.LogMsg("------loadmore--");
adapterHome.addLoadingFooter();
vmHome.getHomeMore();
requestCount++;
}
}
}
});
}
@Override
public void onClickItemSinger(ResponseSingle data) {
FragmentActivity activity = getActivity();
if (activity != null) {
Intent intent = new Intent(activity, PlayActivity.class);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, data);
startActivity(intent);
}
}
@Override
public void onClickItemCategory(ResponseCategory data) {
FragmentActivity activity = getActivity();
if (activity != null) {
String pageType = data.getPageType();
String browseId = data.getBrowseId();
String twoSubtitle = data.getTwoSubtitle();
if (pageType.equals(MyValue.PAGE_TYPE_MV)||pageType.equals(MyValue.PAGE_TYPE_MV_LIST)) {
Intent intent = new Intent(activity, PlayActivity.class);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_MV, data);
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_MV);
startActivity(intent);
}
else {
Intent intent = new Intent(activity, CategoryListActivity.class);
intent.putExtra(MyValue.KEY_CATEGORY_LIST_TYPE, pageType);
intent.putExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME, twoSubtitle);
intent.putExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID, browseId);
startActivity(intent);
}
}
}
}

View File

@ -1,143 +0,0 @@
package com.hi.music.player.ui.fragmnt;
import android.content.Intent;
import android.util.Pair;
import android.view.View;
import androidx.annotation.OptIn;
import androidx.lifecycle.Observer;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.offline.Download;
import com.bumptech.glide.Glide;
import com.hi.music.player.R;
import com.hi.music.player.api.LikeSongListener;
import com.hi.music.player.databinding.FragmentProfileBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue;
import com.hi.music.player.javabean.BoxDownloadSong;
import com.hi.music.player.javabean.BoxLikeSong;
import com.hi.music.player.media3.MyDownloadService;
import com.hi.music.player.objectbox.ObjectBoxManager;
import com.hi.music.player.ui.activity.LikeSongActivity;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
import java.util.List;
import io.objectbox.reactive.DataSubscription;
public class ProfileFragment extends BaseFragment<FragmentProfileBinding> implements View.OnClickListener {
private DataSubscription dataSubscription;
private int likeSongCount = 0;
private int downloadSongCount = 0;
@Override
protected FragmentProfileBinding getFragmentVb() {
return FragmentProfileBinding.inflate(getLayoutInflater());
}
@OptIn(markerClass = UnstableApi.class)
@Override
protected void initView() {
dataSubscription = ObjectBoxManager.setLikeDataListener(new LikeSongListener() {
@Override
public void onLikeSongChange(List<BoxLikeSong> data) {
CommonUtils.LogMsg("------onLikeSongChange data=" + data.size());
int size = data.size();
likeSongCount = size;
Vb.tvLikeSize.setText(String.format(getString(R.string.like_song), size));
if (size == 0) {
Vb.likeCovert.setVisibility(View.GONE);
Vb.likeDefault.setVisibility(View.VISIBLE);
} else {
Vb.likeCovert.setVisibility(View.VISIBLE);
Vb.likeDefault.setVisibility(View.GONE);
BoxLikeSong boxLikeSong = data.get(size - 1);
Glide.with(requireContext())
.asDrawable()
.load(boxLikeSong.getCovert())
.placeholder(R.mipmap.im_placeholder)
.error(R.mipmap.im_placeholder)
.into(Vb.likeCovert);
}
}
});
MyDownloadService.updateDownloadUi(vmApplication);
vmApplication.downloadData.observe(getViewLifecycleOwner(), new Observer<List<Download>>() {
@Override
public void onChanged(List<Download> downloads) {
int size = downloads.size();
Vb.tvDownloadSize.setText(String.format(getString(R.string.download_song), size));
downloadSongCount = size;
if (size > 0) {
Download download = downloads.get(downloads.size() - 1);
BoxDownloadSong boxDownloadSong = CommonUtils.downloadToBean(download);
Vb.downloadCovert.setVisibility(View.VISIBLE);
Vb.downloadDefault.setVisibility(View.GONE);
Glide.with(requireContext())
.asDrawable()
.load(boxDownloadSong.getCovert())
.placeholder(R.mipmap.im_placeholder)
.error(R.mipmap.im_placeholder)
.into(Vb.downloadCovert);
} else {
Vb.downloadCovert.setVisibility(View.GONE);
Vb.downloadDefault.setVisibility(View.VISIBLE);
}
}
});
Vb.relayoutLike.setOnClickListener(this);
Vb.relayoutDownload.setOnClickListener(this);
}
@Override
public void onStart() {
super.onStart();
CommonUtils.LogMsg("------ProfileFragment-onStart");
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (dataSubscription != null) {
dataSubscription.cancel();
}
CommonUtils.LogMsg("------ProfileFragment-onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
CommonUtils.LogMsg("------ProfileFragment-onDestroy");
}
@Override
public void onClick(View v) {
if (v.equals(Vb.relayoutLike)) {
if (likeSongCount > 0) {
Intent intent = new Intent(requireActivity(), LikeSongActivity.class);
intent.putExtra(MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE, MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE_LIKE);
startActivity(intent);
}
} else if (v.equals(Vb.relayoutDownload)) {
if (downloadSongCount > 0) {
Intent intent = new Intent(requireActivity(), LikeSongActivity.class);
intent.putExtra(MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE, MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE_DOWNLOAD);
startActivity(intent);
}
}
}
}

View File

@ -1,230 +0,0 @@
package com.hi.music.player.ui.fragmnt;
import android.content.Intent;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.hi.music.player.adapter.AdapterSearch;
import com.hi.music.player.adapter.AdapterSuggestion;
import com.hi.music.player.api.HomeItemClickListener;
import com.hi.music.player.databinding.FragmentSearchBinding;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue;
import com.hi.music.player.javabean.response.ResponseSearch;
import com.hi.music.player.javabean.response.child.ResponseSearchChild;
import com.hi.music.player.javabean.response.child.ResponseSingle;
import com.hi.music.player.ui.activity.CategoryListActivity;
import com.hi.music.player.ui.activity.PlayActivity;
import com.hi.music.player.ui.activity.ResultListActivity;
import com.hi.music.player.ui.fragmnt.viewmodel.VMSearch;
import java.util.List;
public class SearchFragment extends BaseFragment<FragmentSearchBinding> implements HomeItemClickListener, View.OnClickListener {
private VMSearch vmSearch;
@Override
protected FragmentSearchBinding getFragmentVb() {
return FragmentSearchBinding.inflate(getLayoutInflater());
}
@Override
protected void initView() {
// Vb.etSearch.requestFocus();
vmSearch = getFragmentScopeViewModel(VMSearch.class);
Vb.etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String input = s.toString();
if (!input.isEmpty()) {
vmSearch.getSuggestion(input);
}
}
});
Vb.etSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
String s = v.getText().toString();
CommonUtils.LogMsg("------------v=" + s);
startQuery(s);
return true;
} else
return false;
}
});
initSuggestionRecycler();
initResultRecycler();
}
private void initSuggestionRecycler() {
AdapterSuggestion adapterSuggestion = new AdapterSuggestion();
Vb.recyclerSuggestion.setLayoutManager(new LinearLayoutManager(requireContext()));
Vb.recyclerSuggestion.setAdapter(adapterSuggestion);
adapterSuggestion.setHomeItemClickListener(this);
Vb.imCancel.setOnClickListener(this);
vmSearch.suggestion.observe(getViewLifecycleOwner(), new Observer<List<String>>() {
@Override
public void onChanged(List<String> strings) {
if (strings != null) {
adapterSuggestion.setData(strings);
CommonUtils.LogMsg("------------更新=");
}
}
});
}
private void initResultRecycler(){
AdapterSearch adapterSearch = new AdapterSearch();
adapterSearch.setHomeItemClickListener(this);
Vb.recyclerResult.setLayoutManager(new LinearLayoutManager(requireContext()));
Vb.recyclerResult.setAdapter(adapterSearch);
vmSearch.result.observe(getViewLifecycleOwner(), new Observer<List<ResponseSearch>>() {
@Override
public void onChanged(List<ResponseSearch> responseSearches) {
Vb.pbloading.setVisibility(View.GONE);
if(responseSearches == null){
Vb.recyclerResult.setVisibility(View.GONE);
Vb.layoutError.setVisibility(View.VISIBLE);
CommonUtils.LogMsg("------------更新结果 null");
return;
}
Vb.recyclerResult.setVisibility(View.VISIBLE);
Vb.layoutError.setVisibility(View.GONE);
adapterSearch.setData(responseSearches);
}
});
}
private void startQuery(String query){
Vb.pbloading.setVisibility(View.VISIBLE);
Vb.recyclerSuggestion.setVisibility(View.GONE);
Vb.recyclerResult.setVisibility(View.VISIBLE);
vmSearch.getSearchResult(query);
}
@Override
public void onClickItemSuggestion(boolean isSearch, String data) {
if (isSearch) {
startQuery(data);
} else {
Vb.etSearch.setText(data);
}
}
@Override
public void onClick(View v) {
if (v.equals(Vb.imCancel)) {
Vb.etSearch.setText("");
}
}
//点击搜索结果的play按钮
@Override
public void onClickSearchResultBest(ResponseSearch responseSearch) {
String beastBrowserId = responseSearch.getBeastBrowserId();
String beastVideoId = responseSearch.getBeastVideoId();
String beastSongTitle = responseSearch.getBeastSongTitle();
String beastSongTCovert = responseSearch.getBeastSongTCovert();
String pageType = responseSearch.getPageType();
if(beastVideoId!= null&&!beastVideoId.isEmpty()){
CommonUtils.LogMsg("---------击搜索结果的play按钮--beastVideoId="+beastVideoId);
ResponseSingle responseSingle = new ResponseSingle();
responseSingle.setSongTitle(beastSongTitle);
responseSingle.setSingerHead(beastSongTCovert);
responseSingle.setVideoId(beastVideoId);
responseSingle.setPlaylistId("");
Intent intent = new Intent(requireActivity(), PlayActivity.class);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, responseSingle);
startActivity(intent);
}else if(beastBrowserId!= null&&!beastBrowserId.isEmpty()){
CommonUtils.LogMsg("---------击搜索结果的play按钮--pageType="+pageType);
switch (pageType){
case "MUSIC_PAGE_TYPE_PLAYLIST":
case "MUSIC_PAGE_TYPE_ALBUM":
Intent intent1 = new Intent(requireActivity(), CategoryListActivity.class);
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_TYPE, pageType);
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME, responseSearch.getBeastSongDescribe());
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID, beastBrowserId);
startActivity(intent1);
break;
default:
Intent intent = new Intent(requireActivity(), ResultListActivity.class);
intent.putExtra(MyValue.KEY_SEARCH_RESULT_BROWSER_ID, beastBrowserId);
startActivity(intent);
break;
}
}
}
//点击搜索结果普通项
@Override
public void onClickSearchResult(ResponseSearchChild responseSearchChild) {
String browserId = responseSearchChild.getBrowserId();
String songVideoId = responseSearchChild.getSongVideoId();
String songCovert = responseSearchChild.getSongCovert();
String songTitle = responseSearchChild.getSongTitle();
String songDescribe = responseSearchChild.getSongDescribe();
if(browserId!= null&&!browserId.isEmpty()){
String pageType = responseSearchChild.getPageType();
CommonUtils.LogMsg("---------点击搜索结果--pageType="+pageType);
switch (pageType){
case "MUSIC_PAGE_TYPE_ARTIST":
Intent intent = new Intent(requireActivity(), ResultListActivity.class);
intent.putExtra(MyValue.KEY_SEARCH_RESULT_BROWSER_ID, browserId);
startActivity(intent);
break;
default:
Intent intent1 = new Intent(requireActivity(), CategoryListActivity.class);
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_TYPE, pageType);
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME, songDescribe);
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID, browserId);
startActivity(intent1);
break;
}
}else {
CommonUtils.LogMsg("---------点击搜索结果--VideoId="+songVideoId);
ResponseSingle responseSingle = new ResponseSingle();
responseSingle.setSongTitle(songTitle);
responseSingle.setSingerHead(songCovert);
responseSingle.setVideoId(songVideoId);
responseSingle.setPlaylistId("");
Intent intent = new Intent(requireActivity(), PlayActivity.class);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, responseSingle);
startActivity(intent);
}
}
}

View File

@ -60,7 +60,7 @@
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_gravity="center" android:layout_gravity="center"
android:src="@mipmap/im_placeholder" /> android:src="@mipmap/default_image" />
</FrameLayout> </FrameLayout>
<!-- 中间的两排 TextView --> <!-- 中间的两排 TextView -->

View File

@ -1,140 +0,0 @@
<?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:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
tools:context=".ui.activity.CategoryListActivity">
<ImageView
android:id="@+id/im_bg"
android:layout_width="match_parent"
android:layout_height="390dp" />
<View
android:layout_width="match_parent"
android:layout_height="390dp"
android:background="@drawable/black_gradient" />
<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_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="77dp">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/card_im"
app:cardBackgroundColor="@color/color_transparent"
android:layout_centerHorizontal="true"
app:cardCornerRadius="10dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/imCovert"
android:scaleType="centerCrop"
android:layout_width="250dp"
android:layout_height="220dp" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/card_im"
android:layout_centerHorizontal="true"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="21sp" />
<TextView
android:id="@+id/tvSingerName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tvTitle"
android:layout_centerHorizontal="true"
android:layout_marginStart="20dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="20dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="14sp" />
<TextView
android:id="@+id/tvSubTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tvSingerName"
android:layout_centerHorizontal="true"
android:layout_marginStart="20dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="20dp"
android:gravity="center"
android:textColor="@color/white"
android:textSize="14sp" />
<ImageView
android:id="@+id/btn_play"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_below="@id/tvSubTitle"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:src="@drawable/selector_icon_play"
android:visibility="invisible" />
<ProgressBar
android:id="@+id/pb_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateTint="@color/white" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<ImageView
android:id="@+id/im_back"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginStart="16dp"
android:layout_marginTop="35dp"
android:padding="9dp"
android:src="@drawable/arrow_bottom" />
<include
android:id="@+id/layout_error"
layout="@layout/layout_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="80dp" />
</FrameLayout>

View File

@ -1,87 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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:fillViewport="true"
tools:context=".ui.activity.ResultListActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/relayout_top"
android:layout_width="match_parent"
android:layout_height="280dp"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/covert"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/im_placeholder" />
<ImageView
android:id="@+id/im_back"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginStart="16dp"
android:layout_marginTop="35dp"
android:padding="9dp"
android:src="@drawable/arrow_bottom" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:background="@drawable/black_gradient" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="200dp"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/main_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="17sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/main_title" />
</LinearLayout>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:id="@+id/pb_loading"
android:indeterminateTint="@color/white" />
<include
android:id="@+id/layout_error"
layout="@layout/layout_error"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</androidx.core.widget.NestedScrollView>

View File

@ -1,116 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginTop="35dp"
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">
<androidx.cardview.widget.CardView
android:layout_width="60dp"
android:layout_height="60dp"
app:cardCornerRadius="6dp"
android:id="@+id/card_view"
android:layout_marginStart="10dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/top_im"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:src="@mipmap/im_placeholder" />
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/card_view"
android:layout_alignBottom="@id/card_view"
android:layout_marginStart="15dp"
android:layout_toStartOf="@id/im_play"
android:layout_toEndOf="@id/card_view"
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="60dp"
android:layout_height="60dp"
android:layout_alignParentEnd="true"
android:layout_marginEnd="22dp"
android:padding="20dp"
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" />
</RelativeLayout>
</LinearLayout>
</FrameLayout>

View File

@ -1,66 +0,0 @@
<LinearLayout 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:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_transparent"
android:orientation="vertical"
tools:context=".ui.fragmnt.HomeFragment">
<TextView
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="22sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_song_of_the_day"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="6dp" />
<RelativeLayout
android:id="@+id/layout_error"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="200dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:gravity="center"
android:text="@string/net_error"
android:textColor="@color/white"
android:textSize="16sp" />
<TextView
android:id="@+id/tv_retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_error"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:background="@drawable/bg_retry_btn"
android:paddingStart="15dp"
android:paddingTop="8dp"
android:paddingEnd="15dp"
android:paddingBottom="8dp"
android:text="@string/retry"
android:textColor="@color/white"
android:textSize="17sp" />
</RelativeLayout>
</LinearLayout>

View File

@ -1,94 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/default_play_list_color"
tools:context=".ui.fragmnt.SearchFragment">
<RelativeLayout
android:id="@+id/layout_et"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginStart="22dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="22dp"
android:background="@drawable/bg_search">
<EditText
android:id="@+id/et_search"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toStartOf="@id/im_cancel"
android:background="@null"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint="@string/search_hint"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:paddingStart="20dp"
android:textColor="@color/white"
android:textColorHint="@color/seek_bg_color" />
<ImageView
android:id="@+id/im_cancel"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:paddingStart="13dp"
android:paddingEnd="13dp"
android:src="@drawable/icon_cancel" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_suggestion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/layout_et"
android:layout_alignStart="@id/layout_et"
android:layout_alignEnd="@id/layout_et" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/layout_et"
android:layout_alignStart="@id/layout_et"
android:layout_alignEnd="@id/layout_et"
android:visibility="gone" />
<RelativeLayout
android:id="@+id/layout_error"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/layout_et"
android:visibility="gone">
<TextView
android:id="@+id/tv_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginStart="15dp"
android:layout_marginTop="200dp"
android:layout_marginEnd="15dp"
android:gravity="center"
android:text="@string/no_result"
android:textColor="@color/white"
android:textSize="16sp" />
</RelativeLayout>
<ProgressBar
android:id="@+id/pbloading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/layout_et"
android:layout_centerHorizontal="true"
android:layout_marginTop="200dp"
android:visibility="gone"
android:indeterminateTint="@color/white" />
</RelativeLayout>

View File

@ -18,7 +18,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@mipmap/im_placeholder" /> android:src="@mipmap/default_image" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -17,7 +17,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@mipmap/im_placeholder" /> android:src="@mipmap/default_image" />
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>

View File

@ -20,7 +20,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@mipmap/im_placeholder" /> android:src="@mipmap/default_image" />
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>

View File

@ -22,7 +22,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:background="@color/black" android:background="@color/black"
android:src="@mipmap/im_placeholder" /> android:src="@mipmap/default_image" />
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>

View File

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/head_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:textColor="@color/text_color_1"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:textSize="18sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_singer"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_category"
android:layout_width="match_parent"
android:visibility="gone"
android:paddingStart="7dp"
android:paddingEnd="14dp"
android:layout_height="wrap_content" />
<View
android:layout_width="wrap_content"
android:id="@+id/place"
android:layout_height="74dp" />
</LinearLayout>

View File

@ -1,66 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="@+id/item_layout"
android:paddingStart="20dp">
<androidx.cardview.widget.CardView
android:id="@+id/card"
android:layout_width="60dp"
android:layout_height="60dp"
app:cardElevation="0dp"
android:layout_centerVertical="true"
app:cardCornerRadius="6dp">
<ImageView
android:id="@+id/im_covert"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:src="@mipmap/im_placeholder" />
</androidx.cardview.widget.CardView>
<com.hi.music.player.customerview.AnimaPlayingView
android:id="@+id/view_playing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@id/card"
android:layout_alignTop="@id/card"
android:layout_alignEnd="@id/card"
android:layout_alignBottom="@id/card"
android:layout_marginBottom="10dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="12dp"
android:paddingEnd="10dp"
android:layout_toEndOf="@id/card"
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:maxLines="1"
android:ellipsize="end"
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>

View File

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="5dp"
android:orientation="vertical">
<ImageView
android:id="@+id/header"
android:layout_width="170dp"
android:layout_height="170dp"
android:src="@mipmap/im_placeholder" />
<TextView
android:id="@+id/tv_title"
android:layout_width="169dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:layout_marginTop="10dp"
android:text="@string/app_name"
android:textColor="@color/text_color_1"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_subtitle"
android:layout_width="169dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:maxLines="2"
android:text="@string/app_name"
android:textColor="@color/text_color_2"
android:textSize="12sp" />
<View
android:layout_width="match_parent"
android:id="@+id/view"
android:visibility="gone"
android:layout_height="100dp"/>
</LinearLayout>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="vertical">
<ImageView
android:id="@+id/header"
android:layout_width="66dp"
android:layout_height="66dp"
android:scaleType="fitXY"
android:layout_marginStart="14dp"
android:layout_centerVertical="true"
android:src="@mipmap/im_placeholder" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:paddingEnd="10dp"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/header"
android:orientation="vertical">
<TextView
android:id="@+id/tv_song_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="99999999999999999999999999999999999"
android:maxLines="1"
android:maxWidth="200dp"
android:ellipsize="end"
android:textColor="@color/text_color_1"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_singer_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/app_name"
android:maxLines="1"
android:maxWidth="200dp"
android:ellipsize="end"
android:textColor="@color/text_color_2"
android:textSize="12sp" />
<!-- <TextView-->
<!-- android:id="@+id/tv_describe"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_marginTop="4dp"-->
<!-- android:maxLines="1"-->
<!-- android:ellipsize="end"-->
<!-- android:text="@string/app_name"-->
<!-- android:textColor="@color/text_color_1"-->
<!-- android:textSize="14sp" />-->
</LinearLayout>
</RelativeLayout>

View File

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/layout_panel"
android:layout_width="match_parent"
android:layout_height="74dp"
android:layout_gravity="bottom"
android:background="@drawable/panel_bg"
android:paddingStart="14dp"
android:paddingEnd="14dp">
<androidx.cardview.widget.CardView
android:id="@+id/cardimage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="2dp"
app:cardCornerRadius="200dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/image"
android:layout_width="52dp"
android:layout_height="52dp"
android:src="@mipmap/im_placeholder" />
</androidx.cardview.widget.CardView>
<com.hi.music.player.helper.CircularProgressBar
android:id="@+id/circular_pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@id/cardimage"
android:layout_alignTop="@id/cardimage"
android:layout_alignEnd="@id/cardimage"
android:layout_alignBottom="@id/cardimage"
android:layout_gravity="center" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="22dp"
android:layout_toStartOf="@id/frame_play"
android:layout_toEndOf="@id/image"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/black"
android:textSize="14sp" />
<TextView
android:id="@+id/singer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/panel_singer_color"
android:textSize="12sp" />
</LinearLayout>
<FrameLayout
android:id="@+id/frame_play"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_marginEnd="10dp"
android:layout_toStartOf="@id/im_next"
android:paddingStart="10dp"
android:paddingEnd="10dp">
<ImageView
android:id="@+id/im_play"
android:layout_width="34dp"
android:layout_height="34dp"
android:layout_gravity="center"
android:src="@drawable/selector_panel_icon_play" />
</FrameLayout>
<ImageView
android:id="@+id/im_next"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="10dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:src="@drawable/icon_next_black"
android:visibility="visible" />
</RelativeLayout>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 454 KiB

View File

@ -1,18 +1,10 @@
<resources> <resources>
<string name="app_name">MusicApp</string> <string name="app_name">Offline Music Player</string>
<!-- TODO: Remove or change this placeholder text --> <!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="song_of_the_day">Song Of The Day</string>
<string name="recently_played">Recently Played</string>
<string name="top_artists">Top Artists</string>
<string name="trending_in_shorts">Trending in Shorts</string>
<string name="new_releases">New Releases</string>
<string name="musicoo">Musicoo</string>
<string name="library">Library</string>
<string name="listen_music_anytime">Listen Music Anytime</string> <string name="listen_music_anytime">Listen Music Anytime</string>
<string name="resource_loading">Resource Loading...</string> <string name="resource_loading">Resource Loading...</string>
<string name="ready_to_sleep">Ready to sleep</string> <string name="ready_to_sleep">Sounds of Serenity</string>
<string name="we_ve_carefully_prepared_sounds_for_you">We\'ve carefully prepared sounds for you 🔥</string> <string name="we_ve_carefully_prepared_sounds_for_you">Soothing tunes crafted for deep relaxation and sleep 🌙</string>
<string name="white_noise">White noise</string> <string name="white_noise">White noise</string>
<string name="voice_of_nature">Voice of Nature</string> <string name="voice_of_nature">Voice of Nature</string>
<string name="setting">Setting</string> <string name="setting">Setting</string>
@ -21,24 +13,4 @@
<string name="share">Share</string> <string name="share">Share</string>
<string name="privacy_policy">Privacy Policy</string> <string name="privacy_policy">Privacy Policy</string>
<string name="terms_of_service">Terms of Service</string> <string name="terms_of_service">Terms of Service</string>
<string name="play_next">Play next</string>
<string name="retry">Try again</string>
<string name="An_error_occurred">An error occurred</string>
<string name="search_hint">Search songs, artists…</string>
<string name="play">Play</string>
<string name="no_next_song_yet">There is no next song yet</string>
<string name="image_loading_failed">Image loading failed</string>
<string name="song_loading_failed">Song loading failed</string>
<string name="playList_loading_failed">Playlist loading failed</string>
<string name="time_format">%d:%02d:%02d</string>
<string name="minute_time_format">%d:%02d</string>
<string name="like">Like</string>
<string name="download">Download</string>
<string name="like_song">Songs %d</string>
<string name="download_song">Offline %d</string>
<string name="text_like_song">Favorite Songs</string>
<string name="text_offline_song">Offline Songs</string>
<string name="text_has_downloaded">It\'s already downloaded</string>
<string name="net_error">An error occurred in the network request. Please try again.</string>
<string name="no_result">No results yet</string>
</resources> </resources>