update
有内存泄露
This commit is contained in:
parent
c7c6a07e45
commit
26bdcffb68
@ -40,4 +40,8 @@ dependencies {
|
||||
implementation 'androidx.palette:palette:1.0.0'
|
||||
implementation 'com.github.zrunker:ZTextView:v1.0.2'
|
||||
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.5'
|
||||
implementation 'com.kaopiz:kprogresshud:1.2.0'
|
||||
implementation 'com.ogaclejapan.smarttablayout:library:2.0.0@aar'
|
||||
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity
|
||||
android:name=".views.OpenActivity"
|
||||
android:theme="@style/Theme.AppCompat.NoActionBar">
|
||||
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@ -25,7 +25,11 @@
|
||||
<activity
|
||||
android:name=".views.MainActivity"
|
||||
android:fitsSystemWindows="true"
|
||||
android:theme="@style/Theme.AppCompat.NoActionBar" />
|
||||
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" />
|
||||
<activity
|
||||
android:name=".views.PlayLibsActivity"
|
||||
android:fitsSystemWindows="true"
|
||||
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" />
|
||||
|
||||
<service
|
||||
android:name=".services.MusicService"
|
||||
|
@ -1,14 +1,18 @@
|
||||
package com.yutou.nas_music_player.containers;
|
||||
package com.yutou.nas_music_player.Datas;
|
||||
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.util.Base64;
|
||||
|
||||
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.MyApplication;
|
||||
import com.yutou.nas_music_player.R;
|
||||
import com.yutou.nas_music_player.tools.AppTools;
|
||||
import com.yutou.nas_music_player.tools.NetworkTool;
|
||||
import com.yutou.nas_music_player.tools.StringUtil;
|
||||
|
||||
@ -149,7 +153,7 @@ public class MusicData {
|
||||
}
|
||||
|
||||
public String getPlayFileBase64() {
|
||||
return new String(Base64.encode(file.getBytes(), Base64.DEFAULT));
|
||||
return new String(Base64.encode(file.replace("\r\n", "").getBytes(), Base64.DEFAULT));
|
||||
}
|
||||
|
||||
public String getPlayUrl() {
|
||||
@ -166,6 +170,11 @@ public class MusicData {
|
||||
if (isDownloadImg) {
|
||||
return null;
|
||||
}
|
||||
img = AppTools.getSaveBitmap(getPlayFileBase64());
|
||||
if (img != null) {
|
||||
return img;
|
||||
}
|
||||
img = null;
|
||||
isDownloadImg = true;
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("fileName", getPlayFileBase64());
|
||||
@ -173,9 +182,15 @@ public class MusicData {
|
||||
@Override
|
||||
public void httpGetData(Object data, int state) {
|
||||
JSONObject json = JSONObject.parseObject(data.toString());
|
||||
try {
|
||||
if (json.getInteger("code") == 0) {
|
||||
byte[] bytes = json.getBytes("data");
|
||||
img = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
|
||||
AppTools.saveBitmap(img,getPlayFileBase64());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
img = BitmapFactory.decodeResource(MyApplication.application.getResources(), R.mipmap.ic_launcher);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package com.yutou.nas_music_player.Datas;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 播放记录
|
||||
*/
|
||||
public class PreviousPlayerList {
|
||||
private static final int INDEX=10;//记录十条
|
||||
private List<MusicData> list;
|
||||
public PreviousPlayerList(){
|
||||
list=new ArrayList<>();
|
||||
}
|
||||
public void add(MusicData musicData){
|
||||
MusicData tmp = null;
|
||||
for (MusicData data : list) {
|
||||
if(data.getFile().equals(musicData.getFile())){
|
||||
tmp=data;
|
||||
}
|
||||
|
||||
}
|
||||
if(tmp!=null){
|
||||
list.remove(tmp);
|
||||
}
|
||||
list.add(musicData);
|
||||
}
|
||||
public MusicData getMusicData(){
|
||||
if(list.size()>1){
|
||||
list.remove(list.size()-1);
|
||||
}
|
||||
return list.get(list.size()-1);
|
||||
}
|
||||
}
|
@ -53,7 +53,6 @@ public class MediaBrowserHelper {
|
||||
public void regPlayListener(MediaControllerCompat.Callback playListener) {
|
||||
callbacks.add(playListener);
|
||||
}
|
||||
|
||||
private class MediaBrowserConnectionCallback extends MediaBrowserCompat.ConnectionCallback {
|
||||
@Override
|
||||
public void onConnected() {
|
||||
|
@ -1,11 +1,17 @@
|
||||
package com.yutou.nas_music_player.containers;
|
||||
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Build;
|
||||
import android.support.v4.media.MediaMetadataCompat;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yutou.nas_music_player.Datas.MusicData;
|
||||
import com.yutou.nas_music_player.Datas.PreviousPlayerList;
|
||||
import com.yutou.nas_music_player.Interfaces.NetworkInterface;
|
||||
import com.yutou.nas_music_player.MyApplication;
|
||||
import com.yutou.nas_music_player.tools.ConfigTools;
|
||||
import com.yutou.nas_music_player.tools.NetworkTool;
|
||||
import com.yutou.nas_music_player.tools.StringUtil;
|
||||
|
||||
@ -18,23 +24,26 @@ import java.util.Random;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import static android.media.MediaPlayer.SEEK_PREVIOUS_SYNC;
|
||||
|
||||
|
||||
public class MusicContainer {
|
||||
public static final int PLAY_MODEL_RANDOM = 0;
|
||||
public static final int PLAY_MODEL_LIST = 1;
|
||||
public static final int PLAY_MODEL_TMP_LIST = 2;
|
||||
public static final int PLAY_MODEL_ALBUM = 3;
|
||||
public static final int PLAY_MODEL_RANDOM = 0;//随机
|
||||
public static final int PLAY_MODEL_ORDER = 1;//顺序
|
||||
public static final int PLAY_MODEL_ONE_LOOP = 2;//单曲循环
|
||||
public static final int PLAY_MODEL_LOOP = 3;//列表循环
|
||||
private static MusicContainer container;
|
||||
private MusicLibs libs;
|
||||
private MediaPlayer mediaPlayer;
|
||||
private int playIndex = 0;
|
||||
private MusicData nowPlayData = null;
|
||||
private final MusicLibsInitInterface initInterface;
|
||||
private MusicLibsInitInterface initInterface;
|
||||
private List<MediaPlayer.OnCompletionListener> completionListener;
|
||||
private MediaBrowserHelper browserHelper;
|
||||
private List<MusicData> playList, tmpList;
|
||||
private Map<String, List<MusicData>> albumMapList;
|
||||
private int playModel = PLAY_MODEL_RANDOM;
|
||||
private PreviousPlayerList previousPlayerList;
|
||||
|
||||
private MusicContainer(MusicLibsInitInterface initInterface) {
|
||||
this.initInterface = initInterface;
|
||||
@ -42,6 +51,8 @@ public class MusicContainer {
|
||||
playList = new ArrayList<>();
|
||||
tmpList = new ArrayList<>();
|
||||
albumMapList = new HashMap<>();
|
||||
previousPlayerList = new PreviousPlayerList();
|
||||
playIndex = ConfigTools.getPreferences().getInt("playIndex", 0);
|
||||
initMediaPlayer();
|
||||
libs = new MusicLibs();
|
||||
}
|
||||
@ -52,13 +63,37 @@ public class MusicContainer {
|
||||
|
||||
private void initMediaPlayer() {
|
||||
completionListener = new ArrayList<>();
|
||||
mediaPlayer.setLooping(false);
|
||||
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
||||
@Override
|
||||
public void onCompletion(MediaPlayer mp) {
|
||||
|
||||
System.out.println(nowPlayData.getFile());
|
||||
int tmp=((int)(nowPlayData.getDurationAsDouble()*1000)-mp.getCurrentPosition());
|
||||
if(tmp>1000){
|
||||
System.out.println("发生跳曲行为");
|
||||
mp.start();
|
||||
seekTo(mp.getCurrentPosition());
|
||||
}else {
|
||||
System.out.println("自动播放完成,进行下一曲");
|
||||
playTimer.cancel();
|
||||
playTimer = null;
|
||||
browserHelper.getTransportControls().skipToNext();
|
||||
}
|
||||
}
|
||||
});
|
||||
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
|
||||
@Override
|
||||
public boolean onError(MediaPlayer mp, int what, int extra) {
|
||||
System.out.println("播放错误: what="+what+" extra="+extra);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
||||
@Override
|
||||
public void onPrepared(MediaPlayer mp) {
|
||||
System.out.println("调用了onPrepared");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -110,13 +145,15 @@ public class MusicContainer {
|
||||
isPause = false;
|
||||
return;
|
||||
}
|
||||
ConfigTools.getPreferences().edit().putInt("playIndex", playIndex).apply();
|
||||
nowPlayData = data;
|
||||
String url = data.getPlayUrl();
|
||||
previousPlayerList.add(data);
|
||||
try {
|
||||
if (mediaPlayer.isPlaying()) {
|
||||
mediaPlayer.stop();
|
||||
mediaPlayer.reset();
|
||||
}
|
||||
mediaPlayer.reset();
|
||||
mediaPlayer.setDataSource(url);
|
||||
mediaPlayer.prepare();
|
||||
mediaPlayer.start();
|
||||
@ -133,11 +170,23 @@ public class MusicContainer {
|
||||
}
|
||||
}, 0, 1000);
|
||||
}
|
||||
ConfigTools.getPreferences().edit().putString(ConfigTools.previous_music, JSONObject.toJSONString(data)).apply();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void seekTo(long pos) {
|
||||
System.out.println("跳帧:" + pos);
|
||||
if (mediaPlayer.isPlaying()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
mediaPlayer.seekTo(pos, SEEK_PREVIOUS_SYNC);
|
||||
} else {
|
||||
mediaPlayer.seekTo((int) pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Timer playTimer;
|
||||
|
||||
public MediaMetadataCompat getNowPlayMetadataCompat() {
|
||||
@ -162,7 +211,13 @@ public class MusicContainer {
|
||||
return 8888L;
|
||||
}
|
||||
|
||||
private MediaMetadataCompat metadataCompat;
|
||||
private String metaDataFile;
|
||||
|
||||
public MediaMetadataCompat getMetadataCompat(MusicData data) {
|
||||
if (data.getFile().equals(metaDataFile)) {
|
||||
return metadataCompat;
|
||||
}
|
||||
MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
|
||||
builder.putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, data.getTitle());
|
||||
builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, data.getArtist());
|
||||
@ -172,12 +227,13 @@ public class MusicContainer {
|
||||
builder.putLong(MediaMetadataCompat.METADATA_KEY_YEAR, getYear(data.getYear()));
|
||||
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_DURATION, ((int) data.getDurationAsDouble()) * 1000);
|
||||
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, ((int) (data.getDurationAsDouble() * 1000)));
|
||||
if (data.getImg() != null) {
|
||||
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, data.getImg());
|
||||
}
|
||||
builder.putString("md5", data.getMd5());
|
||||
return builder.build();
|
||||
metadataCompat = builder.build();
|
||||
return metadataCompat;
|
||||
}
|
||||
|
||||
public static MusicLibs getLibs() {
|
||||
@ -191,16 +247,20 @@ public class MusicContainer {
|
||||
mediaPlayer.pause();
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放下一曲
|
||||
*/
|
||||
public void playNext() {
|
||||
System.out.println("播放模式:" + playModel);
|
||||
switch (playModel) {
|
||||
case PLAY_MODEL_LIST:
|
||||
playList(true);
|
||||
case PLAY_MODEL_ORDER:
|
||||
playOrder(false);
|
||||
break;
|
||||
case PLAY_MODEL_TMP_LIST:
|
||||
playTmpList(true);
|
||||
case PLAY_MODEL_ONE_LOOP:
|
||||
playOneLoop();
|
||||
break;
|
||||
case PLAY_MODEL_ALBUM:
|
||||
playAlbumList(true);
|
||||
case PLAY_MODEL_LOOP:
|
||||
playOrder(true);
|
||||
break;
|
||||
case PLAY_MODEL_RANDOM:
|
||||
default:
|
||||
@ -208,18 +268,73 @@ public class MusicContainer {
|
||||
}
|
||||
}
|
||||
|
||||
private void playList(boolean isNext) {
|
||||
|
||||
/**
|
||||
* 播放上一曲
|
||||
*/
|
||||
public void playPrevious() {
|
||||
playIndex--;
|
||||
MusicData data = previousPlayerList.getMusicData();
|
||||
if (data != null) {
|
||||
play(data);
|
||||
} else {
|
||||
Toast.makeText(MyApplication.application, "没有上一曲记录", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void playTmpList(boolean isNext) {
|
||||
|
||||
/**
|
||||
* 顺序播放
|
||||
*
|
||||
* @param isLoop 循环播放列表
|
||||
*/
|
||||
private void playOrder(boolean isLoop) {
|
||||
if (tmpList.size() != 0) {//有插队列表,优先播放
|
||||
play(tmpList.get(0));//后插入先播放
|
||||
tmpList.remove(0);
|
||||
} else if (playList.size() == 0) {//播放列表为空,以所有歌列表顺序播放
|
||||
if (libs.mainData.size() > (playIndex + 1)) {
|
||||
playIndex++;
|
||||
} else {
|
||||
playIndex = 0;
|
||||
}
|
||||
play(libs.mainData.get(playIndex));
|
||||
} else {//播放列表中的歌单
|
||||
if (playList.size() > (playIndex + 1)) {
|
||||
playIndex++;
|
||||
}
|
||||
if (isLoop) {
|
||||
playIndex = 0;
|
||||
play(playList.get(playIndex));
|
||||
} else {
|
||||
playList.clear();//列表播放完了,清空
|
||||
playOfAllRandom();//暂时先设计成后续随机播放,毕竟列表已经空了
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 单曲循环
|
||||
*/
|
||||
private void playOneLoop() {
|
||||
play(nowPlayData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 专辑播放
|
||||
*
|
||||
* @param isNext 下一首
|
||||
*/
|
||||
private void playAlbumList(boolean isNext) {
|
||||
|
||||
}
|
||||
|
||||
public List<MusicData> getPlayList(){
|
||||
if(!tmpList.isEmpty()){
|
||||
return tmpList;
|
||||
}
|
||||
if(!playList.isEmpty()){
|
||||
return playList;
|
||||
}
|
||||
return libs.mainData;
|
||||
}
|
||||
public class MusicLibs {
|
||||
private List<MusicData> mainData;
|
||||
|
||||
@ -251,6 +366,7 @@ public class MusicContainer {
|
||||
}
|
||||
if (initInterface != null) {
|
||||
initInterface.init();
|
||||
initInterface = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -262,14 +378,30 @@ public class MusicContainer {
|
||||
});
|
||||
}
|
||||
|
||||
public MusicData findMusic(String md5) {
|
||||
for (MusicData data : mainData) {
|
||||
public MusicData findMusic(String md5,List<MusicData> list) {
|
||||
for (MusicData data : list) {
|
||||
if (data.getMd5() == null) {
|
||||
continue;
|
||||
}
|
||||
if (md5.contains(data.getMd5())) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int findMusicIndex(String md5, List<MusicData> list) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list.get(i).getMd5() == null) {
|
||||
continue;
|
||||
}
|
||||
if (md5.contains((list.get(i).getMd5()))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public interface MusicLibsInitInterface {
|
||||
|
@ -1,12 +1,8 @@
|
||||
package com.yutou.nas_music_player.services;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
import android.support.v4.media.MediaBrowserCompat;
|
||||
import android.support.v4.media.MediaMetadataCompat;
|
||||
@ -19,15 +15,10 @@ import androidx.media.MediaBrowserServiceCompat;
|
||||
|
||||
import com.yutou.nas_music_player.containers.MediaNotificationManager;
|
||||
import com.yutou.nas_music_player.containers.MusicContainer;
|
||||
import com.yutou.nas_music_player.containers.MusicData;
|
||||
import com.yutou.nas_music_player.tools.AppData;
|
||||
import com.yutou.nas_music_player.Datas.MusicData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import static android.media.MediaPlayer.SEEK_PREVIOUS_SYNC;
|
||||
|
||||
public class MusicService extends MediaBrowserServiceCompat {
|
||||
public MediaSessionCompat mediaSession;
|
||||
@ -78,7 +69,7 @@ public class MusicService extends MediaBrowserServiceCompat {
|
||||
result.sendResult(mediaItems);
|
||||
}
|
||||
|
||||
public void onSeekTo(long pos) {
|
||||
public void seekToNotification(long pos) {
|
||||
MusicData data = MusicContainer.getInstance().getNowPlayData();
|
||||
MediaMetadataCompat metadataCompat = MusicContainer.getInstance().getMetadataCompat(data);
|
||||
Notification notification = notificationManager.getNotification(metadataCompat, builderState(pos).build(), getSessionToken());
|
||||
@ -163,13 +154,9 @@ public class MusicService extends MediaBrowserServiceCompat {
|
||||
@Override
|
||||
public void onSeekTo(long pos) {
|
||||
super.onSeekTo(pos);
|
||||
System.out.println("SeeTo :"+pos);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
MusicContainer.getInstance().getMediaPlayer().seekTo(pos,SEEK_PREVIOUS_SYNC);
|
||||
}else{
|
||||
MusicContainer.getInstance().getMediaPlayer().seekTo((int) pos);
|
||||
}
|
||||
MusicService.this.onSeekTo(pos);
|
||||
System.out.println("接收到跳帧指令~~~");
|
||||
MusicContainer.getInstance().seekTo(pos);
|
||||
MusicService.this.seekToNotification(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -182,6 +169,8 @@ public class MusicService extends MediaBrowserServiceCompat {
|
||||
@Override
|
||||
public void onSkipToPrevious() {
|
||||
super.onSkipToPrevious();
|
||||
MusicContainer.getInstance().playPrevious();
|
||||
updateNotification();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -196,7 +185,7 @@ public class MusicService extends MediaBrowserServiceCompat {
|
||||
|
||||
@Override
|
||||
public void onCompletion(MediaPlayer mp) {
|
||||
onSeekTo(mp.getCurrentPosition());
|
||||
seekToNotification(mp.getCurrentPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,14 @@ package com.yutou.nas_music_player.tools;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.yutou.nas_music_player.MyApplication;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class AppData {
|
||||
|
||||
public static String download_dir="downloads";
|
||||
public static String dir= MyApplication.application.getFilesDir() + File.separator;
|
||||
public static boolean isDebug=true;
|
||||
public static Handler handler=new Handler(Looper.getMainLooper());
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
package com.yutou.nas_music_player.tools;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
import com.kaopiz.kprogresshud.KProgressHUD;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class AppTools {
|
||||
|
||||
public static KProgressHUD showLoading(Context context){
|
||||
return KProgressHUD.create(context)
|
||||
.setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
|
||||
.setDetailsLabel("loading...")
|
||||
.setCancellable(true)
|
||||
.setAnimationSpeed(2)
|
||||
.setDimAmount(0.5f)
|
||||
.show();
|
||||
}
|
||||
public static void saveBitmap(final Bitmap bitmap, final String saveKey){
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String md5=getMD5(saveKey);
|
||||
File path=new File(AppData.dir+"img_cache"+File.separator);
|
||||
if(!path.exists()){
|
||||
path.mkdirs();
|
||||
}
|
||||
File image=new File(AppData.dir+"img_cache"+File.separator+md5);
|
||||
try {
|
||||
|
||||
if(!image.exists()){
|
||||
image.createNewFile();
|
||||
}
|
||||
FileOutputStream outputStream=new FileOutputStream(image);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG,100,outputStream);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
ConfigTools.getPreferences().edit().putString("img_"+md5,image.getAbsolutePath()).apply();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.out.println(image.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
public static Bitmap getSaveBitmap(String saveKey){
|
||||
String path=ConfigTools.getPreferences().getString(getMD5(saveKey),null);
|
||||
if(path==null){
|
||||
return null;
|
||||
}
|
||||
return BitmapFactory.decodeFile(path);
|
||||
}
|
||||
public static String getMD5(String data) {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
digest.update(data.getBytes());
|
||||
return bytesToHexString(digest.digest());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static String bytesToHexString(byte[] src) {
|
||||
StringBuilder stringBuilder = new StringBuilder("");
|
||||
if (src == null || src.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
for (byte aSrc : src) {
|
||||
int v = aSrc & 0xFF;
|
||||
String hv = Integer.toHexString(v);
|
||||
if (hv.length() < 2) {
|
||||
stringBuilder.append(0);
|
||||
}
|
||||
stringBuilder.append(hv);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
@ -47,7 +47,7 @@ public class NetworkTool {
|
||||
private static final String TAG = NetworkTool.class.getName();
|
||||
private static NetworkTool network;
|
||||
public boolean isNet = true;
|
||||
public static String donwloadPath = MyApplication.application.getFilesDir() + File.separator + AppData.download_dir + File.separator;
|
||||
public static String donwloadPath = AppData.dir + AppData.download_dir + File.separator;
|
||||
|
||||
private NetworkTool() {
|
||||
if (StringUtil.isEmpty(HOME)) {
|
||||
@ -101,6 +101,10 @@ public class NetworkTool {
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(url + "?" + toGetSplice(body)).openConnection();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
connection.connect();
|
||||
if(connection.getResponseCode()!=200){
|
||||
networkInterface.httpError(new RuntimeException("http code to :"+connection.getResponseCode()));
|
||||
return;
|
||||
}
|
||||
String tmp;
|
||||
StringBuilder str = new StringBuilder();
|
||||
while ((tmp = reader.readLine()) != null) {
|
||||
|
@ -1,17 +1,23 @@
|
||||
package com.yutou.nas_music_player.views;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
import androidx.core.util.Pair;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActivityOptions;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.media.MediaMetadataCompat;
|
||||
import android.support.v4.media.session.MediaControllerCompat;
|
||||
import android.support.v4.media.session.MediaSessionCompat;
|
||||
import android.support.v4.media.session.PlaybackStateCompat;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
@ -19,14 +25,18 @@ import android.widget.Toast;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.kaopiz.kprogresshud.KProgressHUD;
|
||||
import com.yutou.nas_music_player.R;
|
||||
import com.yutou.nas_music_player.containers.MediaBrowserHelper;
|
||||
import com.yutou.nas_music_player.containers.MusicContainer;
|
||||
import com.yutou.nas_music_player.containers.MusicData;
|
||||
import com.yutou.nas_music_player.Datas.MusicData;
|
||||
import com.yutou.nas_music_player.tools.AppData;
|
||||
import com.yutou.nas_music_player.tools.AppTools;
|
||||
import com.yutou.nas_music_player.tools.ConfigTools;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
@ -35,46 +45,94 @@ import jp.wasabeef.glide.transformations.BlurTransformation;
|
||||
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private ImageButton play, previous, next;
|
||||
private ImageButton play, previous, next, playModel;
|
||||
private MediaBrowserHelper browserHelper;
|
||||
private ImageView album_image, background_image;
|
||||
private MarqueeTextView title, album, artist;
|
||||
private TextView positionTime, durationTime, bitRate;
|
||||
private SeekBar seekBar;
|
||||
private Handler handler;
|
||||
private KProgressHUD hud;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
|
||||
super.onCreate(savedInstanceState);
|
||||
setBarColor(android.R.color.transparent);
|
||||
setContentView(R.layout.activity_main);
|
||||
handler = new Handler();
|
||||
initView();
|
||||
play.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (hud != null) {
|
||||
hud.dismiss();
|
||||
hud = null;
|
||||
}
|
||||
hud = AppTools.showLoading(MainActivity.this);
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
if (browserHelper.isPlayer()) {
|
||||
browserHelper.getTransportControls().pause();
|
||||
} else {
|
||||
browserHelper.getTransportControls().play();
|
||||
}
|
||||
if (hud != null && hud.isShowing()) {
|
||||
hud.dismiss();
|
||||
hud = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
next.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (hud != null) {
|
||||
hud.dismiss();
|
||||
hud = null;
|
||||
}
|
||||
hud = AppTools.showLoading(MainActivity.this);
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
browserHelper.getTransportControls().skipToNext();
|
||||
if (hud != null && hud.isShowing()) {
|
||||
hud.dismiss();
|
||||
hud = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
previous.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (hud != null) {
|
||||
hud.dismiss();
|
||||
hud = null;
|
||||
}
|
||||
hud = AppTools.showLoading(MainActivity.this);
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
browserHelper.getTransportControls().skipToPrevious();
|
||||
if (hud != null && hud.isShowing()) {
|
||||
hud.dismiss();
|
||||
hud = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (browserHelper.getTransportControls() != null)
|
||||
browserHelper.getTransportControls().seekTo(progress);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -84,11 +142,70 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
if (hud != null) {
|
||||
hud.dismiss();
|
||||
hud = null;
|
||||
}
|
||||
hud = AppTools.showLoading(MainActivity.this);
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (browserHelper.getTransportControls() != null)
|
||||
browserHelper.getTransportControls().seekTo(MainActivity.this.seekBar.getProgress());
|
||||
if (hud != null && hud.isShowing()) {
|
||||
hud.dismiss();
|
||||
hud = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
playModel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int model = (int) playModel.getTag();
|
||||
if (model == MusicContainer.PLAY_MODEL_LOOP) {
|
||||
setPlayModelButton(MusicContainer.PLAY_MODEL_RANDOM);
|
||||
return;
|
||||
}
|
||||
setPlayModelButton(model + 1);
|
||||
}
|
||||
});
|
||||
getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {
|
||||
float downPosition_x = 0, downPosition_y = 0;
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
downPosition_x = event.getRawX();
|
||||
downPosition_y = event.getRawY();
|
||||
} else if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
if (Math.abs(downPosition_x - event.getRawX()) < 500 && downPosition_y - event.getRawY() > 500) {
|
||||
Pair<View, String> pImage = Pair.create((View) album_image, "album_image");
|
||||
Pair<View, String> pPrevious = Pair.create((View) previous, "previous");
|
||||
Pair<View, String> pPlay = Pair.create((View) play, "play");
|
||||
Pair<View, String> pNext = Pair.create((View) next, "next");
|
||||
Pair<View, String> pTitle = Pair.create((View) title, "title");
|
||||
Pair<View, String> pArtist = Pair.create((View) artist, "artist");
|
||||
//ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this,list);
|
||||
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, pImage, pPrevious, pPlay, pNext, pTitle, pArtist).toBundle();
|
||||
|
||||
Intent intent = new Intent(
|
||||
MainActivity.this, PlayLibsActivity.class);
|
||||
if (bundle != null) {
|
||||
startActivity(intent, bundle);
|
||||
} else {
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
browserHelper = new MediaBrowserHelper(this);
|
||||
browserHelper.regPlayListener(new PlayListener());
|
||||
|
||||
initData();
|
||||
}
|
||||
|
||||
@ -119,11 +236,13 @@ public class MainActivity extends AppCompatActivity {
|
||||
artist.setText(data.getArtist());
|
||||
album.setText(data.getAlbum());
|
||||
bitRate.setText(data.getBitRate() + "kbps / " + data.getSampleRate() + "hz");
|
||||
seekBar.setMax((int) data.getDurationAsDouble());
|
||||
seekBar.setMax((int) (data.getDurationAsDouble() * 1000));
|
||||
int minutes = (int) (data.getDurationAsDouble() / 60);
|
||||
int seconds = (int) (data.getDurationAsDouble() % 60);
|
||||
durationTime.setText(minutes + ":" + seconds);
|
||||
|
||||
durationTime.setText(String.format(Locale.CHINA, "%02d", minutes) + ":"
|
||||
+ String.format(Locale.CHINA, "%02d", seconds));
|
||||
int model = ConfigTools.getPreferences().getInt("playModel", MusicContainer.PLAY_MODEL_RANDOM);
|
||||
setPlayModelButton(model);
|
||||
if (data.getImg() != null) {
|
||||
setImage(data);
|
||||
} else {
|
||||
@ -145,6 +264,26 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
}
|
||||
|
||||
private void setPlayModelButton(int model) {
|
||||
playModel.setTag(model);
|
||||
MusicContainer.getInstance().setPlayModel(model);
|
||||
switch (model) {
|
||||
case MusicContainer.PLAY_MODEL_RANDOM:
|
||||
playModel.setImageResource(R.drawable.ic_play_random);
|
||||
break;
|
||||
case MusicContainer.PLAY_MODEL_ORDER:
|
||||
playModel.setImageResource(R.drawable.ic_play_list);
|
||||
break;
|
||||
case MusicContainer.PLAY_MODEL_ONE_LOOP:
|
||||
playModel.setImageResource(R.drawable.ic_play_one_loop);
|
||||
break;
|
||||
case MusicContainer.PLAY_MODEL_LOOP:
|
||||
playModel.setImageResource(R.drawable.ic_play_loop);
|
||||
break;
|
||||
}
|
||||
ConfigTools.getPreferences().edit().putInt("playModel", model).apply();
|
||||
}
|
||||
|
||||
private void setImage(MusicData data) {
|
||||
album_image.setImageBitmap(data.getImg());
|
||||
background_image.setImageBitmap(data.getImg());
|
||||
@ -170,6 +309,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
positionTime = findViewById(R.id.positionTime);
|
||||
durationTime = findViewById(R.id.durationTime);
|
||||
seekBar = findViewById(R.id.seekBar);
|
||||
playModel = findViewById(R.id.playModel);
|
||||
}
|
||||
|
||||
public void setBarColor(int color) {
|
||||
@ -182,13 +322,14 @@ public class MainActivity extends AppCompatActivity {
|
||||
@Override
|
||||
public void onPlaybackStateChanged(PlaybackStateCompat state) {
|
||||
super.onPlaybackStateChanged(state);
|
||||
System.out.println("播放状态变化:" + state.getState());
|
||||
System.out.println("播放状态变化:" + state.getPosition() + " " + seekBar.getMax());
|
||||
if (state.getState() == PlaybackStateCompat.STATE_PLAYING) {
|
||||
int duration = (int) (state.getPosition() / 1000);
|
||||
int minutes = duration / 60;
|
||||
int seconds = duration % 60;
|
||||
positionTime.setText(minutes + ":" + seconds);
|
||||
seekBar.setProgress((int) (state.getPosition() / 1000));
|
||||
positionTime.setText(String.format(Locale.CHINA, "%02d", minutes) + ":"
|
||||
+ String.format(Locale.CHINA, "%02d", seconds));
|
||||
seekBar.setProgress((int) (state.getPosition()));
|
||||
play.setImageResource(android.R.drawable.ic_media_pause);
|
||||
} else {
|
||||
play.setImageResource(android.R.drawable.ic_media_play);
|
||||
@ -203,12 +344,11 @@ public class MainActivity extends AppCompatActivity {
|
||||
try {
|
||||
System.out.println("播放歌曲变换:" + metadata.getString("md5"));
|
||||
md5 = metadata.getString("md5");
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
if (md5 != null) {
|
||||
setPlayData(MusicContainer.getLibs().findMusic(md5));
|
||||
setPlayData(MusicContainer.getLibs().findMusic(md5, MusicContainer.getInstance().getPlayList()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class OpenActivity extends AppCompatActivity {
|
||||
public void init() {
|
||||
Intent intent=new Intent(OpenActivity.this,MainActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
OpenActivity.this.finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,145 @@
|
||||
package com.yutou.nas_music_player.views;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.media.MediaMetadataCompat;
|
||||
import android.support.v4.media.session.MediaControllerCompat;
|
||||
import android.support.v4.media.session.MediaSessionCompat;
|
||||
import android.support.v4.media.session.PlaybackStateCompat;
|
||||
import android.view.Window;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.yutou.nas_music_player.Datas.MusicData;
|
||||
import com.yutou.nas_music_player.R;
|
||||
import com.yutou.nas_music_player.containers.MediaBrowserHelper;
|
||||
import com.yutou.nas_music_player.containers.MusicContainer;
|
||||
import com.yutou.nas_music_player.tools.AppData;
|
||||
import com.yutou.nas_music_player.tools.ConfigTools;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import cc.ibooker.ztextviewlib.MarqueeTextView;
|
||||
import jp.wasabeef.glide.transformations.BlurTransformation;
|
||||
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
|
||||
|
||||
public class PlayLibsActivity extends AppCompatActivity {
|
||||
private ImageButton play, previous, next;
|
||||
private MediaBrowserHelper browserHelper;
|
||||
private ImageView album_image;
|
||||
private MarqueeTextView title, artist;
|
||||
private PlayListener playListener;
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_play_list);
|
||||
initView();
|
||||
setPlayData(MusicContainer.getInstance().getNowPlayData());
|
||||
browserHelper = new MediaBrowserHelper(this);
|
||||
playListener=new PlayListener();
|
||||
browserHelper.regPlayListener(playListener);
|
||||
}
|
||||
private void initView() {
|
||||
play = findViewById(R.id.play);
|
||||
next = findViewById(R.id.next);
|
||||
previous = findViewById(R.id.previous);
|
||||
album_image = findViewById(R.id.album_image);
|
||||
title = findViewById(R.id.title);
|
||||
artist = findViewById(R.id.artist);
|
||||
}
|
||||
private void setImage(MusicData data) {
|
||||
album_image.setImageBitmap(data.getImg());
|
||||
Glide.with(this).load(data.getImg())
|
||||
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
|
||||
.into(album_image);
|
||||
}
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void setPlayData(final MusicData data) {
|
||||
System.out.println("设置歌曲");
|
||||
System.out.println(data);
|
||||
if (data == null)
|
||||
return;
|
||||
title.setText(data.getTitle());
|
||||
artist.setText(data.getArtist());
|
||||
if (data.getImg() != null) {
|
||||
setImage(data);
|
||||
} else {
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (data.getImg() != null) {
|
||||
AppData.handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setImage(data);
|
||||
}
|
||||
});
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
}, 0, 100);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
browserHelper=null;
|
||||
finish();
|
||||
}
|
||||
|
||||
private class PlayListener extends MediaControllerCompat.Callback {
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onPlaybackStateChanged(PlaybackStateCompat state) {
|
||||
super.onPlaybackStateChanged(state);
|
||||
if (state.getState() == PlaybackStateCompat.STATE_PLAYING) {
|
||||
play.setImageResource(android.R.drawable.ic_media_pause);
|
||||
} else {
|
||||
play.setImageResource(android.R.drawable.ic_media_play);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMetadataChanged(MediaMetadataCompat metadata) {
|
||||
super.onMetadataChanged(metadata);
|
||||
String md5 = null;
|
||||
try {
|
||||
System.out.println("播放歌曲变换:" + metadata.getString("md5"));
|
||||
md5 = metadata.getString("md5");
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
if (md5 != null) {
|
||||
setPlayData(MusicContainer.getLibs().findMusic(md5, MusicContainer.getInstance().getPlayList()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionDestroyed() {
|
||||
super.onSessionDestroyed();
|
||||
System.out.println("连接被销毁");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged(List<MediaSessionCompat.QueueItem> queue) {
|
||||
super.onQueueChanged(queue);
|
||||
System.out.println("不知道是啥变换了");
|
||||
}
|
||||
|
||||
public void setImage() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
BIN
app/src/main/res/drawable/ic_play_list.png
Normal file
BIN
app/src/main/res/drawable/ic_play_list.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 785 B |
BIN
app/src/main/res/drawable/ic_play_loop.png
Normal file
BIN
app/src/main/res/drawable/ic_play_loop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 962 B |
BIN
app/src/main/res/drawable/ic_play_one_loop.png
Normal file
BIN
app/src/main/res/drawable/ic_play_one_loop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable/ic_play_random.png
Normal file
BIN
app/src/main/res/drawable/ic_play_random.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
@ -34,6 +34,7 @@
|
||||
android:layout_marginTop="150dp"
|
||||
android:contentDescription="专辑图"
|
||||
android:src="@drawable/ic_launcher_foreground"
|
||||
android:transitionName="album_image"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@ -43,13 +44,14 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="26dp"
|
||||
android:shadowColor="@color/textColorGray"
|
||||
android:shadowColor="@color/colorBlack"
|
||||
android:shadowDx="5"
|
||||
android:shadowDy="5"
|
||||
android:shadowRadius="1"
|
||||
android:text="title"
|
||||
android:textColor="@color/musicTitle"
|
||||
android:textSize="24sp"
|
||||
android:transitionName="title"
|
||||
app:layout_constraintBottom_toTopOf="@+id/album_image"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
@ -76,6 +78,10 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_weight="1"
|
||||
android:shadowColor="@color/colorBlack"
|
||||
android:shadowDx="5"
|
||||
android:shadowDy="5"
|
||||
android:shadowRadius="1"
|
||||
android:text="00:00"
|
||||
android:textColor="@color/textColorWhite" />
|
||||
|
||||
@ -85,8 +91,12 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/textColorWhite"
|
||||
android:text="TextView" />
|
||||
android:shadowColor="@color/colorBlack"
|
||||
android:shadowDx="5"
|
||||
android:shadowDy="5"
|
||||
android:shadowRadius="1"
|
||||
android:text="TextView"
|
||||
android:textColor="@color/textColorWhite" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/durationTime"
|
||||
@ -95,6 +105,10 @@
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="end"
|
||||
android:shadowColor="@color/colorBlack"
|
||||
android:shadowDx="5"
|
||||
android:shadowDy="5"
|
||||
android:shadowRadius="1"
|
||||
android:text="00:00"
|
||||
android:textColor="@color/textColorGray" />
|
||||
</LinearLayout>
|
||||
@ -125,20 +139,30 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/playModel"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:scaleType="fitCenter"
|
||||
app:srcCompat="@drawable/ic_play_random" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/previous"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:src="@android:drawable/ic_media_previous" />
|
||||
android:src="@android:drawable/ic_media_previous"
|
||||
android:transitionName="previous" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/play"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:src="@android:drawable/ic_media_play" />
|
||||
android:src="@android:drawable/ic_media_play"
|
||||
android:transitionName="play" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/next"
|
||||
@ -146,7 +170,9 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="30dp"
|
||||
android:src="@android:drawable/ic_media_next" />
|
||||
android:layout_marginEnd="80dp"
|
||||
android:src="@android:drawable/ic_media_next"
|
||||
android:transitionName="next" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@ -163,6 +189,9 @@
|
||||
android:id="@+id/album"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:shadowColor="@color/colorBlack"
|
||||
android:shadowDx="5"
|
||||
android:shadowDy="5"
|
||||
android:shadowRadius="1"
|
||||
android:text="album"
|
||||
android:textColor="@color/textColorWhite"
|
||||
@ -172,9 +201,14 @@
|
||||
android:id="@+id/artist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:shadowColor="@color/colorBlack"
|
||||
android:shadowDx="5"
|
||||
android:shadowDy="5"
|
||||
android:shadowRadius="1"
|
||||
android:text="artist"
|
||||
android:textColor="@color/textColorWhite"
|
||||
android:textSize="20sp" />
|
||||
android:textSize="20sp"
|
||||
android:transitionName="artist" />
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
59
app/src/main/res/layout/activity_play_list.xml
Normal file
59
app/src/main/res/layout/activity_play_list.xml
Normal file
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
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="match_parent">
|
||||
|
||||
<include
|
||||
android:id="@+id/include"
|
||||
layout="@layout/layout_play"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.ogaclejapan.smarttablayout.SmartTabLayout
|
||||
android:id="@+id/viewpagertab"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/include"
|
||||
app:stl_clickable="true"
|
||||
app:stl_defaultTabBackground="?attr/selectableItemBackground"
|
||||
app:stl_defaultTabTextAllCaps="true"
|
||||
app:stl_defaultTabTextColor="#FC000000"
|
||||
app:stl_defaultTabTextHorizontalPadding="16dp"
|
||||
app:stl_defaultTabTextMinWidth="0dp"
|
||||
app:stl_defaultTabTextSize="12sp"
|
||||
app:stl_distributeEvenly="false"
|
||||
app:stl_dividerColor="#4D000000"
|
||||
app:stl_dividerThickness="1dp"
|
||||
app:stl_drawDecorationAfterTab="false"
|
||||
app:stl_indicatorAlwaysInCenter="false"
|
||||
app:stl_indicatorColor="#40C4FF"
|
||||
app:stl_indicatorCornerRadius="2dp"
|
||||
app:stl_indicatorGravity="bottom"
|
||||
app:stl_indicatorInFront="false"
|
||||
app:stl_indicatorInterpolation="smart"
|
||||
app:stl_indicatorThickness="4dp"
|
||||
app:stl_indicatorWidth="auto"
|
||||
app:stl_indicatorWithoutPadding="false"
|
||||
app:stl_overlineColor="#4D000000"
|
||||
app:stl_overlineThickness="0dp"
|
||||
app:stl_titleOffset="24dp"
|
||||
app:stl_underlineColor="#4D000000"
|
||||
app:stl_underlineThickness="1dp" />
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/viewpager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_below="@id/viewpagertab"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/viewpagertab" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
91
app/src/main/res/layout/layout_play.xml
Normal file
91
app/src/main/res/layout/layout_play.xml
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/album_image"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:transitionName="album_image"
|
||||
app:srcCompat="@mipmap/ic_launcher" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<cc.ibooker.ztextviewlib.MarqueeTextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:shadowColor="@color/textColorGray"
|
||||
android:shadowDx="5"
|
||||
android:shadowDy="5"
|
||||
android:shadowRadius="1"
|
||||
android:text="TextView"
|
||||
android:textColor="@color/colorBlack"
|
||||
android:transitionName="title" />
|
||||
|
||||
<cc.ibooker.ztextviewlib.MarqueeTextView
|
||||
android:id="@+id/artist"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:shadowColor="@color/textColorGray"
|
||||
android:shadowDx="5"
|
||||
android:shadowDy="5"
|
||||
android:shadowRadius="1"
|
||||
android:text="TextView"
|
||||
android:textColor="@color/colorBlack"
|
||||
android:transitionName="artist" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="end"
|
||||
android:gravity="end"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/previous"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="fitCenter"
|
||||
android:transitionName="previous"
|
||||
app:srcCompat="@android:drawable/ic_media_previous" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/play"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="fitCenter"
|
||||
android:transitionName="play"
|
||||
app:srcCompat="@android:drawable/ic_media_play" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/next"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:transitionName="next"
|
||||
app:srcCompat="@android:drawable/ic_media_next" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -5,7 +5,7 @@
|
||||
<color name="colorAccent">#03DAC5</color>
|
||||
<color name="colorBlack">#000000</color>
|
||||
|
||||
<color name="musicTitle">#000000</color>
|
||||
<color name="musicTitle">#FFFFFF</color>
|
||||
<color name="musicArtist">#000000</color>
|
||||
<color name="textColorGray">#DEDEDE</color>
|
||||
<color name="textColorWhite">#FFFFFF</color>
|
||||
|
Loading…
Reference in New Issue
Block a user