@ -1,29 +1,113 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<Objective-C-extensions>
|
||||
<file>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||
</file>
|
||||
<class>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||
</class>
|
||||
<extensions>
|
||||
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
||||
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||
</extensions>
|
||||
</Objective-C-extensions>
|
||||
<codeStyleSettings language="XML">
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
@ -1,15 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<litepal>
|
||||
<dbname value="SongList"></dbname>
|
||||
<dbname value="SongList" />
|
||||
|
||||
<version value="15"></version>
|
||||
<version value="27" />
|
||||
|
||||
<list>
|
||||
<mapping class="com.example.musicplayer.entiy.OnlineSong"></mapping>
|
||||
<mapping class="com.example.musicplayer.entiy.LocalSong"></mapping>
|
||||
<mapping class="com.example.musicplayer.entiy.SearchHistory"></mapping>
|
||||
<mapping class="com.example.musicplayer.entiy.Love"></mapping>
|
||||
<mapping class="com.example.musicplayer.entiy.HistorySong"></mapping>
|
||||
<mapping class="com.example.musicplayer.entiy.AlbumCollection"></mapping>
|
||||
<mapping class="com.example.musicplayer.entiy.OnlineSong" />
|
||||
<mapping class="com.example.musicplayer.entiy.LocalSong" />
|
||||
<mapping class="com.example.musicplayer.entiy.SearchHistory" />
|
||||
<mapping class="com.example.musicplayer.entiy.Love" />
|
||||
<mapping class="com.example.musicplayer.entiy.HistorySong" />
|
||||
<mapping class="com.example.musicplayer.entiy.AlbumCollection" />
|
||||
<mapping class="com.example.musicplayer.entiy.DownloadSong" />
|
||||
<mapping class="com.example.musicplayer.entiy.DownloadInfo"/>
|
||||
<mapping class="com.example.musicplayer.entiy.Song"/>
|
||||
</list>
|
||||
</litepal>
|
||||
@ -0,0 +1,143 @@
|
||||
package com.example.musicplayer.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.andexert.library.RippleView;
|
||||
import com.example.musicplayer.R;
|
||||
import com.example.musicplayer.callback.OnItemClickListener;
|
||||
import com.example.musicplayer.entiy.DownloadSong;
|
||||
import com.example.musicplayer.util.FileUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/09/18
|
||||
* desc : 已下载歌曲的适配器
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DownloadSongAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private static final String TAG = "LoveSongAdapter";
|
||||
private int footerViewType = 1;
|
||||
private int itemViewType = 0;
|
||||
private List<DownloadSong> mDownloadSongList;
|
||||
private Context mContext;
|
||||
private int mLastPosition = -1;
|
||||
private OnItemClickListener onItemClickListener;
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
|
||||
this.onItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
public DownloadSongAdapter(Context context, List<DownloadSong> loveList) {
|
||||
mContext = context;
|
||||
mDownloadSongList = loveList;
|
||||
}
|
||||
|
||||
|
||||
class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView songNameTv;
|
||||
TextView singerTv;
|
||||
View playLine;
|
||||
RippleView item;
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
songNameTv = itemView.findViewById(R.id.tv_title);
|
||||
singerTv = itemView.findViewById(R.id.tv_artist);
|
||||
playLine = itemView.findViewById(R.id.line_play);
|
||||
item = itemView.findViewById(R.id.ripple);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 底部holder
|
||||
*/
|
||||
static class FooterHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
TextView numTv;
|
||||
|
||||
public FooterHolder(View itemView) {
|
||||
super(itemView);
|
||||
numTv = itemView.findViewById(R.id.tv_song_num);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
if (viewType == itemViewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.recycler_song_search_item, parent, false);
|
||||
ViewHolder viewHolder = new ViewHolder(view);
|
||||
return viewHolder;
|
||||
} else {
|
||||
View footerView = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.footer_local_songs_item, parent, false);
|
||||
FooterHolder footerHolder = new FooterHolder(footerView);
|
||||
return footerHolder;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||
if (viewHolder instanceof ViewHolder) {
|
||||
ViewHolder holder = (ViewHolder) viewHolder;
|
||||
final DownloadSong downloadSong = mDownloadSongList.get(position);
|
||||
|
||||
holder.songNameTv.setText(downloadSong.getName());
|
||||
holder.singerTv.setText(downloadSong.getSinger());
|
||||
//根据点击显示
|
||||
if (downloadSong.getSongId().equals(FileUtil.getSong().getSongId())) {
|
||||
holder.playLine.setVisibility(View.VISIBLE);
|
||||
mLastPosition = position;
|
||||
holder.songNameTv.setTextColor(mContext.getResources()
|
||||
.getColor(R.color.yellow));
|
||||
holder.singerTv.setTextColor(mContext.getResources()
|
||||
.getColor(R.color.yellow));
|
||||
} else {
|
||||
holder.playLine.setVisibility(View.INVISIBLE);
|
||||
holder.songNameTv.setTextColor(mContext.getResources()
|
||||
.getColor(R.color.white));
|
||||
holder.singerTv.setTextColor(mContext.getResources()
|
||||
.getColor(R.color.white_blue));
|
||||
}
|
||||
holder.item.setOnRippleCompleteListener(rippleView -> {
|
||||
if (onItemClickListener != null) {
|
||||
onItemClickListener.onClick(position);
|
||||
}
|
||||
equalPosition(position);
|
||||
});
|
||||
} else {
|
||||
FooterHolder footerHolder = (FooterHolder) viewHolder;
|
||||
footerHolder.numTv.setText("共" + mDownloadSongList.size() + "首音乐");
|
||||
}
|
||||
}
|
||||
|
||||
//判断点击的是否为上一个点击的项目
|
||||
public void equalPosition(int position) {
|
||||
if (position != mLastPosition) {
|
||||
notifyItemChanged(mLastPosition);
|
||||
mLastPosition = position;
|
||||
}
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mDownloadSongList.size() + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return position + 1 == getItemCount() ? footerViewType : itemViewType;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.example.musicplayer.download;
|
||||
|
||||
import com.example.musicplayer.entiy.DownloadInfo;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/04/08
|
||||
* desc : 监听下载过程中的各种状态
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public interface DownloadListener {
|
||||
void onProgress(DownloadInfo downloadInfo); //进度
|
||||
void onSuccess(); //成功
|
||||
void onDownloaded();//已经下载过的歌曲
|
||||
void onFailed(); //失败
|
||||
void onPaused(); //暂停
|
||||
void onCanceled(); //取消
|
||||
}
|
||||
@ -0,0 +1,177 @@
|
||||
package com.example.musicplayer.download;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
|
||||
import com.example.musicplayer.app.Api;
|
||||
import com.example.musicplayer.entiy.DownloadInfo;
|
||||
import com.example.musicplayer.util.DownloadUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
import static com.example.musicplayer.app.Constant.*;
|
||||
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/04/08
|
||||
* desc :
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DownloadTask extends AsyncTask<DownloadInfo, DownloadInfo, Integer> {
|
||||
|
||||
private DownloadListener mDownListener;
|
||||
private boolean isCanceled = false;
|
||||
private boolean isPaused = false;
|
||||
private long lastProgress;
|
||||
|
||||
public DownloadTask(DownloadListener downloadListener) {
|
||||
mDownListener = downloadListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground(DownloadInfo... downloadInfos) {
|
||||
InputStream is = null;
|
||||
RandomAccessFile saveFile = null;
|
||||
File file = null;
|
||||
DownloadInfo downloadInfo = downloadInfos[0];
|
||||
try {
|
||||
long downloadedLength = 0; //记录已下载的文件长度
|
||||
String downloadUrl = downloadInfo.getUrl();
|
||||
|
||||
|
||||
File downloadFile = new File(Api.STORAGE_SONG_FILE);
|
||||
if (!downloadFile.exists()) {
|
||||
downloadFile.mkdirs();
|
||||
}
|
||||
//传过来的下载地址
|
||||
// http://ws.stream.qqmusic.qq.com/C400001DI2Jj3Jqve9.m4a?guid=358840384&vkey=2B9BF114492F203C3943D8AE38C83DD8FEEA5E628B18F7F4455CA9B5059040266D74EBD43E09627AA4419D379B6A9E1FC1E5D2104AC7BB50&uin=0&fromtag=66
|
||||
long contentLength = getContentLength(downloadUrl); //实际文件长度
|
||||
String fileName = DownloadUtil.getSaveSongFile(downloadInfo.getSinger(),downloadInfo.getSongName(),downloadInfo.getDuration(),downloadInfo.getSongId(),contentLength);
|
||||
file = new File(downloadFile ,fileName);
|
||||
if (file.exists()) {
|
||||
downloadedLength = file.length();
|
||||
}
|
||||
if (contentLength == 0) {
|
||||
return TYPE_DOWNLOAD_FAILED;
|
||||
} else if (contentLength == downloadedLength) { //已下载
|
||||
return TYPE_DOWNLOADED;
|
||||
}
|
||||
|
||||
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
Request request = new Request.Builder()
|
||||
//断点下载,指定从哪个字节开始下载
|
||||
.addHeader("RANGE", "bytes=" + downloadedLength + "-")
|
||||
.url(downloadUrl)
|
||||
.build();
|
||||
Response response = client.newCall(request).execute();
|
||||
|
||||
if (response != null) {
|
||||
is = response.body().byteStream();
|
||||
saveFile = new RandomAccessFile(file, "rw");
|
||||
saveFile.seek(downloadedLength); //跳过已下载的字节
|
||||
byte[] b = new byte[1024];
|
||||
int total = 0;
|
||||
int len;
|
||||
while ((len = is.read(b)) != -1) {
|
||||
if (isCanceled) {
|
||||
return TYPE_DOWNLOAD_CANCELED;
|
||||
} else if (isPaused) {
|
||||
return TYPE_DOWNLOAD_PAUSED;
|
||||
} else {
|
||||
total += len;
|
||||
saveFile.write(b, 0, len);
|
||||
int progress = (int) ((total + downloadedLength) * 100 / contentLength);
|
||||
downloadInfo.setProgress(progress);
|
||||
downloadInfo.setTotalSize(contentLength);
|
||||
downloadInfo.setCurrentSize(total+downloadedLength);
|
||||
publishProgress(downloadInfo);
|
||||
}
|
||||
}
|
||||
response.body().close();
|
||||
return TYPE_DOWNLOAD_SUCCESS;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
if (saveFile != null) {
|
||||
saveFile.close();
|
||||
}
|
||||
if (isCanceled && file != null) {
|
||||
file.delete();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return TYPE_DOWNLOAD_FAILED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressUpdate(DownloadInfo... downloadInfos) {
|
||||
DownloadInfo downloadInfo = downloadInfos[0];
|
||||
int progress = downloadInfo.getProgress();
|
||||
if (progress > lastProgress) {
|
||||
mDownListener.onProgress(downloadInfo);
|
||||
lastProgress = progress;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Integer status) {
|
||||
switch (status) {
|
||||
case TYPE_DOWNLOAD_SUCCESS:
|
||||
mDownListener.onSuccess();
|
||||
break;
|
||||
case TYPE_DOWNLOAD_FAILED:
|
||||
mDownListener.onFailed();
|
||||
break;
|
||||
case TYPE_DOWNLOAD_PAUSED:
|
||||
mDownListener.onPaused();
|
||||
break;
|
||||
case TYPE_DOWNLOAD_CANCELED:
|
||||
mDownListener.onCanceled();
|
||||
break;
|
||||
case TYPE_DOWNLOADED:
|
||||
mDownListener.onDownloaded();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void pauseDownload() {
|
||||
isPaused = true;
|
||||
}
|
||||
|
||||
public void cancelDownload() {
|
||||
isCanceled = true;
|
||||
}
|
||||
|
||||
private long getContentLength(String downloadUrl) throws IOException {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
Request request = new Request.Builder()
|
||||
.url(downloadUrl)
|
||||
.build();
|
||||
Response response = client.newCall(request).execute();
|
||||
if (response != null && response.isSuccessful()) {
|
||||
long contentLength = response.body().contentLength();
|
||||
response.body().close();
|
||||
return contentLength;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
package com.example.musicplayer.entiy;
|
||||
|
||||
import org.litepal.crud.LitePalSupport;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/09/17
|
||||
* desc : 下载的信息
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DownloadInfo extends LitePalSupport {
|
||||
private long id;
|
||||
private String songName;
|
||||
private String singer;
|
||||
private String url;
|
||||
private String songId;
|
||||
private int progress;
|
||||
private long currentSize;
|
||||
private long totalSize;
|
||||
// private Song song;
|
||||
private long duration;
|
||||
private int position;//正在下载歌曲列表中的位置
|
||||
private int status;//下载歌曲的状态
|
||||
|
||||
public String getSongName() {
|
||||
return songName;
|
||||
}
|
||||
|
||||
public void setSongName(String songName) {
|
||||
this.songName = songName;
|
||||
}
|
||||
|
||||
public String getSinger() {
|
||||
return singer;
|
||||
}
|
||||
|
||||
public void setSinger(String singer) {
|
||||
this.singer = singer;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getSongId() {
|
||||
return songId;
|
||||
}
|
||||
|
||||
public void setSongId(String songId) {
|
||||
this.songId = songId;
|
||||
}
|
||||
|
||||
public int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void setProgress(int progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
public long getCurrentSize() {
|
||||
return currentSize;
|
||||
}
|
||||
|
||||
public void setCurrentSize(long currentSize) {
|
||||
this.currentSize = currentSize;
|
||||
}
|
||||
|
||||
public long getTotalSize() {
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
public void setTotalSize(long totalSize) {
|
||||
this.totalSize = totalSize;
|
||||
}
|
||||
|
||||
// public Song getSong() {
|
||||
// return song;
|
||||
// }
|
||||
//
|
||||
// public void setSong(Song song) {
|
||||
// this.song = song;
|
||||
// }
|
||||
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(long duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
package com.example.musicplayer.entiy;
|
||||
|
||||
import org.litepal.crud.LitePalSupport;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/09/18
|
||||
* desc : 下载的歌曲
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DownloadSong extends LitePalSupport {
|
||||
private int id;
|
||||
private String songId ;
|
||||
private String mediaId; //下载标识符
|
||||
private String name;
|
||||
private String singer;
|
||||
private String url;
|
||||
private String pic;
|
||||
private long duration;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSinger() {
|
||||
return singer;
|
||||
}
|
||||
|
||||
public void setSinger(String singer) {
|
||||
this.singer = singer;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getPic() {
|
||||
return pic;
|
||||
}
|
||||
|
||||
public void setPic(String pic) {
|
||||
this.pic = pic;
|
||||
}
|
||||
|
||||
|
||||
public void setDuration(long duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setSongId(String songId) {
|
||||
this.songId = songId;
|
||||
}
|
||||
|
||||
public String getSongId() {
|
||||
return songId;
|
||||
}
|
||||
|
||||
public String getMediaId() {
|
||||
return mediaId;
|
||||
}
|
||||
|
||||
public void setMediaId(String mediaId) {
|
||||
this.mediaId = mediaId;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.example.musicplayer.event;
|
||||
|
||||
import com.example.musicplayer.entiy.DownloadInfo;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/09/16
|
||||
* desc :
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DownloadEvent {
|
||||
private int downloadStatus;//下载的状态
|
||||
private DownloadInfo downloadInfo;
|
||||
private int position;
|
||||
|
||||
|
||||
public DownloadEvent(int status){
|
||||
downloadStatus = status;
|
||||
}
|
||||
public DownloadEvent(int status, DownloadInfo downloadInfo){
|
||||
downloadStatus = status;
|
||||
this.downloadInfo = downloadInfo;
|
||||
}
|
||||
|
||||
public DownloadEvent(int status,int position){
|
||||
downloadStatus = status;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
|
||||
public int getDownloadStatus() {
|
||||
return downloadStatus;
|
||||
}
|
||||
|
||||
public DownloadInfo getDownloadInfo() {
|
||||
return downloadInfo;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.example.musicplayer.event;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/09/18
|
||||
* desc : 已下载歌曲改变的消息
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class SongDownloadedEvent {
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.example.musicplayer.event;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/09/20
|
||||
* desc : 歌曲列表数量变化消息
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class SongListNumEvent {
|
||||
private int type;
|
||||
public SongListNumEvent(int type){
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package com.example.musicplayer.util;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.example.musicplayer.app.Api;
|
||||
import com.example.musicplayer.entiy.DownloadSong;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.example.musicplayer.app.Api.STORAGE_SONG_FILE;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/09/24
|
||||
* desc : 下载相关工具
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DownloadUtil {
|
||||
/**
|
||||
*
|
||||
* @param fileName 文件跟目录
|
||||
* @return 得到已下载的歌曲
|
||||
*/
|
||||
public static final List<DownloadSong> getSongFromFile(String fileName){
|
||||
//将.m4a截取掉得到singer-songName-duration-songId-size
|
||||
List<DownloadSong> res = new ArrayList<>();
|
||||
File file=new File(fileName);
|
||||
if(!file.exists()){
|
||||
file.mkdirs();
|
||||
return res;
|
||||
}
|
||||
File[] subFile = file.listFiles();
|
||||
for (File value : subFile) {
|
||||
String songFileName = value.getName();
|
||||
String songFile = songFileName.substring(0, songFileName.lastIndexOf("."));
|
||||
String[] songValue = songFile.split("-");
|
||||
long size = Long.valueOf(songValue[4]);
|
||||
//如果文件的大小不等于实际大小,则表示该歌曲还未下载完成,被人为暂停,故跳过该歌曲,不加入到已下载集合
|
||||
if(size != value.length()) continue;
|
||||
DownloadSong downloadSong = new DownloadSong();
|
||||
downloadSong.setSinger(songValue[0]);
|
||||
downloadSong.setName(songValue[1]);
|
||||
downloadSong.setDuration(Long.valueOf(songValue[2]));
|
||||
downloadSong.setSongId(songValue[3]);
|
||||
downloadSong.setUrl(fileName + songFileName);
|
||||
res.add(downloadSong);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static final boolean isExistOfDownloadSong(String songId){
|
||||
//将.m4a截取掉得到singer-songName-duration-songId-size
|
||||
File file=new File(STORAGE_SONG_FILE);
|
||||
if(!file.exists()){
|
||||
file.mkdirs();
|
||||
return false;
|
||||
}
|
||||
File[] subFile = file.listFiles();
|
||||
for (File value : subFile) {
|
||||
String songFileName = value.getName();
|
||||
String songFile = songFileName.substring(0, songFileName.lastIndexOf("."));
|
||||
String[] songValue = songFile.split("-");
|
||||
//如果文件的大小不等于实际大小,则表示该歌曲还未下载完成,被人为暂停,故跳过该歌曲,不加入到已下载集合
|
||||
if(songValue[3].equals(songId)) {
|
||||
long size = Long.valueOf(songValue[4]);
|
||||
return size == value.length();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//组装下载歌曲的文件名
|
||||
public static final String getSaveSongFile(String singer,String songName,long duration,String songId,long size){
|
||||
return singer+"-"+songName+"-"+duration+"-"+songId+"-"+size+".m4a";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package com.example.musicplayer.view.main.download;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.example.musicplayer.R;
|
||||
import com.example.musicplayer.adapter.TabAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/09/16
|
||||
* desc : 下载模块
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DownloadFragment extends Fragment {
|
||||
@BindView(R.id.backIv)
|
||||
ImageView backIv;
|
||||
@BindView(R.id.tabLayout)
|
||||
TabLayout tabLayout;
|
||||
@BindView(R.id.page)
|
||||
ViewPager page;
|
||||
private Unbinder unbinder;
|
||||
private List<String> mTitleList;
|
||||
private List<Fragment> mFragments;
|
||||
private TabAdapter mAdapter;
|
||||
private String[] mTitles = {"已下载", "正在下载"};
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_download, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
initTab();
|
||||
onClick();
|
||||
return view;
|
||||
|
||||
}
|
||||
|
||||
private void initTab() {
|
||||
mTitleList = new ArrayList<>();
|
||||
mFragments = new ArrayList<>();
|
||||
mTitleList.addAll(Arrays.asList(mTitles));
|
||||
mFragments.add(new DownloadMusicFragment());
|
||||
mFragments.add(new DownloadingFragment());
|
||||
mAdapter = new TabAdapter(getChildFragmentManager(), mFragments, mTitleList);
|
||||
page.setAdapter(mAdapter);
|
||||
tabLayout.setupWithViewPager(page);
|
||||
}
|
||||
private void onClick(){
|
||||
backIv.setOnClickListener(view -> Objects.requireNonNull(getActivity()).getSupportFragmentManager().popBackStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,151 @@
|
||||
package com.example.musicplayer.view.main.download;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.example.musicplayer.R;
|
||||
import com.example.musicplayer.adapter.DownloadSongAdapter;
|
||||
import com.example.musicplayer.app.Constant;
|
||||
import com.example.musicplayer.entiy.DownloadSong;
|
||||
import com.example.musicplayer.entiy.Song;
|
||||
import com.example.musicplayer.event.DownloadEvent;
|
||||
import com.example.musicplayer.event.SongDownloadedEvent;
|
||||
import com.example.musicplayer.service.PlayerService;
|
||||
import com.example.musicplayer.util.DownloadUtil;
|
||||
import com.example.musicplayer.util.FileUtil;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
||||
import static com.example.musicplayer.app.Api.STORAGE_SONG_FILE;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/09/16
|
||||
* desc : 下载歌曲列表
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DownloadMusicFragment extends Fragment {
|
||||
private static final String TAG = "DownloadMusicFragment";
|
||||
|
||||
@BindView(R.id.songRecycle)
|
||||
RecyclerView songRecycle;
|
||||
Unbinder unbinder;
|
||||
|
||||
private LinearLayoutManager mManager;
|
||||
private DownloadSongAdapter mAdapter;
|
||||
private List<DownloadSong> mDownloadSongList; //已下载歌曲列表
|
||||
|
||||
private PlayerService.PlayStatusBinder mPlayStatusBinder;
|
||||
private ServiceConnection connection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
mPlayStatusBinder = (PlayerService.PlayStatusBinder) service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_download_music, container, false);
|
||||
EventBus.getDefault().register(this);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
mDownloadSongList = new ArrayList<>();
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
//启动服务
|
||||
Intent playIntent = new Intent(getActivity(), PlayerService.class);
|
||||
Objects.requireNonNull(getActivity()).bindService(playIntent, connection, Context.BIND_AUTO_CREATE);
|
||||
showSongList();
|
||||
}
|
||||
|
||||
private void showSongList(){
|
||||
mDownloadSongList = orderList(DownloadUtil.getSongFromFile(STORAGE_SONG_FILE));
|
||||
mAdapter = new DownloadSongAdapter(getActivity(), mDownloadSongList);
|
||||
mManager = new LinearLayoutManager(getActivity());
|
||||
songRecycle.setLayoutManager(mManager);
|
||||
songRecycle.setAdapter(mAdapter);
|
||||
|
||||
mAdapter.setOnItemClickListener(position -> {
|
||||
DownloadSong downloadSong = mDownloadSongList.get(position);
|
||||
Song song = new Song();
|
||||
song.setSongId(downloadSong.getSongId());
|
||||
song.setSongName(downloadSong.getName());
|
||||
song.setSinger(downloadSong.getSinger());
|
||||
song.setOnline(false);
|
||||
song.setUrl(downloadSong.getUrl());
|
||||
Log.d(TAG, "showSongList: "+song.getUrl());
|
||||
song.setImgUrl(downloadSong.getPic());
|
||||
song.setPosition(position);
|
||||
song.setDuration(downloadSong.getDuration());
|
||||
song.setListType(Constant.LIST_TYPE_DOWNLOAD);
|
||||
song.setMediaId(downloadSong.getMediaId());
|
||||
song.setDownload(true);
|
||||
FileUtil.saveSong(song);
|
||||
|
||||
mPlayStatusBinder.play(Constant.LIST_TYPE_DOWNLOAD);
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onDownloadSuccessEvent(DownloadEvent event){
|
||||
if(event.getDownloadStatus() == Constant.TYPE_DOWNLOAD_SUCCESS){
|
||||
mDownloadSongList.clear();
|
||||
mDownloadSongList.addAll(orderList(DownloadUtil.getSongFromFile(STORAGE_SONG_FILE)));
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onSongDownloadedEvent(SongDownloadedEvent event){
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
EventBus.getDefault().unregister(this);
|
||||
}
|
||||
private List<DownloadSong> orderList(List<DownloadSong> tempList){
|
||||
List<DownloadSong> loveList=new ArrayList<>();
|
||||
loveList.clear();
|
||||
for(int i=tempList.size()-1;i>=0;i--){
|
||||
loveList.add(tempList.get(i));
|
||||
}
|
||||
return loveList;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,169 @@
|
||||
package com.example.musicplayer.view.main.download;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.example.SpeedDialog.dialog.SpeedDialog;
|
||||
import com.example.SpeedDialog.listener.OnSelectClickListener;
|
||||
import com.example.musicplayer.R;
|
||||
import com.example.musicplayer.adapter.DownloadingAdapter;
|
||||
import com.example.musicplayer.app.Constant;
|
||||
import com.example.musicplayer.entiy.DownloadInfo;
|
||||
import com.example.musicplayer.entiy.Song;
|
||||
import com.example.musicplayer.event.DownloadEvent;
|
||||
import com.example.musicplayer.service.DownloadService;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
import org.litepal.LitePal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author : 残渊
|
||||
* time : 2019/09/16
|
||||
* desc : 正在下载歌曲列表
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class DownloadingFragment extends Fragment {
|
||||
private static final String TAG = "DownloadingFragment";
|
||||
|
||||
@BindView(R.id.songDowningRecycle)
|
||||
RecyclerView songDowningRecycle;
|
||||
Unbinder unbinder;
|
||||
private DownloadingAdapter mAdapter;
|
||||
private LinearLayoutManager mLinearLayoutManager;
|
||||
private List<DownloadInfo> mDownloadInfoList; //下载队列
|
||||
|
||||
private DownloadService.DownloadBinder mDownloadBinder;
|
||||
//绑定下载服务
|
||||
private ServiceConnection mDownloadConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
|
||||
mDownloadBinder = (DownloadService.DownloadBinder) iBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName componentName) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_download_ing, container, false);
|
||||
EventBus.getDefault().register(this);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
initRecycler();
|
||||
//绑定服务
|
||||
Intent downIntent = new Intent(getActivity(), DownloadService.class);
|
||||
getActivity().bindService(downIntent, mDownloadConnection, Context.BIND_AUTO_CREATE);
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
}
|
||||
|
||||
private void initRecycler() {
|
||||
mDownloadInfoList = new LinkedList<>();
|
||||
mDownloadInfoList.addAll(LitePal.findAll(DownloadInfo.class,true));
|
||||
songDowningRecycle.setItemAnimator(null); //解决进度刷新闪屏问题
|
||||
mLinearLayoutManager = new LinearLayoutManager(getActivity());
|
||||
mAdapter = new DownloadingAdapter(mDownloadInfoList);
|
||||
songDowningRecycle.setLayoutManager(mLinearLayoutManager);
|
||||
songDowningRecycle.setAdapter(mAdapter);
|
||||
|
||||
//暂停
|
||||
mAdapter.setOnItemClickListener(position -> {
|
||||
DownloadInfo downloadInfo = mDownloadInfoList.get(position);
|
||||
Log.d(TAG, "initRecycler: "+mDownloadInfoList.get(position).getStatus());
|
||||
//判断是否为正在播放的歌曲
|
||||
if(downloadInfo.getStatus() == Constant.DOWNLOAD_PAUSED){
|
||||
mDownloadBinder.startDownload(downloadInfo);
|
||||
}else {
|
||||
//传入要暂停的音乐id
|
||||
mDownloadBinder.pauseDownload(downloadInfo.getSongId());
|
||||
}
|
||||
});
|
||||
|
||||
//取消下载
|
||||
mAdapter.setOnDeleteClickListener(position -> {
|
||||
SpeedDialog speedDialog = new SpeedDialog(getActivity(),SpeedDialog.SELECT_TYPE);
|
||||
speedDialog.setTitle(getString(R.string.download_cancel))
|
||||
.setMessage(getString(R.string.download_cancel_message))
|
||||
.setSureText(getString(R.string.download_sure))
|
||||
.setSureClickListener(dialog -> {
|
||||
mDownloadBinder.cancelDownload(mDownloadInfoList.get(position));
|
||||
})
|
||||
.show();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onDownloadingMessage(DownloadEvent event) {
|
||||
int status = event.getDownloadStatus();
|
||||
if (status == Constant.TYPE_DOWNLOADING || status == Constant.TYPE_DOWNLOAD_PAUSED) {//进度条更新
|
||||
DownloadInfo downloadInfo = event.getDownloadInfo();
|
||||
mDownloadInfoList.remove(downloadInfo.getPosition());
|
||||
mDownloadInfoList.add(downloadInfo.getPosition(),downloadInfo);
|
||||
mAdapter.notifyItemChanged(downloadInfo.getPosition());
|
||||
}else if(status == Constant.TYPE_DOWNLOAD_SUCCESS){//歌曲下载成功
|
||||
resetDownloadInfoList();
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}else if(status == Constant.TYPE_DOWNLOAD_CANCELED){//下载取消
|
||||
resetDownloadInfoList();
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}else if(status == Constant.TYPE_DOWNLOAD_ADD){//添加了正在下载歌曲
|
||||
resetDownloadInfoList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//重新从数据库中读取需要下载的歌曲
|
||||
private void resetDownloadInfoList(){
|
||||
mDownloadInfoList.clear();
|
||||
List<DownloadInfo> temp = LitePal.findAll(DownloadInfo.class,true);
|
||||
if(temp.size()!=0){
|
||||
mDownloadInfoList.addAll(temp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
EventBus.getDefault().unregister(this);
|
||||
unbinder.unbind();
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
@ -0,0 +1,49 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
android:background="@color/actionBarColor">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/backIv"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="10dp"
|
||||
android:src="@drawable/back" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_toRightOf="@id/backIv"
|
||||
android:text="@string/download"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<android.support.design.widget.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
android:background="@color/tab"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
style="@style/MyTabLayoutStyle">
|
||||
|
||||
</android.support.design.widget.TabLayout>
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/page"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</android.support.v4.view.ViewPager>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/translucent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/songDowningRecycle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="65dp"
|
||||
tools:listitem="@layout/recycler_downing_item">
|
||||
|
||||
</android.support.v7.widget.RecyclerView>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="65dp"
|
||||
android:overScrollMode="never"/>
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/translucent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/songRecycle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="65dp">
|
||||
|
||||
</android.support.v7.widget.RecyclerView>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="65dp"
|
||||
android:overScrollMode="never"/>
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/songTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/white"
|
||||
tools:text="说好不哭"
|
||||
android:layout_marginStart="@dimen/dp_20"
|
||||
android:layout_marginTop="@dimen/dp_10"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sizeTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/short_white"
|
||||
android:layout_marginTop="@dimen/dp_5"
|
||||
tools:text="2.7M "
|
||||
app:layout_constraintLeft_toLeftOf="@+id/songTv"
|
||||
app:layout_constraintTop_toBottomOf="@+id/songTv"/>
|
||||
|
||||
|
||||
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:thumb="@null"
|
||||
android:progressDrawable="@drawable/seekbar_bg"
|
||||
android:maxHeight="5dp"
|
||||
android:max="100"
|
||||
app:layout_constraintLeft_toRightOf="@+id/sizeTv"
|
||||
app:layout_constraintTop_toTopOf="@+id/sizeTv"
|
||||
app:layout_constraintRight_toLeftOf="@id/cancelIv"
|
||||
app:layout_constraintBottom_toBottomOf="@id/sizeTv"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cancelIv"
|
||||
android:layout_width="@dimen/dp_30"
|
||||
android:layout_height="@dimen/dp_30"
|
||||
android:src="@drawable/delete"
|
||||
android:layout_marginEnd="@dimen/dp_10"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.1dip"
|
||||
android:background="@color/gray"
|
||||
android:layout_marginTop="@dimen/dp_10"
|
||||
app:layout_constraintTop_toBottomOf="@id/sizeTv"/>
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
After Width: | Height: | Size: 6.5 MiB |
|
After Width: | Height: | Size: 9.8 MiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 162 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 160 KiB |
|
After Width: | Height: | Size: 86 KiB |