增加网络和加载界面,初步完成大部分所需的功能

pull/1/head
jsyjst 7 years ago
parent 00f4c565e2
commit 29f9c94e38

@ -59,6 +59,9 @@ dependencies {
//litePal
implementation 'org.litepal.android:java:3.0.0'
//
compile 'com.patrickpissurno:ripple-effect:1.3.1'
implementation 'com.patrickpissurno:ripple-effect:1.3.1'
//
implementation 'com.wang.avi:library:2.1.3'
}

@ -10,9 +10,9 @@
<application
android:name=".constant.MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:icon="@mipmap/icon"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:roundIcon="@mipmap/icon"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".view.WelcomeActivity">

@ -10,6 +10,7 @@ import android.widget.TextView;
import com.andexert.library.RippleView;
import com.example.musicplayer.R;
import com.example.musicplayer.constant.MyApplication;
import com.example.musicplayer.entiy.AlbumSong;
import com.example.musicplayer.util.FileHelper;
@ -58,13 +59,18 @@ public class AlbumSongAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
AlbumSong.DataBean.SongsBean songsBean = mSongsBeanList.get(position);
holder.artistTv.setText(songsBean.getSinger());
holder.titleTv.setText(songsBean.getName());
holder.mItemView.setBackgroundResource(R.color.translucent);
//根据点击显示
mLastPosition = FileHelper.getSong().getCurrent();
holder.playLine.setVisibility((songsBean.getId().equals(FileHelper.getSong().getOnlineId())
? View.VISIBLE : View.INVISIBLE));
holder.mItemView.setBackgroundResource((songsBean.getId().equals(FileHelper.getSong().getOnlineId())
? R.color.click : R.color.translucent));
if(songsBean.getId().equals(FileHelper.getSong().getOnlineId())){
holder.playLine.setVisibility(View.VISIBLE);
holder.titleTv.setTextColor(MyApplication.getContext().getResources().getColor(R.color.yellow));
holder.artistTv.setTextColor(MyApplication.getContext().getResources().getColor(R.color.yellow));
mLastPosition = position;
}else{
holder.playLine.setVisibility(View.INVISIBLE);
holder.titleTv.setTextColor(MyApplication.getContext().getResources().getColor(R.color.white));
holder.artistTv.setTextColor(MyApplication.getContext().getResources().getColor(R.color.white_blue));
}
holder.mItemView.setOnRippleCompleteListener(new RippleView.OnRippleCompleteListener() {
@Override
public void onComplete(RippleView rippleView) {

@ -16,16 +16,16 @@ import com.example.musicplayer.util.CommonUtil;
import java.util.List;
/**
*
* Created by on 2018/9/23.
*/
public class ExpandableListViewAdapter extends BaseExpandableListAdapter {
private static final String TAG = "ExpandableListViewAdapter";
private String[] mGroupStrings;
private List<List<AlbumCollection>> mAlbumCollectionList;
private String[] mGroupStrings; //一级标题
private List<List<AlbumCollection>> mAlbumCollectionList; //二级收藏歌单列表
private Context mContext;
private OnChildItemClickListener mChildClickListener;
private OnChildItemClickListener mChildClickListener; //二级item的点击监听
public ExpandableListViewAdapter(Context context, String[] groupStrings, List<List<AlbumCollection>> albumCollectionList) {
@ -33,6 +33,7 @@ public class ExpandableListViewAdapter extends BaseExpandableListAdapter {
mGroupStrings = groupStrings;
mContext = context;
}
//提供给外部使用
public void setOnChildItemClickListener(OnChildItemClickListener onChildItemClickListener){
mChildClickListener=onChildItemClickListener;
}
@ -72,6 +73,7 @@ public class ExpandableListViewAdapter extends BaseExpandableListAdapter {
return true;
}
//绘制一级列表
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View view;
@ -81,13 +83,13 @@ public class ExpandableListViewAdapter extends BaseExpandableListAdapter {
groupViewHolder = new GroupViewHolder();
groupViewHolder.groupTextView = view.findViewById(R.id.tv_new_song);
groupViewHolder.pointIv = view.findViewById(R.id.iv_point);
groupViewHolder.addIv = view.findViewById(R.id.iv_add);
view.setTag(groupViewHolder);
} else {
view = convertView;
groupViewHolder = (GroupViewHolder) view.getTag();
}
groupViewHolder.groupTextView.setText(mGroupStrings[groupPosition]);
//根据展开的状态来改变箭头方向
if (isExpanded) {
groupViewHolder.pointIv.setImageResource(R.drawable.up);
} else {
@ -97,6 +99,7 @@ public class ExpandableListViewAdapter extends BaseExpandableListAdapter {
}
//绘制二级列表
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View view;
@ -118,6 +121,7 @@ public class ExpandableListViewAdapter extends BaseExpandableListAdapter {
childViewHolder.authorTv.setText(mAlbumCollectionList.get(groupPosition).get(childPosition).getSingerName());
CommonUtil.setImgWithGlide(mContext,
mAlbumCollectionList.get(groupPosition).get(childPosition).getAlbumPic(), childViewHolder.faceIv);
//点击水波纹效果,结束后开始点击效果
childViewHolder.childView.setOnRippleCompleteListener(new RippleView.OnRippleCompleteListener() {
@Override
public void onComplete(RippleView rippleView) {
@ -136,7 +140,6 @@ public class ExpandableListViewAdapter extends BaseExpandableListAdapter {
class GroupViewHolder {
private TextView groupTextView;
private ImageView pointIv;
private ImageView addIv;
}
class ChildViewHolder {

@ -0,0 +1,44 @@
package com.example.musicplayer.base;
import android.widget.Toast;
import com.example.musicplayer.constant.Constant;
import com.example.musicplayer.entiy.AlbumSong;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.util.RxApiManager;
import java.net.UnknownHostException;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
/**
* Created by on 2018/12/5.
*/
public abstract class BaseObserver<T> implements Observer<T> {
private BaseActivity context;
public BaseObserver(BaseActivity context) {
this.context = context;
}
@Override
public void onSubscribe(Disposable d) {
RxApiManager.get().add(Constant.ALBUM,d);
}
@Override
public void onError(Throwable e) {
if(e instanceof UnknownHostException){
onComplete();
CommonUtil.showToast(context,"当前网络不可用,请检查当前网络");
}
}
@Override
public void onComplete() {
}
}

@ -0,0 +1,17 @@
package com.example.musicplayer.callback;
import io.reactivex.disposables.Disposable;
/**
* rxJavaSubscription
* Created by on 2018/12/5.
*/
public interface RxActionManager<T> {
void add(T tag, Disposable d);
void remove(T tag);
void cancel(T tag);
void cancelAll();
}

@ -14,4 +14,10 @@ public class Constant {
public static final int LIST_TYPE_LOVE=6;
public static final int LIST_TYPE_HISTORY=7;
public static final int HISTORY_MAX_SIZE=100;
public static final String LOCAL_IMG="local_img";
public static final String SEARCH_SONG= "search_song";
public static final String SEARCH_SONG_MORE= "search_song_more";
public static final String SEARCH_ALBUM="search_album";
public static final String SEARCH_ALBUM_MORE="search_album_more";
public static final String ALBUM="album";
}

@ -19,7 +19,9 @@ public interface IAlbumSongContract {
void setAlbumSongList(List<AlbumSong.DataBean.SongsBean> songList); //成功获取专辑歌曲后填充列表
void showAlbumSongError();//获取专辑失败
void showAlbumMessage(String name,String singer,String company,String desc); //展示专辑详细
void showNetError(); //网络错误
void showLoading(); //显示进度
void hideLoading(); //隐藏进度
void showNetError(); //显示网络错误
}
interface Presenter{
void getAlbumDetail(String id,int type); //获取专辑的更多信息
@ -29,5 +31,7 @@ public interface IAlbumSongContract {
void getAlbumError(); //接口出现问题
void insertAllAlbumSong(ArrayList<AlbumSong.DataBean.SongsBean> songList); //将专辑歌曲添加到数据库
void showNetError(); //显示网络错误
}
}

@ -31,6 +31,9 @@ public interface ISearchContentContract {
void searchAlbumSuccess(List<Album.DataBean> albumList); //获取专辑成功
void searchAlbumMoreSuccess(List<Album.DataBean> songListBeans); //搜索更多内容成功
void searchAlbumError(); //获取专辑失败
void showLoading(); //显示进度
void hideLoading(); //隐藏进度
void showNetError(); //显示网络错误
}
interface Presenter{
void search(String seek,int offset); //搜索
@ -47,5 +50,9 @@ public interface ISearchContentContract {
void searchAlbumMore(String seek,int offset);//搜索更多专辑
void searchAlbumMoreSuccess(List<Album.DataBean> songListBeans); //搜索更多内容成功
void networkError();//网络错误
}
}

@ -6,6 +6,8 @@ import com.example.musicplayer.https.api.AlbumApi;
import com.example.musicplayer.https.api.SearchApi;
import com.example.musicplayer.https.api.SingerImgApi;
import org.reactivestreams.Subscription;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
@ -24,7 +26,7 @@ import static com.example.musicplayer.constant.BaseUri.SINGER_URL;
*/
public class NetWork {
private static okhttp3.OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(20, TimeUnit.SECONDS);
private static okhttp3.OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS);
private static Converter.Factory gsonConverterFactory = GsonConverterFactory.create();
private static CallAdapter.Factory rxJavaCallAdapterFactory = RxJava2CallAdapterFactory.create();
private static SingerImgApi singerImgApi;

@ -2,14 +2,17 @@ package com.example.musicplayer.model;
import android.util.Log;
import com.example.musicplayer.constant.Constant;
import com.example.musicplayer.contract.IAlbumSongContract;
import com.example.musicplayer.entiy.AlbumSong;
import com.example.musicplayer.entiy.OnlineSong;
import com.example.musicplayer.https.NetWork;
import com.example.musicplayer.util.RxApiManager;
import org.litepal.LitePal;
import org.litepal.crud.LitePalSupport;
import java.net.UnknownHostException;
import java.util.ArrayList;
import io.reactivex.Observer;
@ -17,6 +20,8 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import static com.example.musicplayer.view.AlbumSongFragment.ALBUM_SONG;
/**
* Created by on 2018/11/27.
*/
@ -36,7 +41,7 @@ public class AlbumSongModel implements IAlbumSongContract.Model {
.subscribe(new Observer<AlbumSong>() {
@Override
public void onSubscribe(Disposable d) {
RxApiManager.get().add(Constant.ALBUM, d);
}
@Override
@ -53,8 +58,12 @@ public class AlbumSongModel implements IAlbumSongContract.Model {
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: " + e.toString());
if (e instanceof UnknownHostException && type == ALBUM_SONG) {
mPresenter.showNetError();
} else {
mPresenter.getAlbumError();
}
}
@Override
public void onComplete() {

@ -3,18 +3,19 @@ package com.example.musicplayer.model;
import android.support.annotation.MainThread;
import android.util.Log;
import com.example.musicplayer.constant.Constant;
import com.example.musicplayer.contract.IPlayContract;
import com.example.musicplayer.entiy.Love;
import com.example.musicplayer.entiy.SingerImg;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.https.NetWork;
import com.example.musicplayer.util.RxApiManager;
import org.litepal.LitePal;
import org.litepal.crud.callback.FindMultiCallback;
import org.litepal.crud.callback.SaveCallback;
import org.litepal.crud.callback.UpdateOrDeleteCallback;
import java.io.IOException;
import java.util.List;
import io.reactivex.Observer;
@ -45,7 +46,7 @@ public class PlayModel implements IPlayContract.Model {
.subscribe(new Observer<SingerImg>() {
@Override
public void onSubscribe(Disposable d) {
RxApiManager.get().add(Constant.LOCAL_IMG,d);
}
@Override

@ -2,11 +2,14 @@ package com.example.musicplayer.model;
import android.util.Log;
import com.example.musicplayer.constant.Constant;
import com.example.musicplayer.contract.ISearchContentContract;
import com.example.musicplayer.entiy.Album;
import com.example.musicplayer.entiy.SeachSong;
import com.example.musicplayer.https.NetWork;
import com.example.musicplayer.util.RxApiManager;
import java.net.UnknownHostException;
import java.util.ArrayList;
import io.reactivex.Observer;
@ -33,7 +36,7 @@ public class SearchContentModel implements ISearchContentContract.Model {
.subscribe(new Observer<SeachSong>() {
@Override
public void onSubscribe(Disposable d) {
RxApiManager.get().add(Constant.SEARCH_SONG, d);
}
@Override
@ -43,7 +46,9 @@ public class SearchContentModel implements ISearchContentContract.Model {
@Override
public void onError(Throwable e) {
mPresenter.searchError();
if (e instanceof UnknownHostException) {
mPresenter.networkError();
}
Log.d(TAG, "onError: " + e.toString());
}
@ -62,7 +67,7 @@ public class SearchContentModel implements ISearchContentContract.Model {
.subscribe(new Observer<SeachSong>() {
@Override
public void onSubscribe(Disposable d) {
RxApiManager.get().add(Constant.SEARCH_SONG_MORE, d);
}
@Override
@ -99,7 +104,7 @@ public class SearchContentModel implements ISearchContentContract.Model {
.subscribe(new Observer<Album>() {
@Override
public void onSubscribe(Disposable d) {
RxApiManager.get().add(Constant.SEARCH_ALBUM, d);
}
@Override
@ -113,7 +118,11 @@ public class SearchContentModel implements ISearchContentContract.Model {
@Override
public void onError(Throwable e) {
if (e instanceof UnknownHostException) {
mPresenter.networkError();
} else {
mPresenter.searchAlbumError();
}
Log.d(TAG, "onError: searchAlbumError" + e.toString());
}
@ -132,7 +141,7 @@ public class SearchContentModel implements ISearchContentContract.Model {
.subscribe(new Observer<Album>() {
@Override
public void onSubscribe(Disposable d) {
RxApiManager.get().add(Constant.SEARCH_ALBUM_MORE, d);
}
@Override

@ -1,8 +1,10 @@
package com.example.musicplayer.presenter;
import android.os.Handler;
import android.util.Log;
import com.example.musicplayer.base.BasePresenter;
import com.example.musicplayer.constant.Constant;
import com.example.musicplayer.contract.IAlbumSongContract;
import com.example.musicplayer.entiy.AlbumSong;
import com.example.musicplayer.model.AlbumSongModel;
@ -11,6 +13,9 @@ import com.example.musicplayer.view.AlbumSongFragment;
import java.util.ArrayList;
import java.util.List;
import static com.example.musicplayer.view.AlbumSongFragment.ALBUM_SONG;
/**
* Created by on 2018/11/27.
*/
@ -20,6 +25,7 @@ public class AlbumSongPresenter extends BasePresenter<IAlbumSongContract.View> i
private final static String TAG = "AlbumSongPresenter";
private AlbumSongModel mModel;
private Handler mHandler = new Handler();
public AlbumSongPresenter() {
mModel = new AlbumSongModel(this);
@ -28,20 +34,32 @@ public class AlbumSongPresenter extends BasePresenter<IAlbumSongContract.View> i
@Override
public void getAlbumDetail(String id, int type) {
mModel.getAlbumDetail(id, type);
if (type == ALBUM_SONG) {
if (isAttachView()) {
getMvpView().showLoading();
}
}
}
@Override
public void getAlbumDetailSuccess(int type, List<AlbumSong.DataBean.SongsBean> songList,
String name, String singer, String company, String desc) {
public void getAlbumDetailSuccess(final int type, final List<AlbumSong.DataBean.SongsBean> songList,
final String name, final String singer, final String company, final String desc) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (isAttachView()) {
if (type == AlbumSongFragment.ALBUM_SONG) {
if (type == ALBUM_SONG) {
getMvpView().setAlbumSongList(songList);
Log.d(TAG, "getAlbumDetailSuccess: "+songList.size());
getMvpView().hideLoading();
} else {
getMvpView().showAlbumMessage(name, singer, company, desc);
}
}
}
}, 1000);
}
@Override
public void getAlbumDetailError() {
@ -53,7 +71,7 @@ public class AlbumSongPresenter extends BasePresenter<IAlbumSongContract.View> i
@Override
public void getAlbumError() {
if (isAttachView()) {
getMvpView().showNetError();
getMvpView().showAlbumSongError();
}
}
@ -61,4 +79,17 @@ public class AlbumSongPresenter extends BasePresenter<IAlbumSongContract.View> i
public void insertAllAlbumSong(ArrayList<AlbumSong.DataBean.SongsBean> songList) {
mModel.insertAllAlbumSong(songList);
}
@Override
public void showNetError() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (isAttachView()) {
getMvpView().showNetError();
}
}
}, 1000);
}
}

@ -26,6 +26,9 @@ public class SearchContentPresenter extends BasePresenter<ISearchContentContract
@Override
public void search(String seek,int offset) {
mModel.search(seek,offset);
if(isAttachView()){
getMvpView().showLoading();
}
}
@Override
@ -34,12 +37,18 @@ public class SearchContentPresenter extends BasePresenter<ISearchContentContract
}
@Override
public void searchSuccess(ArrayList<SeachSong.DataBean> songListBeans) {
public void searchSuccess(final ArrayList<SeachSong.DataBean> songListBeans) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if(isAttachView()){
getMvpView().hideLoading();
getMvpView().setSongsList(songListBeans);
}
}
},500);
}
@Override
public void searchError() {
@ -82,12 +91,16 @@ public class SearchContentPresenter extends BasePresenter<ISearchContentContract
@Override
public void searchAlbum(String seek, int offset) {
mModel.searchAlbum(seek,offset);
if(isAttachView()){
getMvpView().showLoading();
}
}
@Override
public void searchAlbumSuccess(List<Album.DataBean> albumList) {
if(isAttachView()){
getMvpView().searchAlbumSuccess(albumList);
getMvpView().hideLoading();
}
}
@ -95,6 +108,7 @@ public class SearchContentPresenter extends BasePresenter<ISearchContentContract
public void searchAlbumError() {
if(isAttachView()){
getMvpView().searchAlbumError();
getMvpView().hideLoading();
}
}
@ -114,4 +128,11 @@ public class SearchContentPresenter extends BasePresenter<ISearchContentContract
}
},500);
}
@Override
public void networkError() {
if(isAttachView()){
getMvpView().showNetError();
}
}
}

@ -2,6 +2,7 @@ package com.example.musicplayer.service;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
@ -65,6 +66,8 @@ public class PlayerService extends Service {
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Log.d(TAG, "onCompletion: true");
sendBroadcast(new Intent(BroadcastName.SONG_PAUSE));//暂停广播
mCurrent = FileHelper.getSong().getCurrent();
mCurrent++;
//将歌曲的信息保存起来
@ -75,7 +78,6 @@ public class PlayerService extends Service {
sendBroadcast(new Intent(BroadcastName.LOCAL_SONG_CHANGE_LIST));//发送广播改变当地列表的显示
} else {
mPlayStatusBinder.stop();
sendBroadcast(new Intent(BroadcastName.SONG_PAUSE)); //发送暂停的广播
}
} else if (mListType == Constant.LIST_TYPE_ONLINE) {
if (mCurrent < mSongList.size()) {
@ -84,7 +86,6 @@ public class PlayerService extends Service {
sendBroadcast(new Intent(BroadcastName.ONLINE_ALBUM_SONG_Change));//专辑列表的改变
} else {
mPlayStatusBinder.stop();
sendBroadcast(new Intent(BroadcastName.SONG_PAUSE)); //发送暂停的广播
}
} else if (mListType == Constant.LIST_TYPE_LOVE) {
@ -94,7 +95,6 @@ public class PlayerService extends Service {
sendBroadcast(new Intent(BroadcastName.LOVE_SONG_CHANGE));//专辑列表的改变
} else {
mPlayStatusBinder.stop();
sendBroadcast(new Intent(BroadcastName.SONG_PAUSE)); //发送暂停的广播
}
} else {
if (mCurrent < mHistoryList.size()) {
@ -102,15 +102,18 @@ public class PlayerService extends Service {
mPlayStatusBinder.play(Constant.LIST_TYPE_HISTORY);
} else {
mPlayStatusBinder.stop();
sendBroadcast(new Intent(BroadcastName.SONG_PAUSE)); //发送暂停的广播
}
}
sendBroadcast(new Intent(BroadcastName.ONLINE_SONG_FINISH));//发送网络歌曲播放结束的广播改变网络搜索列表的改变
}
});
/**
* MediaPlayersetOnCompletionListener
* trueonCompletion
*/
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.d(TAG, "onError: "+what);
return true;
}
});
@ -119,7 +122,6 @@ public class PlayerService extends Service {
@Override
public void onRebind(Intent intent) {
Log.d(TAG, "-------onRebind: ");
}
@ -156,30 +158,26 @@ public class PlayerService extends Service {
mediaPlayer.reset();//把各项参数恢复到初始状态
if (mListType == Constant.LIST_TYPE_LOCAL) {
mediaPlayer.setDataSource(mLocalSongList.get(mCurrent).getUrl());
mediaPlayer.prepare(); //进行缓冲
} else if (mListType == Constant.LIST_TYPE_ONLINE) {
mediaPlayer.setDataSource(mSongList.get(mCurrent).getUrl());
mediaPlayer.prepare(); //进行缓冲
} else {
if (mListType == Constant.LIST_TYPE_LOVE) {
} else if (mListType == Constant.LIST_TYPE_LOVE) {
mediaPlayer.setDataSource(mLoveList.get(mCurrent).getUrl());
} else {
Log.d(TAG, "play: "+mCurrent);
mediaPlayer.setDataSource(mHistoryList.get(mCurrent).getUrl());
}
mediaPlayer.prepare(); //进行缓冲
//保存歌曲时长
Song song = FileHelper.getSong();
song.setDuration(mediaPlayer.getDuration());
FileHelper.saveSong(song);
}
isPlaying = true;
mediaPlayer.start();
saveToHistoryTable();
sendBroadcast(new Intent(BroadcastName.ONLINE_ALBUM_SONG_Change));
sendBroadcast(new Intent(BroadcastName.SONG_CHANGE));
sendBroadcast(new Intent(BroadcastName.ONLINE_SONG_FINISH));//发送网络歌曲播放结束的广播改变网络搜索列表的改变
} catch (Exception e) {
e.printStackTrace();
}
}
@ -196,6 +194,7 @@ public class PlayerService extends Service {
isPlaying = true;
saveToHistoryTable();
sendBroadcast(new Intent(BroadcastName.ONLINE_SONG));
sendBroadcast(new Intent(BroadcastName.SONG_CHANGE));
} catch (Exception e) {
sendBroadcast(new Intent(BroadcastName.ONLINE_SONG_ERROR));
e.printStackTrace();
@ -225,9 +224,10 @@ public class PlayerService extends Service {
}
public void next() {
sendBroadcast(new Intent(BroadcastName.SONG_PAUSE));//暂停广播
mCurrent = FileHelper.getSong().getCurrent();
mCurrent++;
Log.d(TAG, "next: "+mCurrent);
if (mListType == Constant.LIST_TYPE_LOCAL) {
if (mCurrent >= mLocalSongList.size()) {
mCurrent = 0;
@ -246,7 +246,6 @@ public class PlayerService extends Service {
if (mCurrent >= mLoveList.size()) {
mCurrent = 0;
}
Log.d(TAG, "next: " + mCurrent);
saveLoveInfo(mCurrent);
mPlayStatusBinder.play(Constant.LIST_TYPE_LOVE);
sendBroadcast(new Intent(BroadcastName.LOVE_SONG_CHANGE));
@ -261,6 +260,7 @@ public class PlayerService extends Service {
}
public void last() {
sendBroadcast(new Intent(BroadcastName.SONG_PAUSE));//暂停广播
mCurrent = FileHelper.getSong().getCurrent();
mCurrent--;
if (mCurrent == -1) {
@ -427,7 +427,6 @@ public class PlayerService extends Service {
//将歌曲保存到最近播放的数据库中
private void saveToHistoryTable() {
Log.d(TAG, "saveToHistoryTable: ture");
final Song song = FileHelper.getSong();
LitePal.where("songId=?", song.getOnlineId()).findAsync(HistorySong.class)

@ -0,0 +1,94 @@
package com.example.musicplayer.util;
import android.annotation.TargetApi;
import android.os.Build;
import android.support.v4.util.ArrayMap;
import android.util.Log;
import com.example.musicplayer.callback.RxActionManager;
import org.reactivestreams.Subscription;
import java.util.Set;
import io.reactivex.disposables.Disposable;
/**
* Created by on 2018/12/5.
*/
public class RxApiManager implements RxActionManager<Object> {
private static final String TAG="RxApiManager";
private static RxApiManager sInstance = null;
private ArrayMap<Object, Disposable> maps;
public static RxApiManager get() {
if (sInstance == null) {
synchronized (RxApiManager.class) {
if (sInstance == null) {
sInstance = new RxApiManager();
}
}
}
return sInstance;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private RxApiManager() {
maps = new ArrayMap<>();
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public void add(Object tag, Disposable disposable) {
maps.put(tag, disposable);
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public void remove(Object tag) {
if (!maps.isEmpty()) {
maps.remove(tag);
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public void removeAll() {
if (!maps.isEmpty()) {
maps.clear();
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override public void cancel(Object tag) {
if (maps.isEmpty()) {
return;
}
if (maps.get(tag) == null) {
return;
}
if (!maps.get(tag).isDisposed()) {
Log.d(TAG, "cancel: "+tag);
maps.get(tag).dispose();
maps.remove(tag);
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override public void cancelAll() {
if (maps.isEmpty()) {
return;
}
Set<Object> keys = maps.keySet();
for (Object apiKey : keys) {
cancel(apiKey);
}
removeAll();
}
}

@ -19,6 +19,7 @@ import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.musicplayer.R;
@ -35,8 +36,10 @@ import com.example.musicplayer.presenter.AlbumSongPresenter;
import com.example.musicplayer.service.PlayerService;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.util.FileHelper;
import com.example.musicplayer.util.RxApiManager;
import com.github.florent37.materialviewpager.MaterialViewPagerHelper;
import com.github.florent37.materialviewpager.header.MaterialViewPagerHeaderDecorator;
import com.wang.avi.AVLoadingIndicatorView;
import org.litepal.LitePal;
@ -64,6 +67,12 @@ public class AlbumSongFragment extends Fragment implements IAlbumSongContract.Vi
private String mPublicTime;
private String mDesc;
//用来判断网络问题及加载问题
private AVLoadingIndicatorView mLoading;
private TextView mLoadingTv;
private ImageView mNetworkErrorIv;
private List<AlbumSong.DataBean.SongsBean> mSongsList;
private RecyclerView mRecycle;
@ -94,6 +103,9 @@ public class AlbumSongFragment extends Fragment implements IAlbumSongContract.Vi
if (mType == ALBUM_SONG) {
view = inflater.inflate(R.layout.fragment_album_recycler, container, false);
mRecycle = view.findViewById(R.id.recycler_song_list);
mLoading = view.findViewById(R.id.avi);
mLoadingTv = view.findViewById(R.id.tv_loading);
mNetworkErrorIv = view.findViewById(R.id.iv_network_error);
LitePal.getDatabase();
} else {
view = inflater.inflate(R.layout.fragment_album_song, container, false);
@ -130,9 +142,9 @@ public class AlbumSongFragment extends Fragment implements IAlbumSongContract.Vi
}
@Override
public void onDestroy(){
super.onDestroy();
getActivity().unregisterReceiver(albumSongChangeReceiver);
public void onDestroyView(){
RxApiManager.get().cancel(Constant.ALBUM);
super.onDestroyView();
}
private void getBundle(){
@ -198,9 +210,24 @@ public class AlbumSongFragment extends Fragment implements IAlbumSongContract.Vi
mPublicTimeTv.setText(mPublicTime);
}
@Override
public void showLoading() {
mLoading.show();
}
@Override
public void hideLoading() {
mLoading.hide();
mLoadingTv.setVisibility(View.GONE);
mRecycle.setVisibility(View.VISIBLE);
mNetworkErrorIv.setVisibility(View.GONE);
}
@Override
public void showNetError() {
CommonUtil.showToast(getActivity(),"网络错误");
mLoadingTv.setVisibility(View.GONE);
mLoading.hide();
mNetworkErrorIv.setVisibility(View.VISIBLE);
}
class AlbumSongChangeReceiver extends BroadcastReceiver {

@ -16,7 +16,9 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.example.musicplayer.R;
@ -54,7 +56,7 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract.
private ImageView mFindLocalMusicIv;
private ImageView mBackIv;
private ViewStub mEmptyViewStub;
private FrameLayout mEmptyViewLinear;
private ServiceConnection connection = new ServiceConnection() {
@Override
@ -76,7 +78,7 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract.
mRecycler = mView.findViewById(R.id.recycler_song_list);
mFindLocalMusicIv = mView.findViewById(R.id.iv_find_local_song);
mBackIv = mView.findViewById(R.id.iv_back);
mEmptyViewStub = mView.findViewById(R.id.stub_empty);
mEmptyViewLinear = mView.findViewById(R.id.linear_empty);
return mView;
}
@ -90,6 +92,7 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract.
initView();
setOnClickListener();
}
@Override
public void onDestroy() {
super.onDestroy();
@ -109,13 +112,12 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract.
getActivity().bindService(playIntent, connection, Context.BIND_AUTO_CREATE);
mLocalSongsList = LitePal.findAll(LocalSong.class);
Log.d(TAG, "initView: "+mLocalSongsList.size());
if (mLocalSongsList.size() == 0) {
mRecycler.setVisibility(View.GONE);
mEmptyViewStub.setVisibility(View.VISIBLE);
mEmptyViewLinear.setVisibility(View.VISIBLE);
} else {
mRecycler.setVisibility(View.VISIBLE);
mEmptyViewStub.setVisibility(View.GONE);
mEmptyViewLinear.setVisibility(View.GONE);
mRecycler.setLayoutManager(layoutManager);
@ -172,17 +174,26 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract.
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mLocalSongsList.clear();
mLocalSongsList.addAll(mp3InfoList);
if (mLocalSongsList.size() == 0) {
mRecycler.setVisibility(View.GONE);
mEmptyViewLinear.setVisibility(View.VISIBLE);
} else {
mRecycler.setVisibility(View.VISIBLE);
mEmptyViewLinear.setVisibility(View.GONE);
mRecycler.setLayoutManager(layoutManager);
//令recyclerView定位到当前播放的位置
songAdapter = new SongAdapter(mView.getContext(), mLocalSongsList);
mRecycler.setAdapter(songAdapter);
setOnClickListener();
CommonUtil.showToast(getActivity(), "成功导入本地音乐");
mPresenter.saveSong(mp3InfoList);//保存到数据库中
if (FileHelper.getSong() != null) {
layoutManager.scrollToPositionWithOffset(FileHelper.getSong().getCurrent() - 4, mRecycler.getHeight());
}
}
}
});
}

@ -37,6 +37,7 @@ import com.example.musicplayer.service.PlayerService;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.util.FileHelper;
import com.example.musicplayer.util.MediaUtil;
import com.example.musicplayer.util.RxApiManager;
import org.litepal.LitePal;
@ -92,21 +93,22 @@ public class MainActivity extends AppCompatActivity {
songChangeReceiver = new SongChangeReceiver();
registerReceiver(songChangeReceiver, intentFilter);
LitePal.getDatabase();
//启动服务
Intent playIntent = new Intent(MainActivity.this, PlayerService.class);
bindService(playIntent, connection, Context.BIND_AUTO_CREATE);
initView();
onClick();
}
private void initView() {
mSong = FileHelper.getSong();
Log.d(TAG, "jsyjst: " + mSong.toString());
mSongNameTv = findViewById(R.id.tv_song_name);
mSingerTv = findViewById(R.id.tv_singer);
mLinear = findViewById(R.id.linear_player);
mSeekBar = findViewById(R.id.sb_progress);
mNextIv = findViewById(R.id.song_next);
mCoverIv = findViewById(R.id.circle_img);
mPlayerBtn = findViewById(R.id.btn_player);
//设置属性动画
mCircleAnimator = ObjectAnimator.ofFloat(mCoverIv, "rotation", 0.0f, 360.0f);
mCircleAnimator.setDuration(30000);
@ -116,11 +118,6 @@ public class MainActivity extends AppCompatActivity {
if (mSong.getSongName() != null) {
//启动服务
Intent playIntent = new Intent(MainActivity.this, PlayerService.class);
bindService(playIntent, connection, Context.BIND_AUTO_CREATE);
Log.d(TAG, "------initView:bindService ");
mLinear.setVisibility(View.VISIBLE);
mSongNameTv.setText(mSong.getSongName());
mSingerTv.setText(mSong.getSinger());
@ -135,12 +132,20 @@ public class MainActivity extends AppCompatActivity {
.apply(RequestOptions.errorOf(R.drawable.welcome))
.into(mCoverIv);
}
onClick();
} else {
mLinear.setVisibility(View.GONE);
mSongNameTv.setText("心渊音乐");
mSingerTv.setText("袁健策 3117004905");
mCoverIv.setImageResource(R.drawable.jay);
mLinear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CommonUtil.showToast(MainActivity.this, "开启你的音乐之旅吧");
}
});
}
mPlayerBtn = findViewById(R.id.btn_player);
addMainFragment();
}
@ -181,8 +186,6 @@ public class MainActivity extends AppCompatActivity {
time = mMediaPlayer.getCurrentPosition();
mPlayStatusBinder.pause();
flag = true;
mPlayerBtn.setSelected(false);
mCircleAnimator.pause();
} else if (flag) {
mPlayStatusBinder.resume();
flag = false;
@ -191,10 +194,6 @@ public class MainActivity extends AppCompatActivity {
} else {
isSeek = false;
}
mCircleAnimator.resume();
mPlayerBtn.setSelected(true);
mSeekBarThread = new Thread(new SeekBarThread());
mSeekBarThread.start();
} else {
if (FileHelper.getSong().isOnline()) {
mPlayStatusBinder.playOnline();
@ -202,9 +201,6 @@ public class MainActivity extends AppCompatActivity {
mPlayStatusBinder.play(FileHelper.getSong().getListType());
}
mMediaPlayer.seekTo((int) mSong.getCurrentTime());
mCircleAnimator.start();
mPlayerBtn.setSelected(true);
seekBarStart();
}
}
});
@ -262,11 +258,10 @@ public class MainActivity extends AppCompatActivity {
if (mSeekBarThread != null) mSeekBarThread.interrupt();
Song song = FileHelper.getSong();
song.setCurrentTime(mPlayStatusBinder.getCurrentTime());
Log.d(TAG, "onServiceDisconnected: " + song.getCurrentTime());
FileHelper.saveSong(song);
RxApiManager.get().cancelAll();
super.onDestroy();
}
private void seekBarStart() {
@ -296,11 +291,27 @@ public class MainActivity extends AppCompatActivity {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
mSong = FileHelper.getSong();
onClick();
if (action.equals(BroadcastName.ONLINE_SONG_ERROR)) {
CommonUtil.showToast(MainActivity.this, "抱歉,该歌曲暂无版权,搜搜其他歌曲吧");
} else if (action.equals(BroadcastName.SONG_PAUSE)) {
mPlayerBtn.setSelected(false);
mCircleAnimator.pause();
} else if (action.equals(BroadcastName.SONG_RESUME)) {
mPlayerBtn.setSelected(true);
mCircleAnimator.resume();
seekBarStart();
} else if (action.equals(BroadcastName.SONG_CHANGE)) {
mSong = FileHelper.getSong();
mSongNameTv.setText(mSong.getSongName());
mSingerTv.setText(mSong.getSinger());
Log.d(TAG, "onReceive: " + mSong.getDuration());
mSeekBar.setMax((int) mSong.getDuration());
mPlayerBtn.setSelected(true);
mCircleAnimator.start();
seekBarStart();
}
if (!mSong.isOnline()) {
FileHelper.setSingerImg(MainActivity.this, mSong.getSinger(), mCoverIv);
} else {
@ -310,19 +321,6 @@ public class MainActivity extends AppCompatActivity {
.apply(RequestOptions.errorOf(R.drawable.welcome))
.into(mCoverIv);
}
if (action.equals(BroadcastName.SONG_PAUSE)) {
mPlayerBtn.setSelected(false);
mCircleAnimator.pause();
} else if (action.equals(BroadcastName.SONG_RESUME)) {
mPlayerBtn.setSelected(true);
mCircleAnimator.resume();
seekBarStart();
} else {
mPlayerBtn.setSelected(true);
mCircleAnimator.start();
seekBarStart();
}
}
}
}

@ -13,22 +13,17 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.musicplayer.R;
import com.example.musicplayer.adapter.ExpandableListViewAdapter;
import com.example.musicplayer.adapter.HistoryAdapter;
import com.example.musicplayer.constant.BroadcastName;
import com.example.musicplayer.entiy.Album;
import com.example.musicplayer.entiy.AlbumCollection;
import com.example.musicplayer.entiy.HistorySong;
import com.example.musicplayer.entiy.LocalSong;
import com.example.musicplayer.entiy.Love;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.widget.MyListView;
import org.litepal.LitePal;
@ -46,19 +41,13 @@ public class MainFragment extends Fragment {
private MyListView myListView;
private ExpandableListViewAdapter mAdapter;
private LinearLayout mLocalMusicLinear, mCollectionLinear, mHistoryMusicLinear;
private Button playerBtn;
private TextView mLocalMusicNum, mLoveMusicNum, mHistoryMusicNum;
private TextView mSeekBtn;
private List<List<AlbumCollection>> mAlbumCollectionList;
private List<AlbumCollection> mLoveAlbumList;
private boolean oneExpand;
private boolean twoExpand;
private String[] mGroupStrings = {"自建歌单", "收藏歌单"};
private String[][] mSongStrings = {
{"我喜欢"},
{"Jay", "魔杰座"}
};
//注册广播
private IntentFilter intentFilter;
private SongChangeReceiver songChangeReceiver;
@ -70,7 +59,6 @@ public class MainFragment extends Fragment {
View view = inflater.inflate(R.layout.fragment_main, container, false);
mLocalMusicLinear = view.findViewById(R.id.linear_local_music);
mCollectionLinear = view.findViewById(R.id.linear_collection);
playerBtn = view.findViewById(R.id.btn_player);
mFunctionLinear = view.findViewById(R.id.linear_function);
mHistoryMusicLinear = view.findViewById(R.id.linear_history);
//获取焦点
@ -87,6 +75,17 @@ public class MainFragment extends Fragment {
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//注册广播
intentFilter = new IntentFilter();
intentFilter.addAction(BroadcastName.SONG_CHANGE);
intentFilter.addAction(BroadcastName.COLLECTION_ALBUM_CHANGE);
songChangeReceiver = new SongChangeReceiver();
getActivity().registerReceiver(songChangeReceiver, intentFilter);
showAlbumList();
onClick();
}
private void showAlbumList(){
mLoveAlbumList = new ArrayList<>();
mAlbumCollectionList = new ArrayList<>();
AlbumCollection albumCollection = new AlbumCollection();
@ -97,13 +96,6 @@ public class MainFragment extends Fragment {
mAlbumCollectionList.add(orderCollection(LitePal.findAll(AlbumCollection.class)));
mAdapter = new ExpandableListViewAdapter(getActivity(), mGroupStrings, mAlbumCollectionList);
myListView.setAdapter(mAdapter);
//注册广播
intentFilter = new IntentFilter();
intentFilter.addAction(BroadcastName.SONG_CHANGE);
intentFilter.addAction(BroadcastName.COLLECTION_ALBUM_CHANGE);
songChangeReceiver = new SongChangeReceiver();
getActivity().registerReceiver(songChangeReceiver, intentFilter);
onClick();
}
@Override
@ -116,7 +108,6 @@ public class MainFragment extends Fragment {
public void onResume() {
super.onResume();
showMusicNum();
Log.d(TAG, "onResume: true");
}
private void onClick() {
@ -150,9 +141,7 @@ public class MainFragment extends Fragment {
myListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
if (groupPosition == 0) {
oneExpand = true;
} else if (groupPosition == 1) {
if (groupPosition == 1) {
twoExpand = true;
}
}
@ -160,9 +149,7 @@ public class MainFragment extends Fragment {
myListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
if (groupPosition == 0) {
oneExpand = false;
} else if (groupPosition == 1) {
if (groupPosition == 1) {
twoExpand = false;
}
}
@ -173,13 +160,15 @@ public class MainFragment extends Fragment {
return false;
}
});
//二级列表的item点击效果
mAdapter.setOnChildItemClickListener(new ExpandableListViewAdapter.OnChildItemClickListener() {
@Override
public void onClick(int groupPosition, int childPosition) {
//一级列表的第一个默认为我喜欢的歌单,故点击后跳转到我的收藏界面
if (groupPosition == 0 && childPosition == 0) {
replaceFragment(new CollectionFragment());
} else if (groupPosition == 1) {
//其他的列表都是我的收藏的列表故跳转到专辑详细fragment
AlbumCollection albumCollection = mAlbumCollectionList.get(groupPosition).get(childPosition);
replaceFragment(AlbumContentFragment.newInstance(
albumCollection.getAlbumId(),
@ -207,13 +196,14 @@ public class MainFragment extends Fragment {
transaction.commit();
}
//显示数目
private void showMusicNum() {
mLoveMusicNum.setText("" + LitePal.findAll(LocalSong.class).size());
mLocalMusicNum.setText("" + LitePal.findAll(LocalSong.class).size());
mLoveMusicNum.setText("" + LitePal.findAll(Love.class).size());
mHistoryMusicNum.setText("" + LitePal.findAll(HistorySong.class).size());
}
//使数据库中的列表逆序排列
private List<AlbumCollection> orderCollection(List<AlbumCollection> tempList) {
List<AlbumCollection> mAlbumCollectionList = new ArrayList<>();
for (int i = tempList.size() - 1; i >= 0; i--) {
@ -222,6 +212,7 @@ public class MainFragment extends Fragment {
return mAlbumCollectionList;
}
//收藏和最近播放变化的广播接收器
private class SongChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
@ -232,6 +223,7 @@ public class MainFragment extends Fragment {
mAlbumCollectionList.clear();
mAlbumCollectionList.add(mLoveAlbumList);
mAlbumCollectionList.add(orderCollection(LitePal.findAll(AlbumCollection.class)));
//根据之前的状态,进行展开和收缩,从而达到更新列表的功能
if (twoExpand) {
myListView.collapseGroup(1);
myListView.expandGroup(1);

@ -18,6 +18,7 @@ import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.provider.ContactsContract;
import android.support.annotation.Nullable;
import android.transition.Slide;
import android.util.Log;
@ -52,6 +53,7 @@ import com.example.musicplayer.util.DisplayUtil;
import com.example.musicplayer.util.FastBlurUtil;
import com.example.musicplayer.util.FileHelper;
import com.example.musicplayer.util.MediaUtil;
import com.example.musicplayer.util.RxApiManager;
import com.example.musicplayer.widget.BackgroundAnimationRelativeLayout;
import com.example.musicplayer.widget.DiscView;
@ -59,8 +61,6 @@ import org.litepal.LitePal;
import java.util.List;
import static com.example.musicplayer.view.AlbumSongFragment.IS_ONLINE_ALBUM;
/**
*
*/
@ -80,6 +80,7 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View {
private MediaPlayer mMediaPlayer;
private TextView mSongTv; //
private ImageView mBackIv;
private TextView mSingerTv;
private Button mPlayBtn;
private Button mLastBtn;
@ -111,6 +112,13 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mPlayStatusBinder = (PlayerService.PlayStatusBinder) service;
//缓存进度条
mPlayStatusBinder.getMediaPlayer().setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
mSeekBar.setSecondaryProgress(percent*mSeekBar.getProgress());
}
});
isOnline = FileHelper.getSong().isOnline();
if (isOnline) {
mGetImgAndLrcBtn.setVisibility(View.GONE);
@ -138,7 +146,6 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View {
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (!isChange) {
Log.d(TAG, "handleMessage: send");
mSeekBar.setProgress((int) mPlayStatusBinder.getCurrentTime());
mCurrentTimeTv.setText(MediaUtil.formatTime(mSeekBar.getProgress()));
startUpdateSeekBarProgress();
@ -182,7 +189,7 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View {
mLastBtn = findViewById(R.id.btn_last);
mNextBtn = findViewById(R.id.next);
mGetImgAndLrcBtn = findViewById(R.id.btn_get_img_lrc);
mBackIv = findViewById(R.id.iv_back);
mSeekBar = findViewById(R.id.seek);
mDurationTimeTv = findViewById(R.id.tv_duration_time);
mCurrentTimeTv = findViewById(R.id.tv_current_time);
@ -202,6 +209,7 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View {
mCurrentTimeTv.setText(MediaUtil.formatTime(mSong.getCurrentTime()));
mSeekBar.setMax((int) mSong.getDuration());
mSeekBar.setProgress((int) mSong.getCurrentTime());
mPresenter.queryLove(mSong.getOnlineId()); //查找歌曲是否为我喜欢的歌曲
if (mPlayStatus == PlayerStatus.PLAY) {
@ -258,7 +266,12 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View {
@Override
protected void onClick() {
mBackIv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
mGetImgAndLrcBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -482,6 +495,15 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View {
mPlayBtn.setSelected(true);
mSeekBar.setMax((int) mSong.getDuration());
startUpdateSeekBarProgress();
//缓存进度条
mPlayStatusBinder.getMediaPlayer().setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.d(TAG, "onBufferingUpdate: "+percent);
mSeekBar.setSecondaryProgress(percent*mSeekBar.getProgress());
}
});
mPresenter.queryLove(mSong.getOnlineId()); //查找歌曲是否为我喜欢的歌曲
if (mSong.isOnline()) {
setSingerImg(mSong.getImgUrl());
} else {
@ -541,7 +563,7 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View {
unbindService(connection);
unregisterReceiver(songChangeReceiver);
stopUpdateSeekBarProgress();
RxApiManager.get().cancel(Constant.LOCAL_IMG);
}
}

@ -16,6 +16,8 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.musicplayer.R;
import com.example.musicplayer.adapter.SearchContentAdapter;
@ -29,10 +31,12 @@ import com.example.musicplayer.presenter.SearchContentPresenter;
import com.example.musicplayer.service.PlayerService;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.util.FileHelper;
import com.example.musicplayer.util.RxApiManager;
import com.github.jdsjlzx.interfaces.OnLoadMoreListener;
import com.github.jdsjlzx.interfaces.OnNetWorkErrorListener;
import com.github.jdsjlzx.recyclerview.LRecyclerView;
import com.github.jdsjlzx.recyclerview.LRecyclerViewAdapter;
import com.wang.avi.AVLoadingIndicatorView;
import java.util.ArrayList;
import java.util.List;
@ -49,7 +53,7 @@ public class SearchContentFragment extends Fragment implements ISearchContentCon
private int mOffset = 1; //用于翻页搜索
private String mAlbumName, mSingerName, mAlbumPic, mPublicTime;
private SongFinishReceiver songFinishReceiver;
private SearchContentPresenter mPresenter;
private LRecyclerView mRecycler;
private LinearLayoutManager manager;
@ -59,6 +63,10 @@ public class SearchContentFragment extends Fragment implements ISearchContentCon
private IntentFilter intentFilter;
private LRecyclerViewAdapter mLRecyclerViewAdapter;//下拉刷新
private AVLoadingIndicatorView mLoading;
private TextView mLoadingTv;
private ImageView mBackgroundIv;
private ImageView mNetworkErrorIv;
private Bundle mBundle;
private String mSeek;
@ -89,6 +97,10 @@ public class SearchContentFragment extends Fragment implements ISearchContentCon
}
mRecycler = view.findViewById(R.id.recycler_song_list);
mLoading = view.findViewById(R.id.avi);
mLoadingTv = view.findViewById(R.id.tv_loading);
mBackgroundIv = view.findViewById(R.id.iv_background);
mNetworkErrorIv = view.findViewById(R.id.iv_network_error);
mPresenter = new SearchContentPresenter();
mPresenter.attachView(this);
if (mType.equals("song")) {
@ -110,7 +122,8 @@ public class SearchContentFragment extends Fragment implements ISearchContentCon
intentFilter = new IntentFilter();
intentFilter.addAction(BroadcastName.ONLINE_SONG_FINISH);
intentFilter.addAction(BroadcastName.ONLINE_ALBUM_SONG_Change);
SongFinishReceiver songFinishReceiver = new SongFinishReceiver();
intentFilter.addAction(BroadcastName.ONLINE_SONG_ERROR);
songFinishReceiver = new SongFinishReceiver();
getActivity().registerReceiver(songFinishReceiver, intentFilter);
//启动服务
@ -119,10 +132,21 @@ public class SearchContentFragment extends Fragment implements ISearchContentCon
}
@Override
public void onDestroy() {
super.onDestroy();
getActivity().unbindService(connection);
getActivity().unregisterReceiver(songFinishReceiver);
}
@Override
public void onDestroyView(){
Log.d(TAG, "onDestroyView: true");
RxApiManager.get().cancel(Constant.SEARCH_SONG);
RxApiManager.get().cancel(Constant.SEARCH_ALBUM);
RxApiManager.get().cancel(Constant.SEARCH_ALBUM_MORE);
RxApiManager.get().cancel(Constant.SEARCH_SONG_MORE);
super.onDestroyView();
}
@ -235,6 +259,28 @@ public class SearchContentFragment extends Fragment implements ISearchContentCon
CommonUtil.showToast(getActivity(), "获取专辑信息失败");
}
@Override
public void showLoading() {
mLoading.show();
}
@Override
public void hideLoading() {
mRecycler.setVisibility(View.VISIBLE);
mLoading.hide();
mLoadingTv.setVisibility(View.GONE);
mBackgroundIv.setVisibility(View.GONE);
mNetworkErrorIv.setVisibility(View.GONE);
}
@Override
public void showNetError() {
mRecycler.setVisibility(View.GONE);
mLoading.setVisibility(View.GONE);
mLoadingTv.setVisibility(View.GONE);
mNetworkErrorIv.setVisibility(View.VISIBLE);
}
/**
* fragment
*
@ -254,9 +300,14 @@ public class SearchContentFragment extends Fragment implements ISearchContentCon
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive: " + intent.getAction());
String action = intent.getAction();
if (action.equals(BroadcastName.ONLINE_SONG_ERROR)) {
CommonUtil.showToast(getActivity(), "抱歉该歌曲暂没有版权,搜搜其他歌曲吧");
} else {
mAdapter.notifyDataSetChanged();
}
}
}
public void toAlbumContentFragment(Album.DataBean album) {
FragmentManager manager = getActivity().getSupportFragmentManager();

@ -52,6 +52,9 @@ public class SearchFragment extends Fragment {
public void onClick(View v) {
CommonUtil.closeKeybord(mSeekEdit, getActivity());
mSeekEdit.setCursorVisible(false);//隐藏光标
if(mSeekEdit.getText().toString().trim().length()==0){
mSeekEdit.setText(mSeekEdit.getHint().toString().trim());
}
saveDatabase(mSeekEdit.getText().toString());
replaceFragment(ContentFragment.newInstance(mSeekEdit.getText().toString()));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

@ -3,7 +3,7 @@
<item android:id="@android:id/background">
<shape>
<corners android:radius="3dp"/>
<solid android:color="@color/white"/>
<solid android:color="@color/gray"/>
</shape>
</item>

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="false" android:drawable="@drawable/favorites"/>
<item android:state_selected="true" android:drawable="@drawable/favorites_selected"/>
<item android:drawable="@drawable/favorites"/>
</selector>

@ -48,7 +48,7 @@
android:ellipsize="end"
android:singleLine="true"
android:paddingEnd="20dp"
android:textColor="@color/white_easy" />
android:textColor="@color/white_blue" />
</LinearLayout>
</RelativeLayout>

@ -1,34 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@drawable/welcome"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
android:background="@drawable/welcome"
android:orientation="horizontal">
<TextView
android:id="@+id/music"
android:layout_centerVertical="true"
android:layout_marginStart="50dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:layout_centerVertical="true"
android:layout_marginStart="50dp"
android:ems="1"
android:textStyle="bold"
android:text="@string/welcome"
android:textColor="@color/musicStyle"
android:textSize="30sp"
android:typeface="serif"
android:textColor="@color/musicStyle"/>
android:textStyle="bold"
android:typeface="serif" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/tab"
android:orientation="vertical">
<RelativeLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<ImageView
android:id="@+id/iv_icon"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="@mipmap/icon" />
<TextView
android:layout_marginTop="40dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="@string/welcome"
android:textSize="25sp"
android:textColor="@color/musicStyle"
android:layout_below="@+id/music"/>
android:layout_marginTop="5dp"
android:layout_marginStart="10dp"
android:layout_toRightOf="@+id/iv_icon"
android:text="@string/app_name"
android:textColor="@color/white_blue"
android:textSize="22sp" />
</RelativeLayout>
<TextView
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_below="@+id/iv_icon"
android:textColor="@color/white"
android:textSize="16sp"
android:text="袁健策版权所有@2018"/>
</LinearLayout>
</RelativeLayout>

@ -1,23 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/iv_empty_song"
android:layout_centerInParent="true"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/song_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/empty_song"
android:scaleType="centerCrop"/>
<TextView
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/iv_empty_song"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:text="本地音乐为空,试试点击右上角导入本地歌曲"
android:textColor="@color/white_blue"/>
android:textColor="@color/player"/>
</RelativeLayout>
</FrameLayout>

@ -1,5 +1,6 @@
<?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="match_parent"
android:orientation="vertical">
@ -9,14 +10,58 @@
android:id="@+id/recycler_song_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
android:visibility="gone">
</android.support.v7.widget.RecyclerView>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/translucent" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/avi"
style="@style/AVLoadingIndicatorView.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="180dp"
android:visibility="visible"
app:indicatorColor="@color/musicStyle"
app:indicatorName="LineScaleIndicator" />
<TextView
android:id="@+id/tv_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="150dp"
android:text="加载中,请稍侯"
android:textColor="@color/white_blue"
android:textSize="16sp" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/iv_network_error"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="150dp"
android:scaleType="centerCrop"
android:src="@drawable/network_error"
android:visibility="gone" />
</RelativeLayout>
</FrameLayout>
</LinearLayout>

@ -42,12 +42,11 @@
</RelativeLayout>
<LinearLayout
<View
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="@color/seekColor">
</LinearLayout>
</View>
<RelativeLayout
android:layout_width="match_parent"
@ -63,14 +62,9 @@
</android.support.v7.widget.RecyclerView>
<ViewStub
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/stub_empty"
android:layout="@layout/empty_song"
/>
<include layout="@layout/empty_song"
android:id="@+id/linear_empty"/>
</RelativeLayout>
</LinearLayout>

@ -38,6 +38,7 @@
android:focusable="true"
android:focusableInTouchMode="true"
android:paddingStart="15dp"
android:hint="周杰伦"
android:textColor="@color/white"
android:textSize="16sp" />

@ -1,17 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_marginBottom="65dp"
android:src="@color/translucent"/>
<com.github.jdsjlzx.recyclerview.LRecyclerView
android:id="@+id/recycler_song_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="65dp">
android:layout_marginBottom="65dp"
android:visibility="gone">
</com.github.jdsjlzx.recyclerview.LRecyclerView>
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/avi"
style="@style/AVLoadingIndicatorView.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="visible"
app:indicatorColor="@color/musicStyle"
app:indicatorName="LineScaleIndicator" />
<TextView
android:id="@+id/tv_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/avi"
android:layout_centerHorizontal="true"
android:text="加载中,请稍侯"
android:textColor="@color/white_blue"
android:textSize="16sp"/>
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/iv_network_error"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginTop="130dp"
android:visibility="gone"
android:layout_centerHorizontal="true"
android:src="@drawable/network_error"
android:scaleType="centerCrop"
/>
</RelativeLayout>
</LinearLayout>
</FrameLayout>

@ -47,7 +47,7 @@
android:ellipsize="end"
android:maxEms="15"
android:singleLine="true"
android:textColor="@color/short_white"
android:textColor="@color/white_blue"
android:textSize="14sp"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

@ -12,12 +12,13 @@
<color name="seekColor">#80FFFFFF</color>
<color name="translucent">#80010738</color>
<color name="click">#99010738</color>
<color name="click">#80010733</color>
<color name="tab">#2e3259</color>
<color name="actionBarColor">#0f1934</color>
<color name="transparent">#00000000</color>
<color name="musicStyle_low">#2ad3df</color>
<color name="player">#161e31</color>
<color name="black">#000</color>
<color name="white_easy">#bcb9b9</color>
<color name="yellow">#FFC66D</color>
<color name="white_blue">#caeefc</color>

@ -10,7 +10,7 @@
<string name="song_list">自建歌单</string>
<string name="love">我喜欢</string>
<string name="collection_start">默认收藏</string>
<string name="welcome">人生几何对酒当歌</string>
<string name="welcome">人生几何,对酒当歌</string>
<string name="search">搜索</string>
<string name="delete_all_history">清空搜索历史</string>
<string name="cancel">取消</string>

Loading…
Cancel
Save