列表需要是乱序

Fragment有泄露问题
新增了Kotlin插件,但仅仅只是为了Helpers类
This commit is contained in:
Yutousama 2020-11-25 02:20:14 +08:00
parent 26bdcffb68
commit 7364d3500c
22 changed files with 821 additions and 118 deletions

View File

@ -1,6 +1,17 @@
apply plugin: 'com.android.application'
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
signingConfigs {
yutou {
storeFile file('D:\\AndroidKeys\\yutou.jks')
storePassword '34864394'
keyAlias 'yutou'
keyPassword '34864394'
}
}
compileSdkVersion 30
buildToolsVersion "30.0.2"
@ -20,21 +31,30 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.work:work-runtime:2.4.0'
testImplementation 'junit:junit:4.12'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'jp.wasabeef:glide-transformations:4.3.0'
implementation 'jp.co.cyberagent.android:gpuimage:2.1.0'
implementation 'com.alibaba:fastjson:1.1.72.android'
implementation 'com.alibaba:fastjson:1.2.68'
//noinspection GradleCompatible
implementation 'com.android.support:support-media-compat:28.0.0'
implementation 'androidx.palette:palette:1.0.0'
@ -43,5 +63,9 @@ dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.5'
implementation 'com.kaopiz:kprogresshud:1.2.0'
implementation 'com.ogaclejapan.smarttablayout:library:2.0.0@aar'
implementation 'com.ogaclejapan.smarttablayout:utils-v4:2.0.0@aar'
implementation 'com.github.promeg:tinypinyin:2.0.3'
implementation 'com.github.myinnos:AlphabetIndex-Fast-Scroll-RecyclerView:1.0.95'
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
}

View File

@ -0,0 +1,230 @@
package com.yutou.nas_music_player.Adapters;
import android.annotation.SuppressLint;
import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SectionIndexer;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.github.promeg.pinyinhelper.Pinyin;
import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.MyApplication;
import com.yutou.nas_music_player.R;
import com.yutou.nas_music_player.containers.MusicContainer;
import com.yutou.nas_music_player.tools.AppData;
import com.yutou.nas_music_player.tools.AppTools;
import com.yutou.nas_music_player.tools.Helpers;
import com.yutou.nas_music_player.tools.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import cc.ibooker.ztextviewlib.MarqueeTextView;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
public class MusicLibsAdapter extends RecyclerView.Adapter<MusicLibsAdapter.ViewHolder> implements SectionIndexer {
public static final int LIBS_MODEL_ALL=0;
public static final int LIBS_MODEL_Album=1;
public static final int LIBS_MODEL_Artist=2;
public static final int LIBS_MODEL_Tmp=3;
public static final int LIBS_MODEL_PLAY_LIST=4;
public static final int LIBS_MODEL_PLAY_Collection=5;
private LinkedHashMap<String,List<MusicData>> musicDataList;
private String mSections = "ABCDEFGHIJKLMNOPQRSTUVWXYZ#";
private HashMap<Integer, Integer> sectionsTranslator = new HashMap<>();
private ArrayList<Integer> mSectionPositions;
private ArrayList<String> mSectionPositionsKey;
public MusicLibsAdapter(int model){
initData(model);
}
private int model=-1;
public void initData(int model){
this.model=model;
System.out.println("填充序列 设置model "+model);
List<MusicData> tmp=new ArrayList<>();
switch (model){
case LIBS_MODEL_Album:
musicDataList= MusicContainer.getInstance().getAllAlbumMapList();
break;
case LIBS_MODEL_Artist:
musicDataList=MusicContainer.getInstance().getAllArtistMapList();
break;
case LIBS_MODEL_Tmp:
tmp=MusicContainer.getInstance().getTmpPlayList();
musicDataList=new LinkedHashMap<>();
musicDataList.put("list",tmp);
break;
case LIBS_MODEL_PLAY_LIST:
tmp=MusicContainer.getInstance().getPlayList();
musicDataList=new LinkedHashMap<>();
musicDataList.put("list",tmp);
break;
case LIBS_MODEL_PLAY_Collection:
tmp=new ArrayList<>();
musicDataList=new LinkedHashMap<>();
musicDataList.put("list",tmp);
break;
case LIBS_MODEL_ALL:
default:
tmp=MusicContainer.getLibs().getMainData();
musicDataList=new LinkedHashMap<>();
musicDataList.put("list",tmp);
}
}
@Override
public Object[] getSections() {
List<String> sections = new ArrayList<>(27);
mSectionPositions = new ArrayList<>();
mSectionPositionsKey = new ArrayList<>();
System.out.println("填充序列:"+musicDataList.size()+" "+model+" "+musicDataList.containsKey("list"));
if(musicDataList.containsKey("list")){
List<MusicData> list=musicDataList.get("list");
for (int i = 0; i < list.size(); i++) {
String section= Pinyin.toPinyin(list.get(i).getTitle().charAt(0)).substring(0,1).toUpperCase();
if (!sections.contains(section)) {
sections.add(section);
System.out.println(section);
mSectionPositions.add(i);
}
}
}else {
/* Iterator<String> iterator=musicDataList.keySet().iterator();
int i=0;
while (iterator.hasNext()){
String key=iterator.next();
if(StringUtil.isEmpty(key)){
key="#";
}
String section= Pinyin.toPinyin(key.charAt(0)).toUpperCase();
if (!sections.contains(section)) {
sections.add(section);
mSectionPositions.add(i);
}
i++;
}*/
int i=0;
for (String key : musicDataList.keySet()) {
if(StringUtil.isEmpty(key)){
key="#";
}
mSectionPositionsKey.add(key);
String section=Pinyin.toPinyin(key.charAt(0)).substring(0,1).toUpperCase();
System.out.println(section);
if (!sections.contains(section)) {
sections.add(section);
mSectionPositions.add(i);
}
i++;
}
}
ArrayList<String> alphabetFull = new ArrayList<>(Arrays.asList(Pinyin.toPinyin(mSections, ",").split(",")));
sectionsTranslator = Helpers.Companion.sectionsHelper(sections, alphabetFull);
return alphabetFull.toArray(new String[0]);
}
@Override
public int getPositionForSection(int i) {
return mSectionPositions.get(sectionsTranslator.get(i));
}
@Override
public int getSectionForPosition(int i) {
return i;
}
@NonNull
@Override
public MusicLibsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_music_libs_item, parent, false);
return new ViewHolder(v);
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull MusicLibsAdapter.ViewHolder holder, int position) {
System.out.println("填充数据?"+position);
if(musicDataList.containsKey("list")){
List<MusicData> list=musicDataList.get("list");
MusicData data=list.get(position);
holder.title.setText(data.getTitle());
holder.artist.setText(data.getArtist());
if(!data.isDir()){
holder.message.setText(data.getBitRate() + "kbps | " + data.getSampleRate() + "hz | "+data.getEncodingType() );
holder.icon.setImageBitmap(data.getImg());
}else{
holder.message.setText("");
holder.icon.setImageResource(R.drawable.ic_dir);
}
}else{
System.out.println(mSectionPositionsKey.size()+" "+musicDataList.size());
String key=mSectionPositionsKey.get(position);
if(musicDataList.containsKey(key)) {
MusicData data = musicDataList.get(key).get(0);
holder.title.setText(data.getAlbum());
// holder.icon.setImageBitmap(data.getImg());
holder.artist.setVisibility(View.GONE);
holder.message.setVisibility(View.GONE);
AppData.handler.post(new Runnable() {
@Override
public void run() {
Glide.with(MyApplication.application).load(data.getImg())
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(holder.icon);
}
});
}
/* for (String title : musicDataList.keySet()) {
MusicData data=musicDataList.get(title).get(0);
holder.icon.setImageBitmap(data.getImg());
holder.title.setText(title);
holder.artist.setVisibility(View.GONE);
holder.message.setVisibility(View.GONE);
}*/
}
}
@Override
public int getItemCount() {
if(musicDataList.containsKey("list")){
return musicDataList.get("list").size();
}
return musicDataList.keySet().size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
MarqueeTextView title,artist,message;
LinearLayout buttons;
ImageButton collection,top,dislike;
ImageView icon;
ViewHolder(View itemView) {
super(itemView);
title=itemView.findViewById(R.id.title);
artist=itemView.findViewById(R.id.artist);
message=itemView.findViewById(R.id.message);
buttons=itemView.findViewById(R.id.buttons);
collection=itemView.findViewById(R.id.collection);
top=itemView.findViewById(R.id.top);
dislike=itemView.findViewById(R.id.dislike);
icon=itemView.findViewById(R.id.album_image);
}
}
}

View File

@ -280,4 +280,33 @@ public class MusicData {
public void setMd5(String md5) {
this.md5 = md5;
}
@Override
public String toString() {
return "MusicData{" +
"artist='" + artist + '\'' +
", album='" + album + '\'' +
", title='" + title + '\'' +
", comment='" + comment + '\'' +
", year='" + year + '\'' +
", track='" + track + '\'' +
", disc_no='" + disc_no + '\'' +
", composer='" + composer + '\'' +
", artist_sort='" + artist_sort + '\'' +
", lastDir='" + lastDir + '\'' +
", file='" + file + '\'' +
", isDir=" + isDir +
", img=" + img +
", bitRate=" + bitRate +
", sampleRate=" + sampleRate +
", noOfSamples=" + noOfSamples +
", channelCount=" + channelCount +
", encodingType='" + encodingType + '\'' +
", durationAsDouble=" + durationAsDouble +
", lossless=" + lossless +
", variableBitRate=" + variableBitRate +
", md5='" + md5 + '\'' +
", isDownloadImg=" + isDownloadImg +
'}';
}
}

View File

@ -10,7 +10,6 @@ import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import com.yutou.nas_music_player.services.MusicService;
import com.yutou.nas_music_player.views.MainActivity;
import java.util.ArrayList;
import java.util.List;
@ -27,32 +26,39 @@ public class MediaBrowserHelper {
this.context = context;
browserConnectionCallback = new MediaBrowserConnectionCallback();
controllerCallback = new MediaControllerCallback();
subscriptionCallback=new MediaBrowserSubscriptionCallback();
subscriptionCallback = new MediaBrowserSubscriptionCallback();
mMediaBrowser = new MediaBrowserCompat(context, new ComponentName(context, MusicService.class), browserConnectionCallback, null);
mMediaBrowser.connect();
MusicContainer.getInstance().setBrowserHelper(this);
MusicContainer.getInstance().addBrowserHelper(this);
}
public void onStop(){
if(controllerCompat!=null){
public void onStop() {
if (controllerCompat != null) {
controllerCompat.unregisterCallback(controllerCallback);
}
if(mMediaBrowser!=null&&mMediaBrowser.isConnected()){
if (mMediaBrowser != null && mMediaBrowser.isConnected()) {
mMediaBrowser.disconnect();
mMediaBrowser=null;
mMediaBrowser = null;
}
MusicContainer.getInstance().removeBrowserHelper(this);
}
public boolean isPlayer(){
public boolean isPlayer() {
return MusicContainer.getInstance().getMediaPlayer().isPlaying();
}
public MediaControllerCompat.TransportControls getTransportControls() {
if(controllerCompat==null)
if (controllerCompat == null)
return null;
return controllerCompat.getTransportControls();
}
private List<MediaControllerCompat.Callback> callbacks=new ArrayList<>();
private List<MediaControllerCompat.Callback> callbacks = new ArrayList<>();
public void regPlayListener(MediaControllerCompat.Callback playListener) {
callbacks.add(playListener);
}
private class MediaBrowserConnectionCallback extends MediaBrowserCompat.ConnectionCallback {
@Override
public void onConnected() {
@ -105,6 +111,7 @@ public class MediaBrowserHelper {
}
}
}
public class MediaBrowserSubscriptionCallback extends MediaBrowserCompat.SubscriptionCallback {
}

View File

@ -18,6 +18,7 @@ import com.yutou.nas_music_player.tools.StringUtil;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
@ -39,9 +40,10 @@ public class MusicContainer {
private MusicData nowPlayData = null;
private MusicLibsInitInterface initInterface;
private List<MediaPlayer.OnCompletionListener> completionListener;
private MediaBrowserHelper browserHelper;
private List<MediaBrowserHelper> browserHelpers;
private List<MusicData> playList, tmpList;
private Map<String, List<MusicData>> albumMapList;
private LinkedHashMap<String, List<MusicData>> albumMapList;
private LinkedHashMap<String, List<MusicData>> artistMapList;
private int playModel = PLAY_MODEL_RANDOM;
private PreviousPlayerList previousPlayerList;
@ -50,8 +52,10 @@ public class MusicContainer {
mediaPlayer = new MediaPlayer();
playList = new ArrayList<>();
tmpList = new ArrayList<>();
albumMapList = new HashMap<>();
albumMapList = new LinkedHashMap<>();
artistMapList = new LinkedHashMap<>();
previousPlayerList = new PreviousPlayerList();
browserHelpers=new ArrayList<>();
playIndex = ConfigTools.getPreferences().getInt("playIndex", 0);
initMediaPlayer();
libs = new MusicLibs();
@ -78,7 +82,9 @@ public class MusicContainer {
System.out.println("自动播放完成,进行下一曲");
playTimer.cancel();
playTimer = null;
browserHelper.getTransportControls().skipToNext();
for (MediaBrowserHelper browserHelper : browserHelpers) {
browserHelper.getTransportControls().skipToNext();
}
}
}
});
@ -113,8 +119,11 @@ public class MusicContainer {
this.nowPlayData = musicData;
}
public void setBrowserHelper(MediaBrowserHelper browserHelper) {
this.browserHelper = browserHelper;
public void addBrowserHelper(MediaBrowserHelper browserHelper) {
browserHelpers.add(browserHelper);
}
public void removeBrowserHelper(MediaBrowserHelper browserHelper){
browserHelpers.remove(browserHelper);
}
public static MusicContainer getInstance() {
@ -335,6 +344,16 @@ public class MusicContainer {
}
return libs.mainData;
}
public List<MusicData> getTmpPlayList(){
return tmpList;
}
public LinkedHashMap<String,List<MusicData>> getAllAlbumMapList(){
return albumMapList;
}
public LinkedHashMap<String,List<MusicData>> getAllArtistMapList(){
return artistMapList;
}
public class MusicLibs {
private List<MusicData> mainData;
@ -364,6 +383,7 @@ public class MusicContainer {
System.out.println(mainDatum.getFile());
}
}
updateLibsMap();
if (initInterface != null) {
initInterface.init();
initInterface = null;
@ -377,7 +397,26 @@ public class MusicContainer {
}
});
}
public void updateLibsMap(){
for (MusicData musicData : mainData) {
List<MusicData> artist;
List<MusicData> album;
if(artistMapList.containsKey(musicData.getArtist())){
artist=artistMapList.get(musicData.getArtist());
}else{
artist=new ArrayList<>();
}
if(albumMapList.containsKey(musicData.getAlbum())){
album=albumMapList.get(musicData.getAlbum());
}else{
album=new ArrayList<>();
}
artist.add(musicData);
album.add(musicData);
albumMapList.put(musicData.getAlbum(),album);
artistMapList.put(musicData.getArtist(),artist);
}
}
public MusicData findMusic(String md5,List<MusicData> list) {
for (MusicData data : list) {
if (data.getMd5() == null) {

View File

@ -5,6 +5,11 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import com.kaopiz.kprogresshud.KProgressHUD;
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.yutou.nas_music_player.R;
import java.io.File;
import java.io.FileNotFoundException;
@ -51,7 +56,7 @@ public class AppTools {
}
public static Bitmap getSaveBitmap(String saveKey){
String path=ConfigTools.getPreferences().getString(getMD5(saveKey),null);
String path=ConfigTools.getPreferences().getString("img_"+getMD5(saveKey),null);
if(path==null){
return null;
}
@ -82,5 +87,27 @@ public class AppTools {
}
return stringBuilder.toString();
}
private static DisplayImageOptions initDisplayOptions() {
DisplayImageOptions.Builder displayImageOptionsBuilder = new DisplayImageOptions.Builder();
displayImageOptionsBuilder.cacheInMemory(false);
displayImageOptionsBuilder.cacheOnDisk(true);
displayImageOptionsBuilder.showImageForEmptyUri(R.drawable.ic_launcher_background);
displayImageOptionsBuilder.showImageOnFail(R.mipmap.ic_launcher);
return displayImageOptionsBuilder.build();
}
public static ImageLoader initImageLoader(Context context) {
ImageLoader imageLoader = ImageLoader.getInstance();
ImageLoaderConfiguration.Builder builder = new ImageLoaderConfiguration.Builder(context);
File cachePath = new File(context.getFilesDir().getAbsolutePath() + "/cache/");
if (!cachePath.exists()) {
cachePath.exists();
}
builder.diskCache(new UnlimitedDiskCache(cachePath));
builder.defaultDisplayImageOptions(initDisplayOptions());
imageLoader.init(builder.build());
return imageLoader;
}
}

View File

@ -0,0 +1,20 @@
package com.yutou.nas_music_player.tools
class Helpers {
companion object {
fun sectionsHelper(sections: MutableList<String>, test: ArrayList<String>): HashMap<Int, Int> {
val mapOfSections = hashMapOf<Int, Int>()
var lastFound = 0
test.forEachIndexed { index, s ->
if (sections.any { it == s }) {
val value = sections.indexOfFirst { it == s }
mapOfSections[index] = value
lastFound = value
} else {
mapOfSections[index] = lastFound
}
}
return mapOfSections
}
}
}

View File

@ -0,0 +1,60 @@
package com.yutou.nas_music_player.views.Fragments;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItem;
import com.yutou.nas_music_player.Adapters.MusicLibsAdapter;
import com.yutou.nas_music_player.R;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import java.util.HashMap;
import java.util.Map;
import in.myinnos.alphabetsindexfastscrollrecycler.IndexFastScrollRecyclerView;
public class MusicLibsFragment extends Fragment {
public static Map<Integer, MusicLibsFragment> map = new HashMap<>();
private Context context;
private View view;
private IndexFastScrollRecyclerView recyclerView;
private int model=1;
public MusicLibsFragment(){
}
public MusicLibsFragment(Context context,int model){
this.context=context;
this.model=model;
}
public void setModel(int model){
this.model=model;
adapter.initData(model);
adapter.notifyDataSetChanged();
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_music_libs,null);
int id = FragmentPagerItem.getPosition(getArguments());
if (!map.containsKey(id)) {
map.put(id, this);
}
initViews();
return view;
}
private MusicLibsAdapter adapter;
public void initViews(){
recyclerView=view.findViewById(R.id.fast_scroller_recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
adapter=new MusicLibsAdapter(model);
recyclerView.setAdapter(adapter);
}
}

View File

@ -5,7 +5,6 @@ import androidx.core.app.ActivityOptionsCompat;
import androidx.core.util.Pair;
import android.annotation.SuppressLint;
import android.app.ActivityOptions;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
@ -34,7 +33,6 @@ import com.yutou.nas_music_player.tools.AppData;
import com.yutou.nas_music_player.tools.AppTools;
import com.yutou.nas_music_player.tools.ConfigTools;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
@ -188,11 +186,20 @@ public class MainActivity extends AppCompatActivity {
Pair<View, String> pNext = Pair.create((View) next, "next");
Pair<View, String> pTitle = Pair.create((View) title, "title");
Pair<View, String> pArtist = Pair.create((View) artist, "artist");
Pair<View, String> pBar = Pair.create((View) seekBar, "bar");
//ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this,list);
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, pImage, pPrevious, pPlay, pNext, pTitle, pArtist).toBundle();
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this,
pImage,
pPrevious,
pPlay,
pNext,
pBar,
pTitle,
pArtist).toBundle();
Intent intent = new Intent(
MainActivity.this, PlayLibsActivity.class);
intent.putExtra("bar_pos",seekBar.getProgress());
if (bundle != null) {
startActivity(intent, bundle);
} else {
@ -297,9 +304,9 @@ public class MainActivity extends AppCompatActivity {
}
private void initView() {
play = findViewById(R.id.play);
next = findViewById(R.id.next);
previous = findViewById(R.id.previous);
play = findViewById(R.id.collection);
next = findViewById(R.id.top);
previous = findViewById(R.id.dislike);
album_image = findViewById(R.id.album_image);
background_image = findViewById(R.id.background_image);
title = findViewById(R.id.title);
@ -317,6 +324,16 @@ public class MainActivity extends AppCompatActivity {
getWindow().setNavigationBarColor(color);
}
@Override
protected void onDestroy() {
super.onDestroy();
if(browserHelper!=null){
browserHelper.onStop();
browserHelper=null;
}
finish();
}
private class PlayListener extends MediaControllerCompat.Callback {
@SuppressLint("SetTextI18n")
@Override

View File

@ -2,74 +2,168 @@ package com.yutou.nas_music_player.views;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.view.View;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.ProgressBar;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.ogaclejapan.smarttablayout.SmartTabLayout;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItemAdapter;
import com.ogaclejapan.smarttablayout.utils.v4.FragmentPagerItems;
import com.yutou.nas_music_player.Adapters.MusicLibsAdapter;
import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.R;
import com.yutou.nas_music_player.containers.MediaBrowserHelper;
import com.yutou.nas_music_player.containers.MusicContainer;
import com.yutou.nas_music_player.tools.AppData;
import com.yutou.nas_music_player.tools.ConfigTools;
import com.yutou.nas_music_player.views.Fragments.MusicLibsFragment;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;
import cc.ibooker.ztextviewlib.MarqueeTextView;
import jp.wasabeef.glide.transformations.BlurTransformation;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
public class PlayLibsActivity extends AppCompatActivity {
private ImageButton play, previous, next;
private ProgressBar progressBar;
private MediaBrowserHelper browserHelper;
private ImageView album_image;
private MarqueeTextView title, artist;
private PlayListener playListener;
private MarqueeTextView title, artist;
private Handler handler;
private int bar_pos=0;
private SmartTabLayout tabLayout;
private ViewPager viewPager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_list);
initView();
bar_pos=getIntent().getIntExtra("bar_pos",0);
setPlayData(MusicContainer.getInstance().getNowPlayData());
browserHelper = new MediaBrowserHelper(this);
playListener=new PlayListener();
PlayListener playListener = new PlayListener();
browserHelper.regPlayListener(playListener);
handler = new Handler();
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.post(new Runnable() {
@Override
public void run() {
if (browserHelper.isPlayer()) {
browserHelper.getTransportControls().pause();
} else {
browserHelper.getTransportControls().play();
}
}
});
}
});
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.post(new Runnable() {
@Override
public void run() {
browserHelper.getTransportControls().skipToNext();
}
});
}
});
previous.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.post(new Runnable() {
@Override
public void run() {
browserHelper.getTransportControls().skipToPrevious();
}
});
}
});
}
private void initView() {
play = findViewById(R.id.play);
next = findViewById(R.id.next);
previous = findViewById(R.id.previous);
play = findViewById(R.id.collection);
next = findViewById(R.id.top);
previous = findViewById(R.id.dislike);
album_image = findViewById(R.id.album_image);
title = findViewById(R.id.title);
artist = findViewById(R.id.artist);
progressBar = findViewById(R.id.progressBar);
tabLayout = findViewById(R.id.viewpagertab);
viewPager = findViewById(R.id.viewpager);
FragmentPagerItemAdapter adapter = new FragmentPagerItemAdapter(
getSupportFragmentManager(), FragmentPagerItems.with(this)
.add("全部", MusicLibsFragment.class)
.add("专辑", MusicLibsFragment.class)
.create());
viewPager.setAdapter(adapter);
tabLayout.setViewPager(viewPager);
tabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
MusicLibsFragment fragment = MusicLibsFragment.map.get(position);
if (fragment != null) {
switch (position){
case 0:
fragment.setModel(MusicLibsAdapter.LIBS_MODEL_ALL);
break;
case 1:
fragment.setModel(MusicLibsAdapter.LIBS_MODEL_Album);
break;
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void setImage(MusicData data) {
album_image.setImageBitmap(data.getImg());
Glide.with(this).load(data.getImg())
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(album_image);
}
@SuppressLint("SetTextI18n")
private void setPlayData(final MusicData data) {
System.out.println("设置歌曲");
System.out.println(data);
if (data == null)
return;
title.setText(data.getTitle());
artist.setText(data.getArtist());
progressBar.setMax((int) (data.getDurationAsDouble() * 1000));
progressBar.setProgress(bar_pos);
if (data.getImg() != null) {
setImage(data);
} else {
@ -94,16 +188,19 @@ public class PlayLibsActivity extends AppCompatActivity {
@Override
protected void onDestroy() {
super.onDestroy();
browserHelper=null;
browserHelper.onStop();
browserHelper = null;
finish();
}
private class PlayListener extends MediaControllerCompat.Callback {
@SuppressLint("SetTextI18n")
@Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
super.onPlaybackStateChanged(state);
if (state.getState() == PlaybackStateCompat.STATE_PLAYING) {
progressBar.setProgress((int) (state.getPosition()));
play.setImageResource(android.R.drawable.ic_media_pause);
} else {
play.setImageResource(android.R.drawable.ic_media_play);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 994 B

View File

@ -124,7 +124,8 @@
android:max="100"
android:progressBackgroundTintMode="add"
android:progressTint="#EC1E1E"
android:textColor="@color/colorBlack" />
android:textColor="@color/colorBlack"
android:transitionName="bar" />
</LinearLayout>
@ -148,7 +149,7 @@
app:srcCompat="@drawable/ic_play_random" />
<ImageButton
android:id="@+id/previous"
android:id="@+id/dislike"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -157,7 +158,7 @@
android:transitionName="previous" />
<ImageButton
android:id="@+id/play"
android:id="@+id/collection"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -165,7 +166,7 @@
android:transitionName="play" />
<ImageButton
android:id="@+id/next"
android:id="@+id/top"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center"

View File

@ -0,0 +1,11 @@
<?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">
<in.myinnos.alphabetsindexfastscrollrecycler.IndexFastScrollRecyclerView
android:id="@+id/fast_scroller_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/album_image"
android:layout_width="64dp"
android:layout_height="64dp"
android:transitionName="album_image"
app:srcCompat="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="120dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<cc.ibooker.ztextviewlib.MarqueeTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:shadowColor="@color/textColorGray"
android:shadowDx="5"
android:shadowDy="5"
android:shadowRadius="1"
android:text="TextView"
android:textColor="@color/colorBlack"
android:transitionName="title" />
<cc.ibooker.ztextviewlib.MarqueeTextView
android:id="@+id/artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:textSize="10sp"
android:layout_marginTop="2dp"
android:shadowColor="@color/textColorGray"
android:shadowDx="5"
android:shadowDy="5"
android:shadowRadius="1"
android:text="TextView"
android:textColor="@color/colorBlack"
android:transitionName="artist" />
<cc.ibooker.ztextviewlib.MarqueeTextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="2dp"
android:shadowColor="@color/textColorGray"
android:shadowDx="5"
android:shadowDy="5"
android:shadowRadius="1"
android:textSize="8sp"
android:text="TextView"
android:textColor="@color/colorBlack"
android:transitionName="artist" />
</LinearLayout>
<LinearLayout
android:id="@+id/buttons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:gravity="end"
android:orientation="horizontal">
<ImageButton
android:id="@+id/dislike"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:transitionName="previous"
app:srcCompat="@drawable/ic_dislike" />
<ImageButton
android:id="@+id/collection"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:transitionName="play"
app:srcCompat="@drawable/ic_collection" />
<ImageButton
android:id="@+id/top"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_marginEnd="10dp"
android:scaleType="fitCenter"
android:transitionName="next"
app:srcCompat="@drawable/ic_top" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@ -3,89 +3,108 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/album_image"
android:layout_width="64dp"
android:layout_height="64dp"
android:transitionName="album_image"
app:srcCompat="@mipmap/ic_launcher" />
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="120dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<cc.ibooker.ztextviewlib.MarqueeTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:shadowColor="@color/textColorGray"
android:shadowDx="5"
android:shadowDy="5"
android:shadowRadius="1"
android:text="TextView"
android:textColor="@color/colorBlack"
android:transitionName="title" />
<cc.ibooker.ztextviewlib.MarqueeTextView
android:id="@+id/artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:shadowColor="@color/textColorGray"
android:shadowDx="5"
android:shadowDy="5"
android:shadowRadius="1"
android:text="TextView"
android:textColor="@color/colorBlack"
android:transitionName="artist" />
</LinearLayout>
<ImageView
android:id="@+id/album_image"
android:layout_width="64dp"
android:layout_height="64dp"
android:transitionName="album_image"
app:srcCompat="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="end"
android:gravity="end"
android:orientation="horizontal">
<ImageButton
android:id="@+id/previous"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:transitionName="previous"
app:srcCompat="@android:drawable/ic_media_previous" />
<LinearLayout
android:layout_width="120dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<ImageButton
android:id="@+id/play"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:transitionName="play"
app:srcCompat="@android:drawable/ic_media_play" />
<cc.ibooker.ztextviewlib.MarqueeTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:shadowColor="@color/textColorGray"
android:shadowDx="5"
android:shadowDy="5"
android:shadowRadius="1"
android:text="TextView"
android:textColor="@color/colorBlack"
android:transitionName="title" />
<ImageButton
android:id="@+id/next"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_marginEnd="10dp"
android:scaleType="fitCenter"
android:transitionName="next"
app:srcCompat="@android:drawable/ic_media_next" />
<cc.ibooker.ztextviewlib.MarqueeTextView
android:id="@+id/artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:shadowColor="@color/textColorGray"
android:shadowDx="5"
android:shadowDy="5"
android:shadowRadius="1"
android:text="TextView"
android:textColor="@color/colorBlack"
android:transitionName="artist" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:gravity="end"
android:orientation="horizontal">
<ImageButton
android:id="@+id/dislike"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:transitionName="previous"
app:srcCompat="@android:drawable/ic_media_previous" />
<ImageButton
android:id="@+id/collection"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:transitionName="play"
app:srcCompat="@android:drawable/ic_media_play" />
<ImageButton
android:id="@+id/top"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_marginEnd="10dp"
android:scaleType="fitCenter"
android:transitionName="next"
app:srcCompat="@android:drawable/ic_media_next" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#000E0A0A"
android:backgroundTint="#D12828"
android:elevation="6dp"
android:progressTint="#EC1E1E"
android:textColor="@color/colorBlack"
android:transitionName="bar" />
</LinearLayout>

View File

@ -1,5 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.4.10"
repositories {
google()
jcenter()
@ -7,6 +9,9 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}

View File

@ -16,4 +16,6 @@ org.gradle.jvmargs=-Xmx2048m
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
android.enableJetifier=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official