添加专辑队列有问题

队列没生效
This commit is contained in:
yutou 2020-11-25 16:19:58 +08:00
parent 614a366351
commit 0d446525ac
12 changed files with 587 additions and 250 deletions

View File

@ -29,6 +29,10 @@ android {
release { release {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.yutou
}
debug {
signingConfig signingConfigs.yutou
} }
} }
compileOptions { compileOptions {

View File

@ -1,219 +1,276 @@
package com.yutou.nas_music_player.Adapters; package com.yutou.nas_music_player.Adapters;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.util.ArrayMap; import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.SectionIndexer; import android.widget.Toast;
import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.github.promeg.pinyinhelper.Pinyin; import com.kaopiz.kprogresshud.KProgressHUD;
import com.yutou.nas_music_player.Datas.MusicData; import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.MyApplication; import com.yutou.nas_music_player.Interfaces.NetworkInterface;
import com.yutou.nas_music_player.R; import com.yutou.nas_music_player.R;
import com.yutou.nas_music_player.containers.MusicContainer; import com.yutou.nas_music_player.containers.MusicContainer;
import com.yutou.nas_music_player.tools.AppData; import com.yutou.nas_music_player.tools.AppData;
import com.yutou.nas_music_player.tools.AppTools; import com.yutou.nas_music_player.tools.AppTools;
import com.yutou.nas_music_player.tools.Helpers; import com.yutou.nas_music_player.tools.NetworkTool;
import com.yutou.nas_music_player.tools.StringUtil; import com.yutou.nas_music_player.tools.StringUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import cc.ibooker.ztextviewlib.MarqueeTextView; import cc.ibooker.ztextviewlib.MarqueeTextView;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation; import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
public class MusicLibsAdapter extends RecyclerView.Adapter<MusicLibsAdapter.ViewHolder> implements SectionIndexer { public class MusicLibsAdapter extends ArrayAdapter<MusicData> {
public static final int LIBS_MODEL_ALL = 0; public static final int LIBS_MODEL_ALL = 0;
public static final int LIBS_MODEL_Album = 1; public static final int LIBS_MODEL_Album = 1;
public static final int LIBS_MODEL_Artist = 2; public static final int LIBS_MODEL_Artist = 2;
public static final int LIBS_MODEL_Tmp = 3; public static final int LIBS_MODEL_Tmp = 3;
public static final int LIBS_MODEL_PLAY_LIST = 4; public static final int LIBS_MODEL_PLAY_LIST = 4;
public static final int LIBS_MODEL_PLAY_Collection = 5; public static final int LIBS_MODEL_PLAY_Collection = 5;
private LinkedHashMap<String,List<MusicData>> musicDataList;
private String mSections = "ABCDEFGHIJKLMNOPQRSTUVWXYZ#"; List<MusicData> list;
private HashMap<Integer, Integer> sectionsTranslator = new HashMap<>(); Map<Integer, Bitmap> icons;
private ArrayList<Integer> mSectionPositions;
private ArrayList<String> mSectionPositionsKey; public MusicLibsAdapter(Context context, int model) {
public MusicLibsAdapter(int model){ super(context, R.layout.layout_music_libs_item);
list = new ArrayList<>();
icons = new HashMap<>();
initData(model); initData(model);
} }
private int model = -1; private int model = -1;
public void initData(int model) { public void initData(int model) {
this.model = model; this.model = model;
list.clear();
System.out.println("填充序列 设置model " + model); System.out.println("填充序列 设置model " + model);
List<MusicData> tmp=new ArrayList<>(); Map<String, List<MusicData>> map;
switch (model) { switch (model) {
case LIBS_MODEL_Album: case LIBS_MODEL_Album:
musicDataList= MusicContainer.getInstance().getAllAlbumMapList(); map = MusicContainer.getInstance().getAllAlbumMapList();
for (String title : map.keySet()) {
MusicData data = new MusicData();
data.setTitle(title);
data.setFile(map.get(title).get(0).getFile());
data.setArtist("");
list.add(data);
}
break; break;
case LIBS_MODEL_Artist: case LIBS_MODEL_Artist:
musicDataList=MusicContainer.getInstance().getAllArtistMapList(); map = MusicContainer.getInstance().getAllArtistMapList();
for (String title : map.keySet()) {
MusicData data = new MusicData();
data.setTitle(title);
data.setFile(map.get(title).get(0).getFile());
data.setArtist("");
list.add(data);
}
break; break;
case LIBS_MODEL_Tmp: case LIBS_MODEL_Tmp:
tmp=MusicContainer.getInstance().getTmpPlayList(); list = MusicContainer.getInstance().getTmpPlayList();
musicDataList=new LinkedHashMap<>();
musicDataList.put("list",tmp);
break; break;
case LIBS_MODEL_PLAY_LIST: case LIBS_MODEL_PLAY_LIST:
tmp=MusicContainer.getInstance().getPlayList(); list = MusicContainer.getInstance().getPlayList();
musicDataList=new LinkedHashMap<>();
musicDataList.put("list",tmp);
break; break;
case LIBS_MODEL_PLAY_Collection: case LIBS_MODEL_PLAY_Collection:
tmp=new ArrayList<>(); list = new ArrayList<>();
musicDataList=new LinkedHashMap<>();
musicDataList.put("list",tmp);
break; break;
case LIBS_MODEL_ALL: case LIBS_MODEL_ALL:
default: default:
tmp=MusicContainer.getLibs().getMainData(); list.addAll(MusicContainer.getLibs().getMainData());
musicDataList=new LinkedHashMap<>();
musicDataList.put("list",tmp);
} }
} }
@Override
public Object[] getSections() {
List<String> sections = new ArrayList<>(27);
mSectionPositions = new ArrayList<>();
mSectionPositionsKey = new ArrayList<>();
System.out.println("填充序列:"+musicDataList.size()+" "+model+" "+musicDataList.containsKey("list"));
if(musicDataList.containsKey("list")){
List<MusicData> list=musicDataList.get("list");
for (int i = 0; i < list.size(); i++) {
String section= Pinyin.toPinyin(list.get(i).getTitle().charAt(0)).substring(0,1).toUpperCase();
if (!sections.contains(section)) {
sections.add(section);
System.out.println(section);
mSectionPositions.add(i);
}
}
}else {
/* Iterator<String> iterator=musicDataList.keySet().iterator();
int i=0;
while (iterator.hasNext()){
String key=iterator.next();
if(StringUtil.isEmpty(key)){
key="#";
}
String section= Pinyin.toPinyin(key.charAt(0)).toUpperCase();
if (!sections.contains(section)) {
sections.add(section);
mSectionPositions.add(i);
}
i++;
}*/
int i=0;
for (String key : musicDataList.keySet()) {
if(StringUtil.isEmpty(key)){
key="#";
}
mSectionPositionsKey.add(key);
String section=Pinyin.toPinyin(key.charAt(0)).substring(0,1).toUpperCase();
System.out.println(section);
if (!sections.contains(section)) {
sections.add(section);
mSectionPositions.add(i);
}
i++;
}
}
ArrayList<String> alphabetFull = new ArrayList<>(Arrays.asList(Pinyin.toPinyin(mSections, ",").split(",")));
sectionsTranslator = Helpers.Companion.sectionsHelper(sections, alphabetFull);
return alphabetFull.toArray(new String[0]);
}
@Override @Override
public int getPositionForSection(int i) { public int getCount() {
return mSectionPositions.get(sectionsTranslator.get(i)); return list.size();
} }
@Nullable
@Override @Override
public int getSectionForPosition(int i) { public MusicData getItem(int position) {
return i; return list.get(position);
} }
private int scrollStatus = 0;
@NonNull public void setScrollStatus(int scrollStatus) {
@Override this.scrollStatus = scrollStatus;
public MusicLibsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_music_libs_item, parent, false);
return new ViewHolder(v);
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@NonNull
@Override @Override
public void onBindViewHolder(@NonNull MusicLibsAdapter.ViewHolder holder, int position) { public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
System.out.println("填充数据?"+position); ViewHolder holder;
if(musicDataList.containsKey("list")){ if (convertView == null) {
List<MusicData> list=musicDataList.get("list"); convertView = LayoutInflater.from(getContext()).inflate(R.layout.layout_music_libs_item, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
MusicData data = list.get(position); MusicData data = list.get(position);
holder.title.setText(data.getTitle()); holder.title.setText(data.getTitle());
holder.artist.setText(data.getArtist()); holder.artist.setText(data.getArtist());
if (!data.isDir()) { if (!data.isDir()) {
if (model != LIBS_MODEL_Album && model != LIBS_MODEL_Artist) {
holder.message.setText(data.getBitRate() + "kbps | " + data.getSampleRate() + "hz | " + data.getEncodingType()); holder.message.setText(data.getBitRate() + "kbps | " + data.getSampleRate() + "hz | " + data.getEncodingType());
holder.icon.setImageBitmap(data.getImg()); holder.message.setVisibility(View.VISIBLE);
holder.artist.setVisibility(View.VISIBLE);
} else {
holder.message.setVisibility(View.GONE);
holder.artist.setVisibility(View.GONE);
}
// holder.icon.setImageBitmap(ThumbnailUtils.extractThumbnail(data.getImg(), 64,64));
if (scrollStatus == 0) {
if (icons.containsKey(position)) {
Glide.with(getContext()).load(icons.get(position))
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(holder.icon);
} else { } else {
holder.message.setText("");
holder.icon.setImageResource(R.drawable.ic_dir); holder.icon.setImageResource(R.drawable.ic_dir);
} }
} else { } else {
System.out.println(mSectionPositionsKey.size()+" "+musicDataList.size()); Bitmap bitmap;
String key=mSectionPositionsKey.get(position); if (icons.containsKey(position)) {
if(musicDataList.containsKey(key)) { bitmap = icons.get(position);
MusicData data = musicDataList.get(key).get(0); } else {
holder.title.setText(data.getAlbum()); bitmap = data.getImg(64, 64);
// holder.icon.setImageBitmap(data.getImg()); if (bitmap == null) {
holder.artist.setVisibility(View.GONE); holder.icon.setImageResource(R.drawable.ic_dir);
holder.message.setVisibility(View.GONE); } else {
AppData.handler.post(new Runnable() { icons.put(position, bitmap);
@Override }
public void run() { }
Glide.with(MyApplication.application).load(data.getImg()) if (bitmap != null)
Glide.with(getContext()).load(bitmap)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3))) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(holder.icon); .into(holder.icon);
} }
}); holder.icon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println(data.getFile());
System.out.println(data.getImageUrl());
System.out.println(data.getImg(-1, -1));
if (data.getImg(-1, -1) != null) {
Glide.with(getContext()).load(data.getImg(-1, -1))
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(holder.icon);
}
}
});
if (!StringUtil.isEmpty(data.getMd5())) {
if (data.getMd5().equals(MusicContainer.getInstance().getNowPlayData().getMd5())) {
holder.play_mask.setVisibility(View.VISIBLE);
} else {
holder.play_mask.setVisibility(View.GONE);
}
}
} else {
holder.message.setText("");
holder.play_mask.setVisibility(View.GONE);
holder.icon.setImageResource(R.drawable.ic_dir);
}
holder.top.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("model = "+model);
if (model == LIBS_MODEL_Album) {
addAlbumList(data.getTitle());
} else if (data.isDir()) {
//showAddTmpListDialog(data);
} else {
MusicContainer.getInstance().addTmpList(data);
Toast.makeText(getContext(), "已添加到队列中", Toast.LENGTH_LONG).show();
for (MusicData musicData : MusicContainer.getInstance().getTmpPlayList()) {
System.out.println("临时队列:" + musicData.getTitle());
} }
/* for (String title : musicDataList.keySet()) {
MusicData data=musicDataList.get(title).get(0);
holder.icon.setImageBitmap(data.getImg());
holder.title.setText(title);
holder.artist.setVisibility(View.GONE);
holder.message.setVisibility(View.GONE);
}*/
} }
} }
private void addAlbumList(String album) {
System.out.println("添加专辑:"+album);
List<MusicData> list = MusicContainer.getInstance().getAllAlbumMapList().get(album);
for (MusicData musicData : list) {
System.out.println(musicData.getTitle()+"| 专辑名 ="+musicData.getAlbum());
MusicContainer.getInstance().addTmpList(musicData);
}
Toast.makeText(getContext(), "已添加到队列中", Toast.LENGTH_LONG).show();
}
private void showAddTmpListDialog(MusicData data) {
AlertDialog dialog = new AlertDialog.Builder(getContext())
.setTitle("添加文件夹到队列")
.setMessage("将文件夹中所有歌曲添加到队列?")
.setPositiveButton("添加", new DialogInterface.OnClickListener() {
KProgressHUD hud;
@Override @Override
public int getItemCount() { public void onClick(DialogInterface dialog, int which) {
if(musicDataList.containsKey("list")){ hud = AppTools.showLoading(getContext());
return musicDataList.get("list").size(); MusicContainer.getLibs().getMusicList(data.getFileBase64(), true, new NetworkInterface() {
@Override
public void httpGetData(Object data, int state) {
List<?> list = (List<?>) data;
for (Object musicData : list) {
MusicContainer.getInstance().addTmpList((MusicData) musicData);
} }
return musicDataList.keySet().size(); AppData.handler.post(new Runnable() {
@Override
public void run() {
hud.dismiss();
Toast.makeText(getContext(), "已添加到队列中", Toast.LENGTH_LONG).show();
} }
});
}
@Override
public void httpError(Exception e) {
}
});
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create();
dialog.show();
}
});
return convertView;
}
static class ViewHolder extends RecyclerView.ViewHolder { static class ViewHolder extends RecyclerView.ViewHolder {
MarqueeTextView title, artist, message; MarqueeTextView title, artist, message;
LinearLayout buttons; LinearLayout buttons;
ImageButton collection, top, dislike; ImageButton collection, top, dislike;
ImageView icon; ImageView icon, play_mask;
ViewHolder(View itemView) { ViewHolder(View itemView) {
super(itemView); super(itemView);
@ -225,6 +282,7 @@ public class MusicLibsAdapter extends RecyclerView.Adapter<MusicLibsAdapter.View
top = itemView.findViewById(R.id.top); top = itemView.findViewById(R.id.top);
dislike = itemView.findViewById(R.id.dislike); dislike = itemView.findViewById(R.id.dislike);
icon = itemView.findViewById(R.id.album_image); icon = itemView.findViewById(R.id.album_image);
play_mask = itemView.findViewById(R.id.play_mask);
} }
} }
} }

View File

@ -4,11 +4,10 @@ package com.yutou.nas_music_player.Datas;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable; import android.media.ThumbnailUtils;
import android.util.Base64; import android.util.Base64;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.yutou.nas_music_player.Interfaces.DownloadInterface;
import com.yutou.nas_music_player.Interfaces.NetworkInterface; import com.yutou.nas_music_player.Interfaces.NetworkInterface;
import com.yutou.nas_music_player.MyApplication; import com.yutou.nas_music_player.MyApplication;
import com.yutou.nas_music_player.R; import com.yutou.nas_music_player.R;
@ -16,6 +15,7 @@ import com.yutou.nas_music_player.tools.AppTools;
import com.yutou.nas_music_player.tools.NetworkTool; import com.yutou.nas_music_player.tools.NetworkTool;
import com.yutou.nas_music_player.tools.StringUtil; import com.yutou.nas_music_player.tools.StringUtil;
import androidx.annotation.Nullable;
import androidx.palette.graphics.Palette; import androidx.palette.graphics.Palette;
public class MusicData { public class MusicData {
@ -152,32 +152,43 @@ public class MusicData {
this.file = file; this.file = file;
} }
public String getPlayFileBase64() { public String getFileBase64() {
return new String(Base64.encode(file.replace("\r\n", "").getBytes(), Base64.DEFAULT)); return new String(Base64.encode(file.getBytes(), Base64.DEFAULT)).replace("\n", "");
} }
public String getPlayUrl() { public String getPlayUrl() {
return NetworkTool.NetworkAPI.HOME + NetworkTool.NetworkAPI.MUSIC_PLAY return NetworkTool.NetworkAPI.HOME + NetworkTool.NetworkAPI.MUSIC_PLAY
+ "?random=false&token=" + NetworkTool.NetworkAPI.HTTP_KEY + "&filePath=" + getPlayFileBase64(); + "?random=false&token=" + NetworkTool.NetworkAPI.HTTP_KEY + "&filePath=" + getFileBase64();
} }
private boolean isDownloadImg = false; private boolean isDownloadImg = false;
public Bitmap getImg() { public String getImageUrl(){
return NetworkTool.NetworkAPI.MUSIC_IMAGE+"?fileName="+ getFileBase64();
}
public Bitmap getImg(int width, int height) {
if (img != null) { if (img != null) {
if(width==-1&&height==-1){
return img; return img;
} }
return ThumbnailUtils.extractThumbnail(img,width,height);
}
if (isDownloadImg) { if (isDownloadImg) {
return null; return null;
} }
img = AppTools.getSaveBitmap(getPlayFileBase64()); img = AppTools.getSaveBitmap(getFileBase64());
if (img != null) { if (img != null) {
if(width==-1&&height==-1){
return img; return img;
} }
return ThumbnailUtils.extractThumbnail(img,width,height);
}
img = null; img = null;
isDownloadImg = true; isDownloadImg = true;
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
json.put("fileName", getPlayFileBase64()); json.put("fileName", getFileBase64());
System.out.println("--->"+ getFileBase64());
NetworkTool.init().httpGet(NetworkTool.NetworkAPI.MUSIC_IMAGE, json, new NetworkInterface() { NetworkTool.init().httpGet(NetworkTool.NetworkAPI.MUSIC_IMAGE, json, new NetworkInterface() {
@Override @Override
public void httpGetData(Object data, int state) { public void httpGetData(Object data, int state) {
@ -186,7 +197,7 @@ public class MusicData {
if (json.getInteger("code") == 0) { if (json.getInteger("code") == 0) {
byte[] bytes = json.getBytes("data"); byte[] bytes = json.getBytes("data");
img = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); img = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
AppTools.saveBitmap(img,getPlayFileBase64()); AppTools.saveBitmap(img, getFileBase64());
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -199,8 +210,12 @@ public class MusicData {
isDownloadImg = false; isDownloadImg = false;
} }
}); });
if(width==-1&&height==-1){
return img; return img;
} }
return ThumbnailUtils.extractThumbnail(img,width,height);
}
public int getImageColor() { public int getImageColor() {
if (img == null) { if (img == null) {
@ -281,6 +296,18 @@ public class MusicData {
this.md5 = md5; this.md5 = md5;
} }
@Override
public boolean equals(@Nullable Object obj) {
if(obj instanceof MusicData){
MusicData data= (MusicData) obj;
if(StringUtil.isEmpty(md5)||StringUtil.isEmpty(data.getMd5())){
return false;
}
return md5.equals(data.getMd5());
}
return false;
}
@Override @Override
public String toString() { public String toString() {
return "MusicData{" + return "MusicData{" +

View File

@ -9,6 +9,7 @@ import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat; import android.support.v4.media.session.PlaybackStateCompat;
import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.services.MusicService; import com.yutou.nas_music_player.services.MusicService;
import java.util.ArrayList; import java.util.ArrayList;
@ -59,6 +60,11 @@ public class MediaBrowserHelper {
callbacks.add(playListener); callbacks.add(playListener);
} }
public void play(MusicData item) {
MusicContainer.getInstance().setNowPlayData(item);
getTransportControls().play();
}
private class MediaBrowserConnectionCallback extends MediaBrowserCompat.ConnectionCallback { private class MediaBrowserConnectionCallback extends MediaBrowserCompat.ConnectionCallback {
@Override @Override
public void onConnected() { public void onConnected() {

View File

@ -11,6 +11,7 @@ import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.Datas.PreviousPlayerList; import com.yutou.nas_music_player.Datas.PreviousPlayerList;
import com.yutou.nas_music_player.Interfaces.NetworkInterface; import com.yutou.nas_music_player.Interfaces.NetworkInterface;
import com.yutou.nas_music_player.MyApplication; import com.yutou.nas_music_player.MyApplication;
import com.yutou.nas_music_player.tools.CollectionTools;
import com.yutou.nas_music_player.tools.ConfigTools; import com.yutou.nas_music_player.tools.ConfigTools;
import com.yutou.nas_music_player.tools.NetworkTool; import com.yutou.nas_music_player.tools.NetworkTool;
import com.yutou.nas_music_player.tools.StringUtil; import com.yutou.nas_music_player.tools.StringUtil;
@ -20,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@ -43,6 +45,7 @@ public class MusicContainer {
private List<MusicData> playList, tmpList; private List<MusicData> playList, tmpList;
private LinkedHashMap<String, List<MusicData>> albumMapList; private LinkedHashMap<String, List<MusicData>> albumMapList;
private LinkedHashMap<String, List<MusicData>> artistMapList; private LinkedHashMap<String, List<MusicData>> artistMapList;
private LinkedHashMap<String, List<MusicData>> collectionMapList;
private int playModel = PLAY_MODEL_RANDOM; private int playModel = PLAY_MODEL_RANDOM;
private PreviousPlayerList previousPlayerList; private PreviousPlayerList previousPlayerList;
@ -53,6 +56,7 @@ public class MusicContainer {
tmpList = new ArrayList<>(); tmpList = new ArrayList<>();
albumMapList = new LinkedHashMap<>(); albumMapList = new LinkedHashMap<>();
artistMapList = new LinkedHashMap<>(); artistMapList = new LinkedHashMap<>();
collectionMapList = new LinkedHashMap<>();
previousPlayerList = new PreviousPlayerList(); previousPlayerList = new PreviousPlayerList();
browserHelpers = new ArrayList<>(); browserHelpers = new ArrayList<>();
playIndex = ConfigTools.getPreferences().getInt("playIndex", 0); playIndex = ConfigTools.getPreferences().getInt("playIndex", 0);
@ -121,6 +125,7 @@ public class MusicContainer {
public void addBrowserHelper(MediaBrowserHelper browserHelper) { public void addBrowserHelper(MediaBrowserHelper browserHelper) {
browserHelpers.add(browserHelper); browserHelpers.add(browserHelper);
} }
public void removeBrowserHelper(MediaBrowserHelper browserHelper) { public void removeBrowserHelper(MediaBrowserHelper browserHelper) {
browserHelpers.remove(browserHelper); browserHelpers.remove(browserHelper);
} }
@ -236,8 +241,8 @@ public class MusicContainer {
builder.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, Long.parseLong(data.getTrack())); builder.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, Long.parseLong(data.getTrack()));
builder.putLong(MediaMetadataCompat.METADATA_KEY_DISC_NUMBER, Long.parseLong(data.getDisc_no())); builder.putLong(MediaMetadataCompat.METADATA_KEY_DISC_NUMBER, Long.parseLong(data.getDisc_no()));
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, ((int) (data.getDurationAsDouble() * 1000))); builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, ((int) (data.getDurationAsDouble() * 1000)));
if (data.getImg() != null) { if (data.getImg(-1, -1) != null) {
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, data.getImg()); builder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, data.getImg(-1, -1));
} }
builder.putString("md5", data.getMd5()); builder.putString("md5", data.getMd5());
metadataCompat = builder.build(); metadataCompat = builder.build();
@ -334,6 +339,7 @@ public class MusicContainer {
private void playAlbumList(boolean isNext) { private void playAlbumList(boolean isNext) {
} }
public List<MusicData> getPlayList() { public List<MusicData> getPlayList() {
if (!tmpList.isEmpty()) { if (!tmpList.isEmpty()) {
return tmpList; return tmpList;
@ -343,16 +349,48 @@ public class MusicContainer {
} }
return libs.mainData; return libs.mainData;
} }
private void flashCollection() {
collectionMapList.clear();
JSONArray array = CollectionTools.readConfig();
for (Object o : array) {
JSONObject json = (JSONObject) o;
JSONArray collections = json.getJSONArray("collections");
List<MusicData> tmp = new ArrayList<>();
for (Object collection : collections) {
MusicData data = libs.findMusic((String) collection, libs.mainData);
if (data != null) {
tmp.add(data);
}
}
collectionMapList.put(json.getString("title"), tmp);
}
}
public void addTmpList(MusicData data) {
tmpList.add(data);
}
public void removeTmpList(MusicData data) {
tmpList.remove(data);
}
public List<MusicData> getTmpPlayList() { public List<MusicData> getTmpPlayList() {
return tmpList; return tmpList;
} }
public LinkedHashMap<String, List<MusicData>> getAllAlbumMapList() { public LinkedHashMap<String, List<MusicData>> getAllAlbumMapList() {
return albumMapList; return albumMapList;
} }
public LinkedHashMap<String, List<MusicData>> getAllArtistMapList() { public LinkedHashMap<String, List<MusicData>> getAllArtistMapList() {
return artistMapList; return artistMapList;
} }
public Map<String, List<MusicData>> getCollectionMap() {
return collectionMapList;
}
public class MusicLibs { public class MusicLibs {
private List<MusicData> mainData; private List<MusicData> mainData;
@ -393,29 +431,56 @@ public class MusicContainer {
} }
}); });
} }
public void updateLibsMap(){
for (MusicData musicData : mainData) { public void getMusicList(String path, boolean type, NetworkInterface networkInterface) {
List<MusicData> artist; JSONObject json = new JSONObject();
List<MusicData> album; json.put("path", path);
if(artistMapList.containsKey(musicData.getArtist())){ json.put("type", type);
artist=artistMapList.get(musicData.getArtist()); NetworkTool.init().httpGet(NetworkTool.NetworkAPI.MUSIC_LIST, json, new NetworkInterface() {
}else{ @Override
artist=new ArrayList<>(); public void httpGetData(Object data, int state) {
JSONObject json = JSONObject.parseObject((String) data);
if (json.getInteger("code") == 0) {
networkInterface.httpGetData(JSONArray.parseArray(json.getJSONArray("data").toJSONString(), MusicData.class), 0);
} }
if(albumMapList.containsKey(musicData.getAlbum())){ }
album=albumMapList.get(musicData.getAlbum());
}else{ @Override
album=new ArrayList<>(); public void httpError(Exception e) {
}
});
}
public void updateLibsMap() {
for (MusicData musicData : mainData) {
List<MusicData> artist = new ArrayList<>();
List<MusicData> album = new ArrayList<>();
String albumName = StringUtil.isEmpty(musicData.getAlbum()) ?
"未知专辑"
: musicData.getAlbum();
String artistName = StringUtil.isEmpty(musicData.getArtist()) ?
"未知作曲家"
: musicData.getArtist();
if (albumMapList.containsKey(albumName)) {
album.addAll(albumMapList.get(albumName));
}
album.add(musicData);
if (artistMapList.containsKey(artistName)) {
artist.addAll(artistMapList.get(artistName));
} }
artist.add(musicData); artist.add(musicData);
album.add(musicData); artistMapList.put(artistName, artist);
albumMapList.put(musicData.getAlbum(),album); albumMapList.put(albumName, album);
artistMapList.put(musicData.getArtist(),artist);
} }
//flashCollection();
if (initInterface != null) if (initInterface != null)
initInterface.init(); initInterface.init();
initInterface = null; initInterface = null;
} }
public MusicData findMusic(String md5, List<MusicData> list) { public MusicData findMusic(String md5, List<MusicData> list) {
for (MusicData data : list) { for (MusicData data : list) {
if (data.getMd5() == null) { if (data.getMd5() == null) {
@ -429,6 +494,9 @@ public class MusicContainer {
} }
public int findMusicIndex(String md5, List<MusicData> list) { public int findMusicIndex(String md5, List<MusicData> list) {
if (StringUtil.isEmpty(md5)) {
return -1;
}
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
if (list.get(i).getMd5() == null) { if (list.get(i).getMd5() == null) {
continue; continue;

View File

@ -0,0 +1,74 @@
package com.yutou.nas_music_player.tools;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.containers.MusicContainer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
/**
* 最后再做用sqlite来存储用配置文件不太放心
*/
public class CollectionTools {
public CollectionTools(){
}
public static JSONArray readConfig(){
return JSONArray.parseArray(ConfigTools.getPreferences().getString(" collection", "[]"));
}
private static void saveConfig(JSONArray array){
ConfigTools.getPreferences().edit().putString("collection",array.toJSONString()).apply();
}
public static List<MusicData> getCollectionTitleList(){
JSONArray array=readConfig();
List<MusicData> list=new ArrayList<>();
for (Object o : array) {
JSONObject json= (JSONObject) o;
MusicData data=new MusicData();
data.setTitle(json.getString("title"));
data.setDir(true);
list.add(data);
}
return list;
}
public static boolean isCollectionTitle(String title){
List<MusicData> list=getCollectionTitleList();
for (MusicData data : list) {
if(data.getTitle().equals(title)){
return true;
}
}
return false;
}
public static void addCollectionTitle(String title){
JSONArray array=readConfig();
JSONObject json=new JSONObject();
json.put("title",title);
json.put("collections",new JSONArray());
array.add(json);
saveConfig(array);
}
public static void addCollection(String title,MusicData data){
JSONArray array=readConfig();
List<MusicData> list=getCollectionList(title);
list.add(data);
}
public static List<MusicData> getCollectionList(String title){
JSONArray array=readConfig();
List<MusicData> list=new ArrayList<>();
for (Object o : array) {
JSONObject json= (JSONObject) o;
if(json.getString("title").equals(title)) {
JSONArray co=json.getJSONArray("collections");
for (Object md5 : co) {
MusicData data=MusicContainer.getLibs().findMusic((String)md5,MusicContainer.getLibs().getMainData());
list.add(data);
}
break;
}
}
return list;
}
}

View File

@ -118,7 +118,7 @@ public class NetworkTool {
e.printStackTrace(); e.printStackTrace();
if (networkInterface != null) if (networkInterface != null)
networkInterface.httpError(e); networkInterface.httpError(e);
Log.e(TAG, url + "\n" + e); Log.e(TAG, url + " body =" + body.toJSONString());
} }
} }
}).start(); }).start();
@ -208,8 +208,8 @@ public class NetworkTool {
Set<String> keys = json.keySet(); Set<String> keys = json.keySet();
for (String key : keys) { for (String key : keys) {
try { try {
string.append("&").append(key).append("=").append(json.getString(key)); string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key),"UTF-8"));
} catch (JSONException e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
try { try {
string.append("&").append(URLEncoder.encode(key, "UTF-8")).append("="); string.append("&").append(URLEncoder.encode(key, "UTF-8")).append("=");

View File

@ -6,10 +6,15 @@ import android.util.ArrayMap;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem; import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;
import com.yutou.nas_music_player.Adapters.MusicLibsAdapter; import com.yutou.nas_music_player.Adapters.MusicLibsAdapter;
import com.yutou.nas_music_player.R; import com.yutou.nas_music_player.R;
import com.yutou.nas_music_player.containers.MediaBrowserHelper;
import com.yutou.nas_music_player.containers.MusicContainer;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -25,20 +30,35 @@ public class MusicLibsFragment extends Fragment {
public static Map<Integer, MusicLibsFragment> map = new HashMap<>(); public static Map<Integer, MusicLibsFragment> map = new HashMap<>();
private Context context; private Context context;
private View view; private View view;
private IndexFastScrollRecyclerView recyclerView; private ListView recyclerView;
private int model = 0; private int model = 0;
private MediaBrowserHelper browserHelper;
public MusicLibsFragment() { public MusicLibsFragment() {
} }
public MusicLibsFragment(Context context, int model) { public MusicLibsFragment(Context context, int model) {
this.context = context; this.context = context;
this.model = model; this.model = model;
} }
public void setPlayContainer(MediaBrowserHelper browserHelper) {
this.browserHelper = browserHelper;
}
public void setModel(int model) { public void setModel(int model) {
this.model = model; this.model = model;
adapter.initData(model); adapter.initData(model);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
@Override
public void onDestroy() {
super.onDestroy();
browserHelper=null;
}
@Nullable @Nullable
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@ -52,12 +72,53 @@ public class MusicLibsFragment extends Fragment {
initViews(); initViews();
return view; return view;
} }
private MusicLibsAdapter adapter;
public void initViews(){
recyclerView=view.findViewById(R.id.fast_scroller_recycler); private MusicLibsAdapter adapter;
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
adapter=new MusicLibsAdapter(model); public void initViews() {
recyclerView = view.findViewById(R.id.listView);
// recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
adapter = new MusicLibsAdapter(getContext(), model);
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
recyclerView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
adapter.setScrollStatus(1);
adapter.notifyDataSetChanged();
} else {
adapter.setScrollStatus(0);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
recyclerView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (browserHelper != null) {
browserHelper.play(adapter.getItem(position));
adapter.notifyDataSetChanged();
}
}
});
adapter.setScrollStatus(1);
adapter.notifyDataSetChanged();
int pos = 0;
switch (model) {
case MusicLibsAdapter.LIBS_MODEL_ALL:
pos = MusicContainer.getLibs().findMusicIndex(MusicContainer.getInstance().getNowPlayData().getMd5()
, MusicContainer.getLibs().getMainData());
break;
}
if (pos != -1)
recyclerView.setSelection(pos);
}
public MusicLibsAdapter getAdapter() {
return adapter;
} }
} }

View File

@ -33,6 +33,7 @@ import com.yutou.nas_music_player.tools.AppData;
import com.yutou.nas_music_player.tools.AppTools; import com.yutou.nas_music_player.tools.AppTools;
import com.yutou.nas_music_player.tools.ConfigTools; import com.yutou.nas_music_player.tools.ConfigTools;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Timer; import java.util.Timer;
@ -162,12 +163,19 @@ public class MainActivity extends AppCompatActivity {
playModel.setOnClickListener(new View.OnClickListener() { playModel.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
int model = (int) playModel.getTag(); /*int model = (int) playModel.getTag();
if (model == MusicContainer.PLAY_MODEL_LOOP) { if (model == MusicContainer.PLAY_MODEL_LOOP) {
setPlayModelButton(MusicContainer.PLAY_MODEL_RANDOM); setPlayModelButton(MusicContainer.PLAY_MODEL_RANDOM);
return; return;
} }
setPlayModelButton(model + 1); setPlayModelButton(model + 1);*/
LinkedHashMap<String,List<MusicData>> map=MusicContainer.getInstance().getAllAlbumMapList();
for (String key : map.keySet()) {
System.out.println("专辑名:"+key);
for (MusicData data : map.get(key)) {
System.out.println(" |单曲:"+data.getTitle()+" 所属专辑:"+data.getAlbum());
}
}
} }
}); });
getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() { getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {
@ -250,13 +258,13 @@ public class MainActivity extends AppCompatActivity {
+ String.format(Locale.CHINA, "%02d", seconds)); + String.format(Locale.CHINA, "%02d", seconds));
int model = ConfigTools.getPreferences().getInt("playModel", MusicContainer.PLAY_MODEL_RANDOM); int model = ConfigTools.getPreferences().getInt("playModel", MusicContainer.PLAY_MODEL_RANDOM);
setPlayModelButton(model); setPlayModelButton(model);
if (data.getImg() != null) { if (data.getImg(-1,-1) != null) {
setImage(data); setImage(data);
} else { } else {
new Timer().schedule(new TimerTask() { new Timer().schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
if (data.getImg() != null) { if (data.getImg(-1,-1) != null) {
AppData.handler.post(new Runnable() { AppData.handler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -292,13 +300,11 @@ public class MainActivity extends AppCompatActivity {
} }
private void setImage(MusicData data) { private void setImage(MusicData data) {
album_image.setImageBitmap(data.getImg());
background_image.setImageBitmap(data.getImg());
setBarColor(data.getImageColor()); setBarColor(data.getImageColor());
Glide.with(this).load(data.getImg()) Glide.with(this).load(data.getImg(-1,-1))
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3))) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(album_image); .into(album_image);
Glide.with(this).load(data.getImg()) Glide.with(this).load(data.getImg(200,200))
.apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 3))) .apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 3)))
.into(background_image); .into(background_image);
} }

View File

@ -33,6 +33,7 @@ import java.util.TimerTask;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
import cc.ibooker.ztextviewlib.MarqueeTextView; import cc.ibooker.ztextviewlib.MarqueeTextView;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation; import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
@ -47,7 +48,7 @@ public class PlayLibsActivity extends AppCompatActivity {
private SmartTabLayout tabLayout; private SmartTabLayout tabLayout;
private ViewPager viewPager; private ViewPager viewPager;
private int index = 0;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
@ -118,18 +119,27 @@ public class PlayLibsActivity extends AppCompatActivity {
getSupportFragmentManager(), FragmentPagerItems.with(this) getSupportFragmentManager(), FragmentPagerItems.with(this)
.add("全部", MusicLibsFragment.class) .add("全部", MusicLibsFragment.class)
.add("专辑", MusicLibsFragment.class) .add("专辑", MusicLibsFragment.class)
.add("队列", MusicLibsFragment.class)
.create()); .create());
viewPager.setAdapter(adapter); viewPager.setAdapter(adapter);
tabLayout.setViewPager(viewPager); tabLayout.setViewPager(viewPager);
tabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { tabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
boolean init = false;
@Override @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (!init) {
MusicLibsFragment fragment = MusicLibsFragment.map.get(position);
fragment.setPlayContainer(browserHelper);
init = true;
}
} }
@Override @Override
public void onPageSelected(int position) { public void onPageSelected(int position) {
index = position;
MusicLibsFragment fragment = MusicLibsFragment.map.get(position); MusicLibsFragment fragment = MusicLibsFragment.map.get(position);
fragment.setPlayContainer(browserHelper);
if (fragment != null) { if (fragment != null) {
switch (position) { switch (position) {
case 0: case 0:
@ -138,20 +148,22 @@ public class PlayLibsActivity extends AppCompatActivity {
case 1: case 1:
fragment.setModel(MusicLibsAdapter.LIBS_MODEL_Album); fragment.setModel(MusicLibsAdapter.LIBS_MODEL_Album);
break; break;
case 2:
fragment.setModel(MusicLibsAdapter.LIBS_MODEL_Tmp);
break;
} }
} }
} }
@Override @Override
public void onPageScrollStateChanged(int state) { public void onPageScrollStateChanged(int state) {
} }
}); });
} }
private void setImage(MusicData data) { private void setImage(MusicData data) {
album_image.setImageBitmap(data.getImg()); album_image.setImageBitmap(data.getImg(-1, -1));
Glide.with(this).load(data.getImg()) Glide.with(this).load(data.getImg(64, 64))
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3))) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(album_image); .into(album_image);
} }
@ -164,13 +176,13 @@ public class PlayLibsActivity extends AppCompatActivity {
artist.setText(data.getArtist()); artist.setText(data.getArtist());
progressBar.setMax((int) (data.getDurationAsDouble() * 1000)); progressBar.setMax((int) (data.getDurationAsDouble() * 1000));
progressBar.setProgress(bar_pos); progressBar.setProgress(bar_pos);
if (data.getImg() != null) { if (data.getImg(-1, -1) != null) {
setImage(data); setImage(data);
} else { } else {
new Timer().schedule(new TimerTask() { new Timer().schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
if (data.getImg() != null) { if (data.getImg(-1, -1) != null) {
AppData.handler.post(new Runnable() { AppData.handler.post(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -182,6 +194,8 @@ public class PlayLibsActivity extends AppCompatActivity {
} }
}, 0, 100); }, 0, 100);
} }
if (MusicLibsFragment.map!=null&&MusicLibsFragment.map.containsKey(index))
MusicLibsFragment.map.get(index).getAdapter().notifyDataSetChanged();
} }
@ -190,6 +204,9 @@ public class PlayLibsActivity extends AppCompatActivity {
super.onDestroy(); super.onDestroy();
browserHelper.onStop(); browserHelper.onStop();
browserHelper = null; browserHelper = null;
for (Integer integer : MusicLibsFragment.map.keySet()) {
MusicLibsFragment.map.get(integer).onDestroy();
}
MusicLibsFragment.map.clear(); MusicLibsFragment.map.clear();
MusicLibsFragment.map = null; MusicLibsFragment.map = null;
finish(); finish();

View File

@ -4,8 +4,9 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<in.myinnos.alphabetsindexfastscrollrecycler.IndexFastScrollRecyclerView
android:id="@+id/fast_scroller_recycler" <ListView
android:id="@+id/listView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
</LinearLayout> </LinearLayout>

View File

@ -4,6 +4,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="15dp" android:layout_marginEnd="15dp"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
@ -11,6 +12,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView <ImageView
android:id="@+id/album_image" android:id="@+id/album_image"
android:layout_width="64dp" android:layout_width="64dp"
@ -18,6 +23,16 @@
android:transitionName="album_image" android:transitionName="album_image"
app:srcCompat="@mipmap/ic_launcher" /> app:srcCompat="@mipmap/ic_launcher" />
<ImageView
android:id="@+id/play_mask"
android:layout_width="64dp"
android:layout_height="64dp"
android:background="#66000000"
android:visibility="gone"
android:scaleType="center"
app:srcCompat="@android:drawable/ic_media_play" />
</FrameLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"