From 733250899f892b4263ec921a303cff719ed49214 Mon Sep 17 00:00:00 2001 From: jsyjst Date: Sat, 1 Dec 2018 00:34:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=88=91=E7=9A=84=E6=94=B6?= =?UTF-8?q?=E8=97=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/litepal.xml | 3 +- .../musicplayer/adapter/LoveSongAdapter.java | 137 +++++++++++++++++ .../musicplayer/adapter/SongAdapter.java | 10 +- .../musicplayer/constant/BroadcastName.java | 1 + .../musicplayer/constant/Constant.java | 1 + .../musicplayer/contract/IPlayContract.java | 15 +- .../example/musicplayer/entiy/LocalSong.java | 9 ++ .../com/example/musicplayer/entiy/Love.java | 75 +++++++++ .../com/example/musicplayer/entiy/Song.java | 12 +- .../example/musicplayer/model/IPlayModel.java | 60 ++++++++ .../musicplayer/model/LocalMusicModel.java | 5 + .../musicplayer/presenter/PlayPresenter.java | 30 ++++ .../musicplayer/service/PlayerService.java | 85 +++++++--- .../musicplayer/view/AlbumSongFragment.java | 2 +- .../musicplayer/view/CollectionFragment.java | 145 ++++++++++++++++++ .../musicplayer/view/LocalMusicFragment.java | 3 - .../musicplayer/view/MainActivity.java | 7 +- .../musicplayer/view/MainFragment.java | 43 ++++-- .../musicplayer/view/PlayActivity.java | 75 +++++++-- .../view/SearchHistoryFragment.java | 27 +++- .../musicplayer/widget/DeleteDialog.java | 84 ++++++++++ app/src/main/res/animator/favorites_anim.xml | 17 ++ .../main/res/drawable-xxhdpi/favorites.png | Bin 0 -> 1522 bytes .../drawable-xxhdpi/favorites_selected.png | Bin 0 -> 2184 bytes app/src/main/res/drawable/dialog_bg.xml | 8 + app/src/main/res/drawable/empty_song.png | Bin 0 -> 7884 bytes app/src/main/res/drawable/love.xml | 6 + app/src/main/res/layout/activity_play.xml | 10 ++ .../main/res/layout/dialog_delete_photo.xml | 62 ++++++++ .../main/res/layout/fragment_local_music.xml | 1 + .../main/res/layout/fragment_love_music.xml | 86 +++++++++++ .../res/layout/fragment_search_history.xml | 2 +- app/src/main/res/layout/function.xml | 6 +- .../res/layout/recycler_seek_history_item.xml | 4 +- app/src/main/res/values/strings.xml | 2 + app/src/main/res/values/styles.xml | 8 +- 36 files changed, 957 insertions(+), 84 deletions(-) create mode 100644 app/src/main/java/com/example/musicplayer/adapter/LoveSongAdapter.java create mode 100644 app/src/main/java/com/example/musicplayer/entiy/Love.java create mode 100644 app/src/main/java/com/example/musicplayer/view/CollectionFragment.java create mode 100644 app/src/main/java/com/example/musicplayer/widget/DeleteDialog.java create mode 100644 app/src/main/res/animator/favorites_anim.xml create mode 100644 app/src/main/res/drawable-xxhdpi/favorites.png create mode 100644 app/src/main/res/drawable-xxhdpi/favorites_selected.png create mode 100644 app/src/main/res/drawable/dialog_bg.xml create mode 100644 app/src/main/res/drawable/empty_song.png create mode 100644 app/src/main/res/drawable/love.xml create mode 100644 app/src/main/res/layout/dialog_delete_photo.xml create mode 100644 app/src/main/res/layout/fragment_love_music.xml diff --git a/app/src/main/assets/litepal.xml b/app/src/main/assets/litepal.xml index d5df70e..0a86e7f 100644 --- a/app/src/main/assets/litepal.xml +++ b/app/src/main/assets/litepal.xml @@ -2,11 +2,12 @@ - + + \ No newline at end of file diff --git a/app/src/main/java/com/example/musicplayer/adapter/LoveSongAdapter.java b/app/src/main/java/com/example/musicplayer/adapter/LoveSongAdapter.java new file mode 100644 index 0000000..ae77e5c --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/adapter/LoveSongAdapter.java @@ -0,0 +1,137 @@ +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.example.musicplayer.R; +import com.example.musicplayer.entiy.Love; +import com.example.musicplayer.util.FileHelper; + +import java.util.List; + +/** + * Created by 残渊 on 2018/11/30. + */ + +public class LoveSongAdapter extends RecyclerView.Adapter { + private static final String TAG = "LoveSongAdapter"; + private int footerViewType = 1; + private int itemViewType = 0; + private List mLoveList; + private Context mContext; + private int mLastPosition = -1; + private OnItemClickListener onItemClickListener; + + public void setOnItemClickListener(OnItemClickListener onItemClickListener) { + this.onItemClickListener = onItemClickListener; + } + + public LoveSongAdapter(Context context, List loveList) { + mContext = context; + mLoveList = loveList; + } + + + class ViewHolder extends RecyclerView.ViewHolder { + TextView songNameTv; + TextView singerTv; + View mItemView; + View playLine; + + 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); + mItemView = itemView; + } + } + + /** + * 底部holder + */ + static class FooterHolder extends RecyclerView.ViewHolder { + + TextView numTv; + + public FooterHolder(View itemView) { + super(itemView); + numTv = itemView.findViewById(R.id.tv_song_num); + } + } + + @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(RecyclerView.ViewHolder viewHolder, final int position) { + if (viewHolder instanceof ViewHolder) { + ViewHolder holder = (ViewHolder) viewHolder; + final Love love = mLoveList.get(position); + + holder.songNameTv.setText(love.getName()); + holder.singerTv.setText(love.getSinger()); + //根据点击显示 + if(love.getSongId().equals(FileHelper.getSong().getOnlineId())){ + holder.playLine.setVisibility(View.VISIBLE); + mLastPosition =position; + holder.mItemView.setBackgroundResource(R.color.click); + }else { + holder.playLine.setVisibility(View.INVISIBLE); + holder.mItemView.setBackgroundResource(R.color.transparent); + } + holder.mItemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onItemClickListener.onSongClick(position); + equalPosition(position); + } + }); + } else { + FooterHolder footerHolder = (FooterHolder) viewHolder; + footerHolder.numTv.setText("共" + mLoveList.size() + "首音乐"); + } + } + + //判断点击的是否为上一个点击的项目 + public void equalPosition(int position) { + if (position != mLastPosition) { + notifyItemChanged(mLastPosition); + mLastPosition = position; + } + notifyItemChanged(position); + } + + @Override + public int getItemCount() { + return mLoveList.size() + 1; + } + + @Override + public int getItemViewType(int position) { + return position + 1 == getItemCount() ? footerViewType : itemViewType; + } + + + public interface OnItemClickListener { + void onSongClick(int position); + } + +} diff --git a/app/src/main/java/com/example/musicplayer/adapter/SongAdapter.java b/app/src/main/java/com/example/musicplayer/adapter/SongAdapter.java index 12343fa..069d475 100644 --- a/app/src/main/java/com/example/musicplayer/adapter/SongAdapter.java +++ b/app/src/main/java/com/example/musicplayer/adapter/SongAdapter.java @@ -9,6 +9,7 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import com.example.musicplayer.constant.Constant; import com.example.musicplayer.constant.MyApplication; import com.example.musicplayer.entiy.Song; import com.example.musicplayer.R; @@ -73,10 +74,6 @@ public class SongAdapter extends RecyclerView.Adapter { if (viewType == itemViewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.recycler_song_item, parent, false); -// TypedValue typedValue = new TypedValue(); -// mContext.getTheme().resolveAttribute(R.attr.selectableItemBackground, typedValue, true); -// view.setBackgroundResource(typedValue.resourceId); - ViewHolder viewHolder = new ViewHolder(view); return viewHolder; } else { @@ -123,6 +120,8 @@ public class SongAdapter extends RecyclerView.Adapter { song.setDuration(mp3Info.getDuration()); song.setCurrent(position); song.setOnline(false); + song.setOnlineId(mp3Info.getSongId()); + song.setListType(Constant.LIST_TYPE_LOCAL); FileHelper.saveSong(song); onItemClickListener.onSongClick(); @@ -131,7 +130,8 @@ public class SongAdapter extends RecyclerView.Adapter { }); } else { FooterHolder footerHolder = (FooterHolder) viewHolder; - footerHolder.numTv.setText("共" + mMp3InfoList.size() + "首音乐"); + int num=mMp3InfoList.size()-1; + footerHolder.numTv.setText("共" + num + "首音乐"); } } diff --git a/app/src/main/java/com/example/musicplayer/constant/BroadcastName.java b/app/src/main/java/com/example/musicplayer/constant/BroadcastName.java index 16c75d7..c988ced 100644 --- a/app/src/main/java/com/example/musicplayer/constant/BroadcastName.java +++ b/app/src/main/java/com/example/musicplayer/constant/BroadcastName.java @@ -13,5 +13,6 @@ public class BroadcastName { public static final String SONG_RESUME="song_resume"; public static final String ONLINE_SONG_ERROR="online_song_error"; public static final String ONLINE_ALBUM_SONG_Change="online_album_song_change"; + public static final String LOVE_SONG_CHANGE="love_song_change"; } diff --git a/app/src/main/java/com/example/musicplayer/constant/Constant.java b/app/src/main/java/com/example/musicplayer/constant/Constant.java index 34110c0..82462ca 100644 --- a/app/src/main/java/com/example/musicplayer/constant/Constant.java +++ b/app/src/main/java/com/example/musicplayer/constant/Constant.java @@ -11,4 +11,5 @@ public class Constant { public static final int TYPE_ALBUM_SONG=3; public static final int LIST_TYPE_LOCAL=4; public static final int LIST_TYPE_ONLINE=5; + public static final int LIST_TYPE_LOVE=6; } diff --git a/app/src/main/java/com/example/musicplayer/contract/IPlayContract.java b/app/src/main/java/com/example/musicplayer/contract/IPlayContract.java index 25325ad..3a14362 100644 --- a/app/src/main/java/com/example/musicplayer/contract/IPlayContract.java +++ b/app/src/main/java/com/example/musicplayer/contract/IPlayContract.java @@ -1,5 +1,8 @@ package com.example.musicplayer.contract; +import com.example.musicplayer.entiy.Love; +import com.example.musicplayer.entiy.Song; + /** * Created by 残渊 on 2018/10/26. */ @@ -7,17 +10,27 @@ package com.example.musicplayer.contract; public interface IPlayContract { interface Model{ void getSingerImg(String singer);//网络请求获得歌手uri + void queryLove(String songId);//查询我喜欢的数据库中有没这首歌 + void saveToLove(Song song); //添加到我喜欢的表 + void deleteFromLove(String songId); //从我喜欢的表中移除 } interface View{ String getSingerName(); //得到歌手的姓名 void getSingerAndLrc();//按钮点击事件,获取封面和歌词 void setSingerImg(String ImgUrl); //将图片设置成背景 void setImgFail(String errorMessage); - void setSearchImg();//设置搜索歌曲的图片 + void showLove(boolean love); //判断是否显示我喜欢的图标 + void showLoveAnim(); //喜欢的动画 + void saveToLoveSuccess();//保存到我喜欢数据库成功 } interface Presenter{ void getSingerImg(String singer); void getSingerImgSuccess(String ImgUrl); //成功获取图片 void getSingerImgFail(); //请求失败 + void queryLove(String songId);//查询我喜欢的数据库中有没这首歌 + void saveToLove(Song song); //添加到我喜欢的表 + void deleteFromLove(String songId); //从我喜欢的表中移除 + void saveToLoveSuccess();//保存到我喜欢数据库成功 + void showLove(boolean love); //判断是否显示我喜欢的图标 } } diff --git a/app/src/main/java/com/example/musicplayer/entiy/LocalSong.java b/app/src/main/java/com/example/musicplayer/entiy/LocalSong.java index 3dba1df..f83121d 100644 --- a/app/src/main/java/com/example/musicplayer/entiy/LocalSong.java +++ b/app/src/main/java/com/example/musicplayer/entiy/LocalSong.java @@ -9,6 +9,7 @@ import org.litepal.crud.LitePalSupport; public class LocalSong extends LitePalSupport{ private int id; + private String songId; private String name; private String singer; private String url; @@ -63,4 +64,12 @@ public class LocalSong extends LitePalSupport{ public long getDuration() { return duration; } + + public void setSongId(String songId) { + this.songId = songId; + } + + public String getSongId() { + return songId; + } } diff --git a/app/src/main/java/com/example/musicplayer/entiy/Love.java b/app/src/main/java/com/example/musicplayer/entiy/Love.java new file mode 100644 index 0000000..18f045d --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/entiy/Love.java @@ -0,0 +1,75 @@ +package com.example.musicplayer.entiy; + +import org.litepal.crud.LitePalSupport; + +/** + * Created by 残渊 on 2018/11/30. + */ + +public class Love extends LitePalSupport{ + private int id; + private String songId; + private String name; + private String singer; + private String url; + private String pic; + private boolean isOnline; + + + 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 String getSongId() { + return songId; + } + + public void setSongId(String songId) { + this.songId = songId; + } + + public void setOnline(boolean online) { + isOnline = online; + } + + public boolean isOnline() { + return isOnline; + } +} diff --git a/app/src/main/java/com/example/musicplayer/entiy/Song.java b/app/src/main/java/com/example/musicplayer/entiy/Song.java index 6548de2..7c7d637 100644 --- a/app/src/main/java/com/example/musicplayer/entiy/Song.java +++ b/app/src/main/java/com/example/musicplayer/entiy/Song.java @@ -18,7 +18,7 @@ public class Song implements Serializable { private int current;//在本地音乐的位置 private String imgUrl; private boolean isOnline; - private boolean isOnlineAlbum; + private int listType; public String getImgUrl() { return imgUrl; @@ -84,12 +84,12 @@ public class Song implements Serializable { isOnline = online; } - public boolean isOnlineAlbum() { - return isOnlineAlbum; + public int getListType() { + return listType; } - public void setOnlineAlbum(boolean onlineAlbum) { - isOnlineAlbum = onlineAlbum; + public void setListType(int listType) { + this.listType = listType; } public String getOnlineId() { @@ -103,7 +103,7 @@ public class Song implements Serializable { public String toString(){ return "songName="+songName+",singer="+singer+",url="+url+",imgUrl="+imgUrl +",duration="+duration+",currentTime="+currentTime+",current="+current - +",onlineId="+onlineId+",isOnline="+isOnline+",isOnlineAlbum="+isOnlineAlbum; + +",onlineId="+onlineId+",isOnline="+isOnline+",listType="+listType; } } diff --git a/app/src/main/java/com/example/musicplayer/model/IPlayModel.java b/app/src/main/java/com/example/musicplayer/model/IPlayModel.java index 221e3ce..b12d765 100644 --- a/app/src/main/java/com/example/musicplayer/model/IPlayModel.java +++ b/app/src/main/java/com/example/musicplayer/model/IPlayModel.java @@ -4,10 +4,17 @@ import android.support.annotation.MainThread; import android.util.Log; 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 org.litepal.LitePal; +import org.litepal.crud.callback.FindMultiCallback; +import org.litepal.crud.callback.SaveCallback; + import java.io.IOException; +import java.util.List; import io.reactivex.Observer; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -63,4 +70,57 @@ public class IPlayModel implements IPlayContract.Model { } }); } + + @Override + public void queryLove(final String songId) { + new Thread(new Runnable() { + @Override + public void run() { + LitePal.where("songId=?",songId).findAsync(Love.class).listen(new FindMultiCallback() { + @Override + public void onFinish(List list) { + if(list.size()==0){ + mPresenter.showLove(false); + }else{ + mPresenter.showLove(true); + } + } + }); + } + }).start(); + } + + @Override + public void saveToLove(final Song song) { + new Thread(new Runnable() { + @Override + public void run() { + Love love =new Love(); + love.setName(song.getSongName()); + love.setSinger(song.getSinger()); + love.setUrl(song.getUrl()); + love.setPic(song.getImgUrl()); + love.setSongId(song.getOnlineId()); + love.setOnline(song.isOnline()); + love.saveAsync().listen(new SaveCallback() { + @Override + public void onFinish(boolean success) { + if(success){ + mPresenter.saveToLoveSuccess(); + } + } + }); + } + }).start(); + } + + @Override + public void deleteFromLove(final String songId) { + new Thread(new Runnable() { + @Override + public void run() { + LitePal.deleteAll("songId=?",songId); + } + }).start(); + } } diff --git a/app/src/main/java/com/example/musicplayer/model/LocalMusicModel.java b/app/src/main/java/com/example/musicplayer/model/LocalMusicModel.java index 5c7758a..77c234c 100644 --- a/app/src/main/java/com/example/musicplayer/model/LocalMusicModel.java +++ b/app/src/main/java/com/example/musicplayer/model/LocalMusicModel.java @@ -2,6 +2,7 @@ package com.example.musicplayer.model; import android.database.Cursor; import android.provider.MediaStore; +import android.util.Log; import com.example.musicplayer.constant.MyApplication; import com.example.musicplayer.contract.ILocalMusicContract; @@ -18,6 +19,7 @@ import java.util.List; */ public class LocalMusicModel implements ILocalMusicContract.Model { + private static final String TAG="LocalMusicModel"; private ILocalMusicContract.Presenter mPresenter; @@ -65,6 +67,8 @@ public class LocalMusicModel implements ILocalMusicContract.Model { mp3Info.setSinger(artist); mp3Info.setDuration(duration); mp3Info.setUrl(url); + mp3Info.setSongId(String.valueOf(id)); + Log.d(TAG, "run: "+mp3Info.getSongId()); mp3InfoList.add(mp3Info); } } @@ -88,6 +92,7 @@ public class LocalMusicModel implements ILocalMusicContract.Model { song.setSinger(localSong.getSinger()); song.setUrl(localSong.getUrl()); song.setDuration(localSong.getDuration()); + song.setSongId(localSong.getSongId()); song.save(); } } diff --git a/app/src/main/java/com/example/musicplayer/presenter/PlayPresenter.java b/app/src/main/java/com/example/musicplayer/presenter/PlayPresenter.java index ca6a13a..ddc1813 100644 --- a/app/src/main/java/com/example/musicplayer/presenter/PlayPresenter.java +++ b/app/src/main/java/com/example/musicplayer/presenter/PlayPresenter.java @@ -2,6 +2,7 @@ package com.example.musicplayer.presenter; import com.example.musicplayer.base.BasePresenter; import com.example.musicplayer.contract.IPlayContract; +import com.example.musicplayer.entiy.Song; import com.example.musicplayer.model.IPlayModel; /** @@ -34,4 +35,33 @@ public class PlayPresenter extends BasePresenter implements getMvpView().setImgFail("获取歌手照片失败"); } } + + @Override + public void queryLove(String songId) { + mModel.queryLove(songId); + } + + @Override + public void saveToLove(Song song) { + mModel.saveToLove(song); + } + + @Override + public void deleteFromLove(String songId) { + mModel.deleteFromLove(songId); + } + + @Override + public void saveToLoveSuccess() { + if(isAttachView()){ + getMvpView().saveToLoveSuccess(); + } + } + + @Override + public void showLove(boolean love) { + if(isAttachView()){ + getMvpView().showLove(love); + } + } } diff --git a/app/src/main/java/com/example/musicplayer/service/PlayerService.java b/app/src/main/java/com/example/musicplayer/service/PlayerService.java index 9d8ddee..c3be26b 100644 --- a/app/src/main/java/com/example/musicplayer/service/PlayerService.java +++ b/app/src/main/java/com/example/musicplayer/service/PlayerService.java @@ -4,6 +4,7 @@ import android.annotation.SuppressLint; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; +import android.net.ConnectivityManager; import android.os.Binder; import android.os.IBinder; import android.util.Log; @@ -11,6 +12,7 @@ import android.util.Log; import com.example.musicplayer.constant.BroadcastName; import com.example.musicplayer.constant.Constant; import com.example.musicplayer.entiy.LocalSong; +import com.example.musicplayer.entiy.Love; import com.example.musicplayer.entiy.OnlineSong; import com.example.musicplayer.entiy.Song; import com.example.musicplayer.util.FileHelper; @@ -28,10 +30,10 @@ public class PlayerService extends Service { private PlayStatusBinder mPlayStatusBinder = new PlayStatusBinder(); private MediaPlayer mediaPlayer = new MediaPlayer(); //媒体播放器对象 private boolean isPause; //暂停状态 - private Song song; private boolean isPlaying; //是否播放 private List mLocalSongList; private List mSongList; + private List mLoveList; private int mCurrent; private int mListType; @@ -60,7 +62,7 @@ public class PlayerService extends Service { } else { mPlayStatusBinder.stop(); } - } else { + } else if(mListType == Constant.LIST_TYPE_ONLINE){ saveOnlineSongInfo(mCurrent); if (mCurrent <= mSongList.size()) { mPlayStatusBinder.play(Constant.LIST_TYPE_ONLINE); @@ -69,8 +71,15 @@ public class PlayerService extends Service { mPlayStatusBinder.stop(); } + } else { + saveLoveInfo(mCurrent,FileHelper.getSong().isOnline()); + if (mCurrent <= mLoveList.size()) { + mPlayStatusBinder.play(Constant.LIST_TYPE_LOVE); + sendBroadcast(new Intent(BroadcastName.LOVE_SONG_CHANGE));//专辑列表的改变 + } else { + mPlayStatusBinder.stop(); + } } - sendBroadcast(new Intent(BroadcastName.SONG_CHANGE)); //发送广播改变播放栏的信息 sendBroadcast(new Intent(BroadcastName.ONLINE_SONG_FINISH));//发送网络歌曲播放结束的广播改变网络搜索列表的改变 } }); @@ -90,15 +99,6 @@ public class PlayerService extends Service { } public class PlayStatusBinder extends Binder { - //确认播放列表的类型 - public void setListType(int listType) { - mListType = listType; - if (mListType == Constant.LIST_TYPE_ONLINE) { - mSongList = LitePal.findAll(OnlineSong.class); - } else if (mListType == Constant.LIST_TYPE_LOCAL) { - mLocalSongList = LitePal.findAll(LocalSong.class); - } - } /** @@ -115,13 +115,17 @@ public class PlayerService extends Service { mSongList = LitePal.findAll(OnlineSong.class); } else if (mListType == Constant.LIST_TYPE_LOCAL) { mLocalSongList = LitePal.findAll(LocalSong.class); + }else if(mListType == Constant.LIST_TYPE_LOVE){ + mLoveList = orderList(LitePal.findAll(Love.class)); } mCurrent = FileHelper.getSong().getCurrent(); mediaPlayer.reset();//把各项参数恢复到初始状态 if (mListType == Constant.LIST_TYPE_LOCAL) { mediaPlayer.setDataSource(mLocalSongList.get(mCurrent).getUrl()); - } else { + } else if(mListType == Constant.LIST_TYPE_ONLINE){ mediaPlayer.setDataSource(mSongList.get(mCurrent).getUrl()); + } else{ + mediaPlayer.setDataSource(mLoveList.get(mCurrent).getUrl()); } mediaPlayer.prepare(); //进行缓冲 isPlaying = true; @@ -185,16 +189,21 @@ public class PlayerService extends Service { saveLocalSongInfo(mCurrent); mPlayStatusBinder.play(Constant.LIST_TYPE_LOCAL); sendBroadcast(new Intent(BroadcastName.LOCAL_SONG_CHANGE_LIST));//发送广播改变当地列表的显示 - } else { + } else if(mListType == Constant.LIST_TYPE_ONLINE){ if (mCurrent >= mSongList.size()) { mCurrent = 0; } saveOnlineSongInfo(mCurrent); mPlayStatusBinder.play(Constant.LIST_TYPE_ONLINE); sendBroadcast(new Intent(BroadcastName.ONLINE_ALBUM_SONG_Change));//专辑列表的改变 + } else{ + if (mCurrent >= mLoveList.size()) { + mCurrent = 0; + } + saveLoveInfo(mCurrent,FileHelper.getSong().isOnline()); + mPlayStatusBinder.play(Constant.LIST_TYPE_LOVE); + sendBroadcast(new Intent(BroadcastName.LOVE_SONG_CHANGE)); } - - sendBroadcast(new Intent(BroadcastName.SONG_CHANGE)); //发送广播改变播放栏的信息 sendBroadcast(new Intent(BroadcastName.ONLINE_SONG_FINISH));//发送网络歌曲播放结束的广播改变网络搜索列表的改变 } @@ -202,18 +211,27 @@ public class PlayerService extends Service { mCurrent = FileHelper.getSong().getCurrent(); mCurrent--; if (mCurrent == -1) { - mCurrent = mListType == Constant.LIST_TYPE_LOCAL ? mLocalSongList.size() - 1 : mSongList.size() - 1; + if(mListType == Constant.LIST_TYPE_LOCAL){ + mCurrent = mLocalSongList.size()-1; + }else if(mListType ==Constant.LIST_TYPE_ONLINE){ + mCurrent =mSongList.size()-1; + }else { + mCurrent = mLoveList.size()-1; + } } if (mListType == Constant.LIST_TYPE_LOCAL) { saveLocalSongInfo(mCurrent); - mPlayStatusBinder.play(Constant.LIST_TYPE_LOCAL); + mPlayStatusBinder.play(mListType); sendBroadcast(new Intent(BroadcastName.LOCAL_SONG_CHANGE_LIST));//发送广播改变当地列表的显示 - } else { + } else if(mListType == Constant.LIST_TYPE_ONLINE){ saveOnlineSongInfo(mCurrent); - mPlayStatusBinder.play(Constant.LIST_TYPE_ONLINE); + mPlayStatusBinder.play(mListType); sendBroadcast(new Intent(BroadcastName.ONLINE_ALBUM_SONG_Change));//专辑列表的改变 + } else{ + saveLoveInfo(mCurrent,FileHelper.getSong().isOnline()); + mPlayStatusBinder.play(mListType); + sendBroadcast(new Intent(BroadcastName.LOVE_SONG_CHANGE)); } - sendBroadcast(new Intent(BroadcastName.SONG_CHANGE)); //发送广播改变播放栏的信息 sendBroadcast(new Intent(BroadcastName.ONLINE_SONG_FINISH));//发送网络歌曲播放结束的广播改变网络搜索列表的改变 } @@ -296,7 +314,7 @@ public class PlayerService extends Service { song.setDuration(localSong.getDuration()); song.setUrl(localSong.getUrl()); song.setOnline(false); - song.setOnlineAlbum(false); + song.setListType(Constant.LIST_TYPE_LOCAL); FileHelper.saveSong(song); } @@ -311,9 +329,30 @@ public class PlayerService extends Service { song.setUrl(mSongList.get(current).getUrl()); song.setImgUrl(mSongList.get(current).getPic()); song.setOnline(true); - song.setOnlineAlbum(true); + song.setListType(Constant.LIST_TYPE_ONLINE); FileHelper.saveSong(song); } + private void saveLoveInfo(int current,boolean isOnline){ + mLoveList = orderList(LitePal.findAll(Love.class)); + Love love = mLoveList.get(current); + Song song = new Song(); + song.setCurrent(current); + song.setOnlineId(love.getSongId()); + song.setSongName(love.getName()); + song.setSinger(love.getSinger()); + song.setUrl(love.getUrl()); + song.setImgUrl(love.getPic()); + song.setListType(Constant.LIST_TYPE_LOVE); + song.setOnline(isOnline); + } + private List orderList(List tempList){ + List loveList=new ArrayList<>(); + loveList.clear(); + for(int i=tempList.size()-1;i>=0;i--){ + loveList.add(tempList.get(i)); + } + return loveList; + } } diff --git a/app/src/main/java/com/example/musicplayer/view/AlbumSongFragment.java b/app/src/main/java/com/example/musicplayer/view/AlbumSongFragment.java index 972c694..a4a57d8 100644 --- a/app/src/main/java/com/example/musicplayer/view/AlbumSongFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/AlbumSongFragment.java @@ -167,7 +167,7 @@ public class AlbumSongFragment extends Fragment implements IAlbumSongContract.Vi song.setImgUrl(dataBean.getPic()); song.setCurrent(position); song.setOnline(true); - song.setOnlineAlbum(true); + song.setListType(Constant.LIST_TYPE_ONLINE); FileHelper.saveSong(song); mPlayStatusBinder.play(Constant.LIST_TYPE_ONLINE); diff --git a/app/src/main/java/com/example/musicplayer/view/CollectionFragment.java b/app/src/main/java/com/example/musicplayer/view/CollectionFragment.java new file mode 100644 index 0000000..58754b2 --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/view/CollectionFragment.java @@ -0,0 +1,145 @@ +package com.example.musicplayer.view; + + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.os.Bundle; +import android.os.IBinder; +import android.support.v4.app.Fragment; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; + +import com.example.musicplayer.R; +import com.example.musicplayer.adapter.LoveSongAdapter; +import com.example.musicplayer.adapter.SongAdapter; +import com.example.musicplayer.constant.BroadcastName; +import com.example.musicplayer.constant.Constant; +import com.example.musicplayer.entiy.LocalSong; +import com.example.musicplayer.entiy.Love; +import com.example.musicplayer.entiy.Song; +import com.example.musicplayer.service.PlayerService; +import com.example.musicplayer.util.FileHelper; + +import org.litepal.LitePal; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by 残渊 on 2018/11/30. + */ + +public class CollectionFragment extends Fragment { + private RecyclerView mRecycler; + private ImageView mBackIv; + private LinearLayoutManager mManager; + private LoveSongAdapter mAdapter; + private LinearLayout mSongListLinear; + private RelativeLayout mEmptyRelative; + private List mLoveList; + private List mTempList; + + //注册广播 + private IntentFilter intentFilter; + private SongChangeReceiver songChangeReceiver; + + 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) { + + } + }; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View mView = inflater.inflate(R.layout.fragment_love_music, container, false); + mRecycler = mView.findViewById(R.id.recycler_love_songs); + mBackIv = mView.findViewById(R.id.iv_back); + mEmptyRelative = mView.findViewById(R.id.relative_empty); + mSongListLinear = mView.findViewById(R.id.linear_song_list); + mTempList =new ArrayList<>(); + mLoveList = new ArrayList<>(); + return mView; + } + @Override + public void onActivityCreated(Bundle savedInstanceState){ + super.onActivityCreated(savedInstanceState); + //启动服务 + Intent playIntent = new Intent(getActivity(), PlayerService.class); + getActivity().bindService(playIntent, connection, Context.BIND_AUTO_CREATE); + //注册广播 + intentFilter=new IntentFilter(); + intentFilter.addAction(BroadcastName.LOVE_SONG_CHANGE); + songChangeReceiver=new SongChangeReceiver(); + getActivity().registerReceiver(songChangeReceiver,intentFilter); + showSongList(); + onClick(); + } + + + private void showSongList(){ + mLoveList.clear(); + mTempList = LitePal.findAll(Love.class); + if(mTempList.size()==0){ + mEmptyRelative.setVisibility(View.VISIBLE); + mSongListLinear.setVisibility(View.GONE); + }else{ + mEmptyRelative.setVisibility(View.GONE); + mSongListLinear.setVisibility(View.VISIBLE); + } + //对数据库的数据倒序显示 + for(int i=mTempList.size()-1;i>=0;i--){ + mLoveList.add(mTempList.get(i)); + } + mAdapter = new LoveSongAdapter(getActivity(),mLoveList); + mManager = new LinearLayoutManager(getActivity()); + mRecycler.setLayoutManager(mManager); + mRecycler.setAdapter(mAdapter); + } + private void onClick(){ + mAdapter.setOnItemClickListener(new LoveSongAdapter.OnItemClickListener() { + @Override + public void onSongClick(int position) { + Love love = mLoveList.get(position); + Song song =new Song(); + song.setOnlineId(love.getSongId()); + song.setSongName(love.getName()); + song.setSinger(love.getSinger()); + song.setOnline(love.isOnline()); + song.setUrl(love.getUrl()); + song.setImgUrl(love.getPic()); + song.setCurrent(position); + song.setListType(Constant.LIST_TYPE_LOVE); + FileHelper.saveSong(song); + + mPlayStatusBinder.play(Constant.LIST_TYPE_LOVE); + } + }); + } + private class SongChangeReceiver extends BroadcastReceiver{ + @Override + public void onReceive(Context context, Intent intent) { + mAdapter.notifyDataSetChanged(); + if(FileHelper.getSong()!=null) { + mManager.scrollToPositionWithOffset(FileHelper.getSong().getCurrent()+4, mRecycler.getHeight()); + } + } + } +} diff --git a/app/src/main/java/com/example/musicplayer/view/LocalMusicFragment.java b/app/src/main/java/com/example/musicplayer/view/LocalMusicFragment.java index 25b3aa7..c6082d7 100644 --- a/app/src/main/java/com/example/musicplayer/view/LocalMusicFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/LocalMusicFragment.java @@ -55,9 +55,6 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract. private ImageView mBackIv; private ViewStub mEmptyViewStub; - - - private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { diff --git a/app/src/main/java/com/example/musicplayer/view/MainActivity.java b/app/src/main/java/com/example/musicplayer/view/MainActivity.java index bc9b427..de4748d 100644 --- a/app/src/main/java/com/example/musicplayer/view/MainActivity.java +++ b/app/src/main/java/com/example/musicplayer/view/MainActivity.java @@ -90,6 +90,7 @@ public class MainActivity extends AppCompatActivity { intentFilter.addAction(BroadcastName.ONLINE_ALBUM_SONG_Change); songChangeReceiver = new SongChangeReceiver(); registerReceiver(songChangeReceiver, intentFilter); + LitePal.getDatabase(); initView(); onClick(); @@ -196,10 +197,8 @@ public class MainActivity extends AppCompatActivity { } else { if (FileHelper.getSong().isOnline()) { mPlayStatusBinder.playOnline(); - } else if(FileHelper.getSong().isOnlineAlbum()){ - mPlayStatusBinder.play(Constant.LIST_TYPE_ONLINE); - }else{ - mPlayStatusBinder.play(Constant.LIST_TYPE_LOCAL); + } else{ + mPlayStatusBinder.play(FileHelper.getSong().getListType()); } mMediaPlayer.seekTo((int) mSong.getCurrentTime()); mCircleAnimator.start(); diff --git a/app/src/main/java/com/example/musicplayer/view/MainFragment.java b/app/src/main/java/com/example/musicplayer/view/MainFragment.java index 4ac9ad2..ce1a2a3 100644 --- a/app/src/main/java/com/example/musicplayer/view/MainFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/MainFragment.java @@ -19,9 +19,14 @@ import android.widget.TextView; import com.example.musicplayer.R; import com.example.musicplayer.adapter.ExpandableListViewAdapter; +import com.example.musicplayer.entiy.History; +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; + /** * A simple {@link Fragment} subclass. */ @@ -30,11 +35,10 @@ public class MainFragment extends Fragment { private LinearLayout mFunctionLinear; private MyListView myListView; - private LocalMusicFragment mLocalMusicFragment; - private SearchFragment mSearchFragment; private ExpandableListAdapter mAdapter; - private LinearLayout mLocalMusicLinear; + private LinearLayout mLocalMusicLinear,mCollectionLinear; private Button playerBtn; + private TextView mLocalMusicNum,mLoveMusicNum,mHistoryMusicNum; private TextView mSeekBtn; private String[] mGroupStrings = {"自建歌单", "收藏歌单"}; @@ -49,12 +53,16 @@ public class MainFragment extends Fragment { Bundle savedInstanceState) { 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); //获取焦点 mFunctionLinear.setFocusableInTouchMode(true); myListView = view.findViewById(R.id.expand_lv_song_list); mSeekBtn = view.findViewById(R.id.tv_seek); + mLocalMusicNum = view.findViewById(R.id.tv_local_music_num); + mLoveMusicNum = view.findViewById(R.id.tv_love_num); + mHistoryMusicNum = view.findViewById(R.id.tv_history_num); return view; } @@ -65,13 +73,12 @@ public class MainFragment extends Fragment { mAdapter = new ExpandableListViewAdapter(getActivity(), mGroupStrings, mSongStrings); myListView.setAdapter(mAdapter); onClick(); - - } @Override public void onResume(){ super.onResume(); CommonUtil.hideStatusBar(getActivity(),true); + showMusicNum(); Log.d(TAG, "onResume: true"); } @@ -79,37 +86,41 @@ public class MainFragment extends Fragment { mLocalMusicLinear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - replaceFragment(1); + replaceFragment(new LocalMusicFragment()); } }); mSeekBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - replaceFragment(2); + replaceFragment(new SearchFragment()); + } + }); + + mCollectionLinear.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + replaceFragment(new CollectionFragment()); } }); } - private void replaceFragment(int type) { + private void replaceFragment(Fragment fragment) { FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); - //进入和退出动画 transaction.setCustomAnimations(R.anim.fragment_in, R.anim.fragment_out, R.anim.slide_in_right, R.anim.slide_out_right); - if (type == 1) { - mLocalMusicFragment = new LocalMusicFragment(); - transaction.add(R.id.fragment_container, mLocalMusicFragment); - } else if (type ==2) { - mSearchFragment = new SearchFragment(); - transaction.add(R.id.fragment_container,mSearchFragment); - } + transaction.add(R.id.fragment_container, fragment); transaction.hide(this); //将事务提交到返回栈 transaction.addToBackStack(null); transaction.commit(); } + private void showMusicNum(){ + mLoveMusicNum.setText(""+LitePal.findAll(LocalSong.class).size()); + mLoveMusicNum.setText(""+LitePal.findAll(Love.class).size()); + } } diff --git a/app/src/main/java/com/example/musicplayer/view/PlayActivity.java b/app/src/main/java/com/example/musicplayer/view/PlayActivity.java index c12a323..4126bf7 100644 --- a/app/src/main/java/com/example/musicplayer/view/PlayActivity.java +++ b/app/src/main/java/com/example/musicplayer/view/PlayActivity.java @@ -1,5 +1,7 @@ package com.example.musicplayer.view; +import android.animation.AnimatorInflater; +import android.animation.AnimatorSet; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -66,7 +68,7 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { private String TAG = "PlayActivity"; private boolean isOnline; //判断是否为网络歌曲 - private boolean isOnlineAlbum;//判断是否为网络专辑 + private int mListType; //列表类型 private int mPlayStatus; private boolean isChange; //拖动进度条 @@ -90,6 +92,9 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { private TextView mDurationTimeTv; + private Button mLoveBtn; + private boolean isLove;//是否已经在我喜欢的列表中 + private DiscView mDisc; //唱碟 private ImageView mDiscImg; //唱碟中的歌手头像 private Bitmap mImgBmp; @@ -107,7 +112,6 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { public void onServiceConnected(ComponentName name, IBinder service) { mPlayStatusBinder = (PlayerService.PlayStatusBinder) service; isOnline = FileHelper.getSong().isOnline(); - isOnlineAlbum = FileHelper.getSong().isOnlineAlbum(); if (isOnline) { mGetImgAndLrcBtn.setVisibility(View.GONE); mDurationTimeTv.setText(MediaUtil.formatTime(FileHelper.getSong().getDuration())); @@ -156,6 +160,7 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { //与Presenter建立关系 mPresenter = new PlayPresenter(); mPresenter.attachView(this); + //是否为网络歌曲 @@ -185,15 +190,19 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { mDisc = findViewById(R.id.disc_view); mDiscImg = findViewById(R.id.iv_disc_background); + mLoveBtn = findViewById(R.id.btn_love); + + //界面填充 mSong = FileHelper.getSong(); + mListType = mSong.getListType(); mSingerTv.setText(mSong.getSinger()); mSongTv.setText(mSong.getSongName()); mCurrentTimeTv.setText(MediaUtil.formatTime(mSong.getCurrentTime())); mSeekBar.setMax((int) mSong.getDuration()); mSeekBar.setProgress((int) mSong.getCurrentTime()); - + mPresenter.queryLove(mSong.getOnlineId()); //查找歌曲是否为我喜欢的歌曲 if (mPlayStatus == PlayerStatus.PLAY) { mDisc.play(); @@ -205,7 +214,6 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { Intent playIntent = new Intent(PlayActivity.this, PlayerService.class); bindService(playIntent, connection, Context.BIND_AUTO_CREATE); - } private void try2UpdateMusicPicBackground(final Bitmap bitmap) { @@ -315,10 +323,8 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { Log.d(TAG, "onClick: --------play"); if (isOnline) { mPlayStatusBinder.playOnline(); - } else if (isOnlineAlbum) { - mPlayStatusBinder.play(Constant.LIST_TYPE_ONLINE); } else { - mPlayStatusBinder.play(Constant.LIST_TYPE_LOCAL); + mPlayStatusBinder.play(mListType); } mMediaPlayer.seekTo((int) mSong.getCurrentTime()); mDisc.play(); @@ -347,6 +353,21 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { mDisc.last(); } }); + + mLoveBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showLoveAnim(); + if(isLove){ + mLoveBtn.setSelected(false); + mPresenter.deleteFromLove(FileHelper.getSong().getOnlineId()); + }else { + mLoveBtn.setSelected(true); + mPresenter.saveToLove(FileHelper.getSong()); + } + + } + }); } @Override @@ -379,12 +400,11 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { //保存图片到本地 FileHelper.saveImgToNative(PlayActivity.this, mImgBmp, getSingerName()); CommonUtil.showToast(PlayActivity.this, "获取封面歌词成功"); - -// //将封面地址放到数据库中 -// LocalSong localSong =new LocalSong(); -// mLocalSong = LitePal.findAll(LocalSong.class); -// localSong.setPic(BaseUri.STORAGE_IMG_FILE + FileHelper.getSong().getSinger() + ".jpg"); -// localSong.updateAll("singer",FileHelper.getSong().getSinger()); + //将封面地址放到数据库中 + LocalSong localSong =new LocalSong(); + mLocalSong = LitePal.findAll(LocalSong.class); + localSong.setPic(BaseUri.STORAGE_IMG_FILE + FileHelper.getSong().getSinger() + ".jpg"); + localSong.updateAll("singer",FileHelper.getSong().getSinger()); } try2UpdateMusicPicBackground(mImgBmp); @@ -406,8 +426,32 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { } @Override - public void setSearchImg() { + public void showLove(final boolean love) { + isLove =love; + runOnUiThread(new Runnable() { + @Override + public void run() { + if(love){ + mLoveBtn.setSelected(true); + }else{ + mLoveBtn.setSelected(false); + } + } + }); + + } + + @Override + public void showLoveAnim() { + mLoveBtn.setSelected(true); + AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(PlayActivity.this, R.animator.favorites_anim); + animatorSet.setTarget(mLoveBtn); + animatorSet.start(); + } + @Override + public void saveToLoveSuccess() { + CommonUtil.showToast(PlayActivity.this,"添加成功"); } @@ -427,7 +471,6 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { @Override public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); Song mSong = FileHelper.getSong(); mSongTv.setText(mSong.getSongName()); mSingerTv.setText(mSong.getSinger()); @@ -435,7 +478,7 @@ public class PlayActivity extends BaseActivity implements IPlayContract.View { mPlayBtn.setSelected(true); mSeekBar.setMax((int) mSong.getDuration()); startUpdateSeekBarProgress(); - if (action.equals(BroadcastName.ONLINE_ALBUM_SONG_Change) || action.equals(BroadcastName.ONLINE_SONG)) { + if (mSong.isOnline()) { setSingerImg(mSong.getImgUrl()); } else { setLocalImg(mSong.getSinger());//显示照片 diff --git a/app/src/main/java/com/example/musicplayer/view/SearchHistoryFragment.java b/app/src/main/java/com/example/musicplayer/view/SearchHistoryFragment.java index 790e085..e4aebd7 100644 --- a/app/src/main/java/com/example/musicplayer/view/SearchHistoryFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/SearchHistoryFragment.java @@ -11,6 +11,7 @@ import android.view.ViewGroup; import com.example.musicplayer.R; import com.example.musicplayer.adapter.SearchHistoryAdapter; import com.example.musicplayer.entiy.History; +import com.example.musicplayer.widget.DeleteDialog; import org.litepal.LitePal; @@ -56,14 +57,34 @@ public class SearchHistoryFragment extends Fragment { mAdapter.setFooterClickListener(new SearchHistoryAdapter.OnFooterClickListener() { @Override public void onClick() { - LitePal.deleteAll(History.class); - mRecycler.setVisibility(View.GONE); + final DeleteDialog dialog = new DeleteDialog(getActivity()); + dialog.setOnClickListener(new DeleteDialog.OnClickListener() { + @Override + public void selectCancel() { + dialog.dismiss(); + } + + @Override + public void selectDelete() { + //删除数据库中的历史记录 + LitePal.deleteAll(History.class); + mRecycler.setVisibility(View.GONE); + dialog.dismiss(); + } + + @Override + public String setTitle() { + return "确定清空搜索历史?"; + } + }); + dialog.show(); + } }); mAdapter.setOnDeleteClickListener(new SearchHistoryAdapter.OnDeleteClickListener() { @Override public void onClick(int position) { - History history =mTempList.get(position); + History history =mHistoryList.get(position); LitePal.deleteAll(History.class,"history = ?",history.getHistory()); mTempList =LitePal.findAll(History.class); changeList(); diff --git a/app/src/main/java/com/example/musicplayer/widget/DeleteDialog.java b/app/src/main/java/com/example/musicplayer/widget/DeleteDialog.java new file mode 100644 index 0000000..215464c --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/widget/DeleteDialog.java @@ -0,0 +1,84 @@ +package com.example.musicplayer.widget; + +import android.annotation.SuppressLint; +import android.app.Dialog; +import android.content.Context; +import android.support.annotation.NonNull; +import android.util.DisplayMetrics; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; + +import com.example.musicplayer.R; + + +public class DeleteDialog extends Dialog implements View.OnClickListener{ + + private OnClickListener mOnClickListener; + + private TextView mTitle; + + public interface OnClickListener { + void selectCancel(); //选择取消 + void selectDelete(); //选择删除 + String setTitle(); + } + + public void setOnClickListener(OnClickListener onClickListener) { + mOnClickListener = onClickListener; + } + + public DeleteDialog(@NonNull Context context) { + super(context, R.style.MyDialog); + initView(); + } + + private void initView() { + @SuppressLint("InflateParams") View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_delete_photo, null); + mTitle = view.findViewById(R.id.tv_dialog_delete_title); //标题 + TextView cancel = view.findViewById(R.id.tv_dialog_delete_photo_cancel); //取消 + cancel.setOnClickListener(this); + TextView delete = view.findViewById(R.id.tv_dialog_delete_photo_delete); //删除 + delete.setOnClickListener(this); + super.setContentView(view); //设置布局 + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.tv_dialog_delete_photo_cancel: //取消 + mOnClickListener.selectCancel(); //回调给主活动,让主活动处理相关逻辑,下同 + break; + case R.id.tv_dialog_delete_photo_delete: //删除 + mOnClickListener.selectDelete(); + break; + default: + break; + } + } + + /** + * 重新该方法,使dialog适应屏幕的宽高 + */ + @Override + public void show() { + super.show(); + Window dialogWindow = this.getWindow(); + assert dialogWindow != null; + WindowManager.LayoutParams lp = dialogWindow.getAttributes(); + //获取屏幕宽度 + DisplayMetrics dm = new DisplayMetrics(); + WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); + assert wm != null; + wm.getDefaultDisplay().getMetrics(dm); + int screenWidth = dm.widthPixels; + //设置高宽 + lp.width = (int) (screenWidth * 0.9); // 宽度 + lp.height = (int) (lp.width * 0.4); // 高度 + dialogWindow.setAttributes(lp); + + mTitle.setText(mOnClickListener.setTitle()); //设置标题 + } +} diff --git a/app/src/main/res/animator/favorites_anim.xml b/app/src/main/res/animator/favorites_anim.xml new file mode 100644 index 0000000..0525aa0 --- /dev/null +++ b/app/src/main/res/animator/favorites_anim.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-xxhdpi/favorites.png b/app/src/main/res/drawable-xxhdpi/favorites.png new file mode 100644 index 0000000000000000000000000000000000000000..f221e5e28ba51ec97e7edf4d7bcde54995aacaec GIT binary patch literal 1522 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1&2vQK~#8N?VSx$ z8!-%pp}jzR1GxX8I6_ZQsMTuQG{n1-EZegDz8QuDVy~?C{F@~_0RR910000000000 z0LacWf1l3B$H&j|jp8|r>HYcn`71vT3Af|RpJxyGpsy(Hm}US$q9jlvTkB||wBx;e zYt7>{V-Gh#Nf`Bj9t<;sljsjAZ5XP_u#0sR{u8~Dn4t~#bic^Rq}}6{#0+hy(Y5lK ziMzo(HI(qX4fPs&nxIR?L4^MgZ4xuIL4tdQ5fgXAhrvf$$XrIy6i zocBupDxOwiK%%)u7ido9=7JfaC8;fXG7czu2S&QHZy zwIEChGhWcW$J8j{b=k_1K>V;fmKL?5spP&mXrv!C-RRy$;qz3TA=@@!bnD}2_UcSA(z5U>)mvo7{I_G6JCYPoufxc^Ck_e-a)YuWA5ZXH4Kmg zvyM#$z>)F#w2lB6K^EssKx_pUKsX9lwX7OI`d&Y#f$3c8bf%?9;2)Zg-;wlwLe*n6;z|PmauoR&PsQElYmHgJHJW@% z#V6FgR4Xh-f_9YRtMaWL0kjv;8V3C1_#`uaDq&2n?>}Nq0v82BM&;N%JXfwgJH>`NB-Od zfC=o(5}$BQK1`rzruc+=;$Z?gv&ARekAf+{(f|5vMIwmb70W>e!Nt?ERbF6%|1svn z{0U%T;D)H+qG{k}sYrER!fjHKB>~(V6{*BO;I^q)JrUdt6 zSNc=76-E;*wGCQ9d}3NcGn-%)@rkL)%xHp@#3!cCtK4vP!mP&W$+5@hr($M`ABH1& zTDbUhR*ydft0u98p!%=s%=)K$z2F3?;G)Cf%d3cXt`Tznp+xaRF{9_w6=IYS@^HnH zC=z5;@5&;6cqq|YdYgbRqk@ZuB)luF3GC71EU`rI`AZB-5loO#d}0X$5Hn4XReWNZ zci5~6wHk*w&L;S&m{r7Il2HdnqpkxC^cII-uA=wu13Z9puY!wK;g_j^_!D6bRMZ6H zU#sAvU?!}EihC3Ak5zEdrAf0|H45_kUPDXSEGzv~+ZCe;)MVP`rQ5IeHbExwiF5`a zdYK@b_(Vzr5Z)%pC_b^=A6rNv!7P8Keh<}=Rs1cmo*EK69Pn)8Y!Z|oirA&sZ#A?@ zO|a9Dzunw+WrCf=C$=*HQ8U4A;uC3i0cWt#w||`RzN7d6000000000000000HsI;$ Y7b&=cR*?~LWB>pF07*qoM6N<$g34#VaR2}S literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/favorites_selected.png b/app/src/main/res/drawable-xxhdpi/favorites_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..a67a2ffb3ee4612ae465fee786cdf07309c732b4 GIT binary patch literal 2184 zcma);=|9x_8^%AgG$!jGzOZKc|NXQ-?MMIWkX=H0b ze6u8?l9ZjS$yUiOe$IdJdvL$+>vcW2AKVYF*A;JWX2ioO$_W7AAsG`d>~F?@gGTMM z1@HJ405q9IG_VS$F5b5{6C+{T%VJX+7@DC>nUAlNg=|fa7ErEg8{`Nc&ynz9%E+O0 zU_MN3IcUwjHbt^ZDoRk{-NAH9|4k9yTKDKzSj`c=CDt5Eg*rD^virrmv{av-2t^tw zF$_{z9DLk_af~Y1Cnpjgmi&K;r<^5!<%;&gq6)fAVIv&J6l`@b*eOEpkJu^8uNwvQGMjBp| zFkMVAmtqWRxOf~qZ6%i%GQ79k9a6DQnIA+Z?Op#tDZTw>%tj9s2Gu&bu)n@7j3m5r=( ztSwy|sSW^aalYryQ*JiaH$=ID8{ObB)(`BYV*a&$^-_)PSSr!a_8$tEmXvdKJ;XR3 zvuzM963F2)MwKSZjy?af>x|ws7h%4|839JNS%qT9445 zT5I}ekGN{E=dVuE$flQBfZeUyn!`pLgExxlrG8HRkHcKO$y-fvc0CgxAH;W#9u~*m zYx~n1V2Keyk2#U5zXi52kgcf0k!aZepO|98DIeuyUr!RNS74pZmtQ z9gmd~>Rcd8#t=;pJ&|`w{$;=mnu%h9_ZR-2Tkg-QZ?`VB^6%S=5)-*3ug))7Hh`mM zcj|KSgCRdGAdVg*_SlYOUkeT8j0?#dT-5#e(hv)@f6sU3m~Bg!5X3;m%=X;3r7ru{ z^q)@tYsN0&1ThA^a;Kxind&l}S}BR-$n>(ke#DjwL~N-CvL_aWe=M-vg+9O;xe;gh zt_&wKs1!2JR*^1`kkAZq<>jN`rZoo?CETOjpZ%#$IMfMhIH$u28-_)eUXu)Xg6)_I zuw#Y&nSh@3BPj>aqgHjEb5Y_lpka8?@{nTtqN1EML-F&Q7ex=U8uh5 zNk>6JdnSu6pip4C9)?Ku-ZL?32gWj;K?sz@*luQWGAz|3V;)saMqHQq;6k7~pcOOb z89zR`@H3y<`^pmPc%f{Ah)H$f_7tye&2%Av=ULDK>fRhHQRca@=iw-cv$9Db-=fSM z2X7qy~%%J8b*} z-h@BDyL6eu9YAi7T&mR=#u_#L>lRIqxX~de$*iILtW}*BrAcF(B&Rscs%}G*1?I_M z0;_@w2L${&nHy@m2byG;PNHz+ra(@Nu#fV1)%GfDmk8o+1xLR*kG4|UyL$nm7`&N> zn_1-HmYdvatogMg)RqP6rXsg=HzMlpO&LiGAXLvCX#1!F#|M!TFrGciJBfvi`C8bh zLYDw8^RK3%g=__Q;%C&>&u0D#3_U6;qR+b=C9)i+k4=kT5u6P#P@sJ}LgwkcL2#~c zXv@EA2_+dr$8K9$gn!mdI2L8~BFO@%M5@)iYHznHBoE4tvU3{7&WF@yiqaY^W1$QW z+1~{}2DC=%#gaflwnL6I6*nPBtXq0s^zy*$t@=waf`8a%D3gbERFnawuRMlB7!jX_ zZ_W8Dj}Z{23mxS=TMUQLOxOheJ+B7C_|@iqta-IoBi3_r6#;jYC?Kt`_J!(RBLt9U zM8>riqCEj!|6$VYiCysrKr|bkF8%54Ya%0Jp31FP^4d zhBJp@5=8!rGC`=ZCxh_YOA=S1hsQ77#f)a+eGf8z^2iwN-yvk!f<#Yworbg)Ag}nr zf}ydCYyKoH z1#Sb_f6qC;n?N#Io|Fl=lQhpn&=ip{oP#UBG|(qt9<4;9ptIVmmG5a%jFfj(j_L@S zAthz&3efev!(({_h?RzXl0%HARbS2O1pVfH1^6Q%CC9nN3I)ZM9$oDK!BfY@9-ai6 xR;!Q5C`ig>Ks6Kg + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/empty_song.png b/app/src/main/res/drawable/empty_song.png new file mode 100644 index 0000000000000000000000000000000000000000..30faa4852231632228aab50a3f672733838a39ca GIT binary patch literal 7884 zcmcJUWmr^C-1m2BmX>Z51f;uR2?=SGmX>a*MPOl(QeuHWA_7t(qS7EBxpa3UE$x!h zeV_H+^Wu4T-=FI`JLl}#nc0~$^ZmtntFNn00%3rFKp>JQ8jqg>B?5Dh;{l&3rA=>u z0>?>7M+pR~NF=(p#RaaxzE9PaL8U`X+rS0e3yr5bAW#q|P$?1wx&*#LY=J=jLLkr| z8xTn50|-Rx{juIa4!D75r=|WFC;={18p42r&|AaI7brFU9csO93Lp@(#goTMhJn9! zvw|%qj2640sB~LTi|9;6wpg~L${ zC9sU3(5N;~{0Y~(c}Hw}5he0p9zm(35}6C0wb*L;lRPP4yok;R1fbxwanD;+yYcba zt5zyX>dwXDB459H6>!V_s|R_H*g$$%*R;-11`@X|m6+(r4}%EfejLQOFfm@7Dkrvp z)dZRvlKbr~A$B2r=0&7mCXW!gWI3&4_og)8)7Dtj+*IFsc4*R~T1bdZ?qnZhbJ6)F z50wO?kT)Bzo^E&2#SD8?)X<#Zw4r4F_@h*2SogBj1EHieCzCeZ7M=6+a`1Nx0fNR& z7^`76BucxhfAWUg0u|}@)esWJ23lD$FVV*1rt*0OqwBR7LGZknZPw#lB|-7hi}O5a z>yEi`l<$3`S>4^eS%~(~Nf>pm#ZD7MpE!!zh@8Z~P3Xp9Vnt-*k0L@2g zcil=^Mrd;qG=?mY2|krnB5j7?=KT6e$)mTYxFCM;{g0!cOtpEz-($-_GMOy3_WmmL z!B191Ed|rgX5lDEg#P*c(lRekiF8n0r(K0PcyDq_Ld^B=VRHYvPs^}gi7`)ji(-j! z$?5UJD?tlTJ;C>%jaa@xA|a5L6%9H85EC+T1?&I*R7uJ5G3Se3o^>A@lvSQh8E*K) z%G|)y0NH+K_u49G=AdKMEU0MGwR#p9hwCo=gI%0EyF-AoNa=)ZS`c9D8DR+;Ix**w-1ERg z*r=-!Pbx$xU7NFtUWhIuGc)r-Bd^ID>>RGvE^_58rdgo*kW>fLNl{U_N{qtY_0e#6 zaq-U1j=N%6Sut=n56glsT{bntuTB$?cwe-iJV}?M{~+Sf_wF5)V&V9_Wy!+!u3t$^ZVzZ|bi7^d zPGqIE=1tWscuE-0BJVh`HQI8#Jzl7nLrTmd7wD~wwY=IM`ODd!(2RjGoz44~+FvX- zW9RoR?cM4ECfps6;H{B7l^9YmYgnW2=1>-5)LD!n!4d|22q5W&B^wZO(28VMRO{MX zpr>ysHmhWi&;sQ4TuyjGqS7eBVH4QJ2`S{3=fe68UJ<#eEqX=)&1r&LAP^9(T3Zu z1V#z>c>*T+pkrr8$L=!TG|_w;Zvc%q+}vW-W9XC1zP?kkbzdJ0kCn`SY*lpA@MC?^ z$&}c2g1$gil?m!UpBovO>G8meT*E>5oL0M^(+XJp^j^U#57AbHCOU$M)z8m` z*r(4ADLLa=$>JGd!}6<~a$coxHoj5@M!|bBil4xzSO1eqZ z?gfVMCn=nI*>d!B67DnQw(W=>3>pRm=E`j*!2E{nGF-t0tZDh!2|(0nZsr~5#zF=xz14`w6!fkGJvJGDdM zmziF=Ie3df=#tv065siQub+mp<%3UmW?SOvMV*E|65{;B?>bajSy@FzCA_62H#e8f z@fbn?!Xsr8b3U+HZj0J)zS@(`Esi&`0W?@RGyDtZ)VQP=29VoS?W@fIS%#`E9% zq4@E1!ai$nD6*`r47q2h-b7y>%NLoTj>ohF!L^u)%I zGN()`(Hsv+=&?9B%Ihu`U|gJ>oLHg%7}{4Uaa3!*uM$oCM4Kw{Xk#!_(u?J4q4@$Y zaKCAHuGS02M{sqvzk~{dQkF;KEvGxZ7Yy5=Hzu2KefgNph=U!(KvJatg9U!XS*47+ zIi2&mJ1IjlhWcR;JIGurHm$IWa!%djn^^rQ)f)X*9cl0A=!k`c9vOxa=O5+?UrzkDWd8y{ARViVO;@MzQ+lD0^MjT4Xt1c0!tu!Q zHUfo0g$3h;v)yNbhPFi#QX*E`)qy$10*31`SL1;#B5L-kCh`l9fdTwVO%=TT4|j2; zf_o-rpQERPvBoOjskOiV=Ing2k?GZVxRHrW2oif2b}}jMHdXwxX@!v(FQOIHctn~h zyT25+3`jYWv00P~64lm?Pe2s+=FJ;W2z<7ZUdML8Q37|wc}65%^y~eRo;UH?s;Zrx z(`DGn$)lq;SF)bxLu^XYn6>1)iI7}01s<$p~FYO1HFVtr4+b%sChY|^!+(HMg{gh@UlH8qPQGCDdc zD(Wpe4s3L$XXDRYO~w7|^?s95Dw_Jx1$9=-a+_8x2_r2%ubVLQg;$$dsJojiSjRL6 z;%U1ZE+YC;^Wk&6@82+ho6mp836e6q!WBvcp;tS;!}3?fGgW>x3_ecw_Vzoo*zeMo z0Fx3h4XrgV8Fj9RLZf!lRPDV^aK(EFqa^N*yKsU&k z>!Xc|Jodp0%k?=g7qjoc7R|lNu`Y68Ps@^>O)~jrUqmyJIG(&H$b$hZ^gQnfsZ**r zbrm142faCdHeIG(^Lpvpu`|~C?$@EKiW-J!seAfGM&D)83AL-$ShWpp{ux|EIrP7cYV~L4{Oi`Xv0WGU3!KD9S>p=v!4uQ0h0|Y?bi{aox}(p~==35ly(kI2I-)Gy!mCHqyWhY6ac#;b zQYhjiAjk)Jlm3Iubmfnd5Bdn-=Ju&au0nH z)Fd0zY|j5&b?ck2Iur^;)u_pp2FV17-`+Mi?=_;n^GI~Sa7ys1i`5rnrwI{*T>-5W zwg7o~CBsGE?fU(OBzk|)W&~~d4RE0fDd>70Kn%##yIU|Q>MbqkEx`1XWc#0$Ib{|y zQ2@K?9>cGCmRG!1Tp${vxIFca&dyE}rkP8*jH(p;j}31U5)%9!#`R4oXaN}e`(ivO z9iQd@{F(g<#X~*!nUen1v}JPgUc+92R+@li!wa zga3+LS{ks8(yPt;dKws4lua*9*$t1(u~n@1Y|+)BdqkfmjZNyj5c`9lKv-S@0XP^lf+KixZnX(FD-mkyb%(In&s` zLvp6fx>r|vufi1eJKpkD8tAPo2G53u!CtNr#Br<<#2P+6QRAt=Zqfx2Kqz&Lm#+32 zF!tCDZlwwcG8q(P4L_MQv4*c-o;^(zfA#nC6A!pGEG6Tz1^aACFq*cI-N-LUK452S z^hKASoMKD^y$~WwH8H`T{}#)@a`04{N#UOjD!J2BmiMs-oT^H6-b4_i6)#AQJ?=n7 zt@-#^+IMU`%++LOZ=nGeS6WdjV%zrfnUk*zh9mB26*|Icw*ueLCW+QpI-ywI|?|6Qs0;3Xa%jV*HVy@QB+jrH&^KC zD!O2#9c~S+=GI}6wfxQTSb<`oR9yM0r*qGBzqNqb-#BZb%oxqi-z$s>$mt*7>KTcl z$P^)uUlV{;*^%=9ex;5>6=O5{DT;_zz}+Jf&8ME|=*S`u2{~WED6f=)*DT<&zvrj) zP!YTL9|P%b(HWXW?|gTkQ%6~(3$k&w4?Cmn?!?7?M5SnxYreqTQ0gurF@198)GznW zl}A>Vx2Obug^3>CzboHuy120WO=zC|hud(p3+X`b(Xnr95FlHRPGBEw07XH)c`OM4kDc_fwx|89d459ooe*JC-8G zo0%NxIT!HxJc4Yo$Db*3DDO+z_L)P_lfmysrw>g9=x&d>U`xvr->~t%8Y*gQ+t|Q@ zh71IxHNgQGFUdLt?7lc)cPi~e{OQCNBA%L&ks;&%ebqF0x6|2v)LGEV9z8x?R`nsA z3WYc=K>H1tQqy)b*xT9J{Z6`HV)?xHtNKc*?4K3%Gfxyo3i|pfS6TJj zC>iX=zZ9*sn~||H^f7r@tp5Q503xE!rNMM)cTX~(#pTg(nZ?ELIJ<~5!$0L=w^g|< z&N#=HU%r%*vzXEBw6X3t>=%?3>c-9cIr&txvZt3XI2Zeb8OA)wm4WxWeLTYxQj zEJWxhsuOZ4+`Nk_)qG-GchyrvP7gpmd3#@!WD-~r?8GtwRP{^sG7)*-z8$e3kEQE% z`*C<4qeA)o7?>Mk>oLgGSVOt+dj{luI7FW@rAr473BTw(vDqa~Z_Y*x1m}7^?wRHHj@Vrl0d)h-)?9 zkivZezK8TAN-<=t7;zYa;-8#P*ep;hMwF`1`(a@L9-9?JFW6wk!YEn!ZKTfEeXA+(P%yN@p3obJ8G#&tpqk|rkf^9Ok1yD~u3Mn= zlzW7M@B{EbfH=#v{y_MJsh(FASX`Wh1P^=oW|LR|#Lu>>Z^?|l2njKrN4z1Zd9=P= zn8qJ`=^}jPt_04E8~b~|vyz=XyVqW#iscQ7yvwtp-<^7LhkzXINAL)oSg5g6a{qbT z+org=@U!*PmV~%4`$x6$x<)*|oBlK+NT@4P=k*hIioOThglbIm>fQ157|%|)+b#fu z1ibcxPP*JZmsGaF}Exi*ky7U^!@$m=W_NvM=Dn}JlOd!t^tSu+=X?>9t zNRm~XBL29(-$^+;C~d{fjYx80Hu9UIjlJ`t_uU_AJVVeqw@t=sb#+m&t0A>@@tSW= zG2Ro91tMiSpGF}J@@JAhSh#0FX&Z6?!P;#Q6;^lWb34z=bC)h_nt$}sgOEOf+?4(; zJHtIH8O=e_vWCMTy_UUb9zLCi=AQL0VTs}|x`3REQ(PBnuGS1vS@Il6d6c)-ak1CQ z?a%khZN|o$+L7KXJwC1jvNyZ2K6dLPQyUyK<&l!tdx%6(kTeAaY{7rp5(t8Tgu4y+ zpqGmke!LR%+i-c(#H7rsiQ$9TqlXTCRJnSrHC&&*YnDx;!&A5tS%-&c)0Iv;;&!TZfUE-<4M=8_~}OS{3W|P z^-TMipDQURefXz1BuvtO*VAIiurDqK9BNAeYG@8l97+cx@VPjEsC&5JOKksJCYKi6 z7A-=`!}$wYdt5Ijrz(n5R!wC;NWQ7xxQ>A2O5Sp zhRY{qSz64`Y;70PVp^bjhteppyMWYZ{Qlk7*QK^xHT?Hze;|D3*)njK4%nWJpFTA= z*U`^Ztj^aVIV5*If07{B2|FU$2SC$CKq#N!C|d5IrK|hgtRR>n1g9k#M}kr7QP*Fd z`nyZDe8649dS3HUp=7!$UPHdM2eX-(1Y-((s^-k_9>88yl)HEAqrx_{9Ukgidx@Mx zN9%cmmjlJ$T@Eaa1l^WeZVsCmfor`OiJOFZg=s-Z6T8}~;MAB#K&+n=eUyK0{)F&41$7pa!w;Z$X^g~A zd7P2K6w_z2lAB(;J>w(Gu}R0qay9haP*mlZ9gyjcQYJ@iIfsR%$9qigK&(BGuoX0K z+Vc{G#iH<1=+qMS-KB|@m5$CnZ0#j=A|YsS#>cn6Z@@9&*w5DcvyzwJ>@Lqwilp{r zAz+wHgsb|X9Us25lC_A3q=k}pqC^F!SwnMWDq!+k;+Z?k=jd(x6>ll#?hFTU2vJry zhmRbt6!*OH;b3NVC^>1&IQW(^zhc^T(&{v;kPqeGKf6tet9Xk8`Y5AHdwlHsQi^Gl zK;|4WZ29xRuB{2Kd?uTyvZD{WhTsvIl1{&6(p`DX0`#`Qgp*LN}-8rVL&NU*O7Vlw%hccRg*5;OlkiuARPNO=oT5 zC(_B}1zxy5^iwtUv$yqgka^+b02Ck*Az>+gVPSqzAwv-%8Bt*waUotIDH$OlDQJN9 z|5L%k%ihKD)&IZ36T6`Upn@5u2j2iE89Q5F2Y!Da7m%ZiyMv6NprEsthl8N4y@!jZ zpvwy{Pku))Pd`CF5AT0h)_yO7oIS*(14LZB1^K-LJsezKdHH)fxcGQ^I{EqAx!8IM X0Ihxu#>2d?20c;LeO#(+^ZI`PYyCw4 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/love.xml b/app/src/main/res/drawable/love.xml new file mode 100644 index 0000000..b20a0b9 --- /dev/null +++ b/app/src/main/res/drawable/love.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_play.xml b/app/src/main/res/layout/activity_play.xml index abd4f40..4083003 100644 --- a/app/src/main/res/layout/activity_play.xml +++ b/app/src/main/res/layout/activity_play.xml @@ -161,6 +161,16 @@ android:layout_height="60dp" android:background="@drawable/activity_play_next" /> + + +