Initial commit retro music app
This commit is contained in:
parent
ab332473bc
commit
fe890632fd
932 changed files with 83126 additions and 0 deletions
|
@ -0,0 +1,167 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.v4.app.ShareCompat;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.Constants;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.RetroApplication;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.APP_INSTAGRAM_LINK;
|
||||
import static code.name.monkey.retromusic.Constants.APP_TWITTER_LINK;
|
||||
import static code.name.monkey.retromusic.Constants.GITHUB_PROJECT;
|
||||
import static code.name.monkey.retromusic.Constants.GOOGLE_PLUS_COMMUNITY;
|
||||
import static code.name.monkey.retromusic.Constants.RATE_ON_GOOGLE_PLAY;
|
||||
import static code.name.monkey.retromusic.Constants.TELEGRAM_CHANGE_LOG;
|
||||
import static code.name.monkey.retromusic.Constants.TRANSLATE;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13)
|
||||
*/
|
||||
|
||||
public class AboutActivity extends AbsBaseActivity {
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appBar;
|
||||
@BindView(R.id.buy_pro)
|
||||
TextView supportText;
|
||||
@BindView(R.id.app_version)
|
||||
TextView appVersion;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_about);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
setUpToolbar();
|
||||
|
||||
appVersion.setText(getAppVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void setUpToolbar() {
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
appBar.setBackgroundColor(primaryColor);
|
||||
setTitle(R.string.action_about);
|
||||
setSupportActionBar(toolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
supportText.setText(RetroApplication.isProVersion() ? R.string.thank_you : R.string.buy_retromusic_pro);
|
||||
}
|
||||
|
||||
|
||||
private void openUrl(String url) {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse(url));
|
||||
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(i);
|
||||
}
|
||||
|
||||
|
||||
@OnClick({R.id.app_github, R.id.faq_link,
|
||||
R.id.app_google_plus, R.id.app_translation,
|
||||
R.id.support_container, R.id.app_rate, R.id.app_share, R.id.pro_container,
|
||||
R.id.instagram_link, R.id.twitter_link, R.id.changelog,
|
||||
R.id.open_source, R.id.discord_link, R.id.telegram_link})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.faq_link:
|
||||
openUrl(Constants.FAQ_LINK);
|
||||
break;
|
||||
case R.id.telegram_link:
|
||||
openUrl(Constants.APP_TELEGRAM_LINK);
|
||||
break;
|
||||
case R.id.discord_link:
|
||||
openUrl(Constants.DISCORD_LINK);
|
||||
break;
|
||||
case R.id.app_github:
|
||||
openUrl(GITHUB_PROJECT);
|
||||
break;
|
||||
case R.id.app_google_plus:
|
||||
openUrl(GOOGLE_PLUS_COMMUNITY);
|
||||
break;
|
||||
case R.id.support_container:
|
||||
startActivity(new Intent(this, SupportDevelopmentActivity.class));
|
||||
break;
|
||||
case R.id.app_translation:
|
||||
openUrl(TRANSLATE);
|
||||
break;
|
||||
case R.id.app_rate:
|
||||
openUrl(RATE_ON_GOOGLE_PLAY);
|
||||
break;
|
||||
case R.id.app_share:
|
||||
shareApp();
|
||||
break;
|
||||
case R.id.pro_container:
|
||||
NavigationUtil.goToProVersion(this);
|
||||
break;
|
||||
|
||||
case R.id.instagram_link:
|
||||
openUrl(APP_INSTAGRAM_LINK);
|
||||
break;
|
||||
case R.id.twitter_link:
|
||||
openUrl(APP_TWITTER_LINK);
|
||||
break;
|
||||
case R.id.changelog:
|
||||
openUrl(TELEGRAM_CHANGE_LOG);
|
||||
break;
|
||||
case R.id.open_source:
|
||||
NavigationUtil.goToOpenSource(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private String getAppVersion() {
|
||||
try {
|
||||
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
|
||||
return packageInfo.versionName;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return "0.0.0";
|
||||
}
|
||||
}
|
||||
|
||||
private void shareApp() {
|
||||
Intent shareIntent = ShareCompat.IntentBuilder.from(this)
|
||||
.setType("songText/plain")
|
||||
.setText(String.format(getString(R.string.app_share), getPackageName()))
|
||||
.getIntent();
|
||||
if (shareIntent.resolveActivity(getPackageManager()) != null) {
|
||||
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.action_share)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,414 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.CollapsingToolbarLayout;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.widget.NestedScrollView;
|
||||
import android.support.v7.widget.AppCompatTextView;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog;
|
||||
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog;
|
||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder;
|
||||
import code.name.monkey.retromusic.loaders.ArtistLoader;
|
||||
import code.name.monkey.retromusic.misc.AppBarStateChangeListener;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.contract.AlbumDetailsContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsPresenter;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import code.name.monkey.retromusic.ui.activities.tageditor.AbsTagEditorActivity;
|
||||
import code.name.monkey.retromusic.ui.activities.tageditor.AlbumTagEditorActivity;
|
||||
import code.name.monkey.retromusic.ui.adapter.album.AlbumAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.album.HorizontalAlbumAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.SimpleSongAdapter;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
public class AlbumDetailsActivity extends AbsSlidingMusicPanelActivity implements
|
||||
AlbumDetailsContract.AlbumDetailsView {
|
||||
|
||||
public static final String EXTRA_ALBUM_ID = "extra_album_id";
|
||||
private static final int TAG_EDITOR_REQUEST = 2001;
|
||||
@BindView(R.id.image)
|
||||
ImageView image;
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.song_title)
|
||||
AppCompatTextView songTitle;
|
||||
@BindView(R.id.action_shuffle_all)
|
||||
FloatingActionButton shuffleButton;
|
||||
@BindView(R.id.collapsing_toolbar)
|
||||
@Nullable
|
||||
CollapsingToolbarLayout collapsingToolbarLayout;
|
||||
@BindView(R.id.app_bar)
|
||||
@Nullable
|
||||
AppBarLayout appBarLayout;
|
||||
@BindView(R.id.image_container)
|
||||
@Nullable
|
||||
View imageContainer;
|
||||
@BindView(R.id.content)
|
||||
View contentContainer;
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.more_recycler_view)
|
||||
RecyclerView moreRecyclerView;
|
||||
@BindView(R.id.more_title)
|
||||
TextView moreTitle;
|
||||
@BindView(R.id.artist_image)
|
||||
ImageView artistImage;
|
||||
|
||||
private AlbumDetailsPresenter albumDetailsPresenter;
|
||||
private Album album;
|
||||
private SimpleSongAdapter adapter;
|
||||
|
||||
@Override
|
||||
protected View createContentView() {
|
||||
return wrapSlidingMusicPanel(R.layout.activity_album);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setDrawUnderStatusbar(true);
|
||||
super.onCreate(savedInstanceState);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
supportPostponeEnterTransition();
|
||||
setupToolbarMarginHeight();
|
||||
setBottomBarVisibility(View.GONE);
|
||||
setLightNavigationBar(true);
|
||||
setNavigationbarColorAuto();
|
||||
|
||||
int albumId = getIntent().getIntExtra(EXTRA_ALBUM_ID, -1);
|
||||
albumDetailsPresenter = new AlbumDetailsPresenter(this, albumId);
|
||||
|
||||
}
|
||||
|
||||
private void setupToolbarMarginHeight() {
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
TintHelper.setTintAuto(contentContainer, primaryColor, true);
|
||||
if (collapsingToolbarLayout != null) {
|
||||
collapsingToolbarLayout.setContentScrimColor(primaryColor);
|
||||
collapsingToolbarLayout.setStatusBarScrimColor(ColorUtil.darkenColor(primaryColor));
|
||||
}
|
||||
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
setSupportActionBar(toolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setTitle(null);
|
||||
|
||||
if (toolbar != null && !PreferenceUtil.getInstance(this).getFullScreenMode()) {
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams();
|
||||
params.topMargin = RetroUtil.getStatusBarHeight(this);
|
||||
toolbar.setLayoutParams(params);
|
||||
}
|
||||
|
||||
if (appBarLayout != null) {
|
||||
appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
|
||||
@Override
|
||||
public void onStateChanged(AppBarLayout appBarLayout, State state) {
|
||||
int color;
|
||||
switch (state) {
|
||||
case COLLAPSED:
|
||||
setLightStatusbar(!ATHUtil.isWindowBackgroundDark(AlbumDetailsActivity.this));
|
||||
color = ATHUtil.resolveColor(AlbumDetailsActivity.this, R.attr.iconColor);
|
||||
break;
|
||||
default:
|
||||
case EXPANDED:
|
||||
case IDLE:
|
||||
setLightStatusbar(false);
|
||||
color = ContextCompat.getColor(AlbumDetailsActivity.this, R.color.md_white_1000);
|
||||
break;
|
||||
}
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, color, AlbumDetailsActivity.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OnClick({R.id.action_shuffle_all})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.menu_close:
|
||||
onBackPressed();
|
||||
break;
|
||||
case R.id.menu:
|
||||
PopupMenu popupMenu = new PopupMenu(this, view);
|
||||
popupMenu.inflate(R.menu.menu_album_detail);
|
||||
MenuItem sortOrder = popupMenu.getMenu().findItem(R.id.action_sort_order);
|
||||
setUpSortOrderMenu(sortOrder.getSubMenu());
|
||||
popupMenu.setOnMenuItemClickListener(this::onOptionsItemSelected);
|
||||
popupMenu.show();
|
||||
break;
|
||||
case R.id.action_shuffle_all:
|
||||
MusicPlayerRemote.openAndShuffleQueue(album.songs, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
albumDetailsPresenter.subscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
albumDetailsPresenter.unsubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
supportStartPostponedEnterTransition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(Album album) {
|
||||
if (album.songs.isEmpty()) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
this.album = album;
|
||||
|
||||
title.setText(album.getTitle());
|
||||
text.setText(String.format("%s%s • %s", album.getArtistName(), " • " + MusicUtil.getYearString(album.getYear()),
|
||||
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(this, album.songs))));
|
||||
|
||||
loadAlbumCover();
|
||||
|
||||
adapter = new SimpleSongAdapter(this, this.album.songs, R.layout.item_song);
|
||||
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setItemAnimator(new DefaultItemAnimator());
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.setNestedScrollingEnabled(false);
|
||||
|
||||
loadMoreFrom(album);
|
||||
|
||||
}
|
||||
|
||||
private void loadMoreFrom(Album album) {
|
||||
|
||||
ArtistGlideRequest.Builder.from(Glide.with(this),
|
||||
ArtistLoader.getArtist(this, album.getArtistId()).blockingFirst())
|
||||
.forceDownload(true)
|
||||
.generatePalette(this).build()
|
||||
.dontAnimate()
|
||||
.into(new RetroMusicColoredTarget(artistImage) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
setColors(color);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
ArrayList<Album> albums = ArtistLoader.getArtist(this, album.getArtistId()).blockingFirst().albums;
|
||||
albums.remove(album);
|
||||
if (!albums.isEmpty()) {
|
||||
moreTitle.setVisibility(View.VISIBLE);
|
||||
moreRecyclerView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
moreTitle.setText(String.format("More from %s", album.getArtistName()));
|
||||
|
||||
AlbumAdapter albumAdapter = new HorizontalAlbumAdapter(this, albums,
|
||||
false, null);
|
||||
moreRecyclerView.setLayoutManager(new GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false));
|
||||
moreRecyclerView.setAdapter(albumAdapter);
|
||||
}
|
||||
|
||||
public Album getAlbum() {
|
||||
return album;
|
||||
}
|
||||
|
||||
private void loadAlbumCover() {
|
||||
SongGlideRequest.Builder.from(Glide.with(this), getAlbum().safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(this)
|
||||
.generatePalette(this).build()
|
||||
.dontAnimate()
|
||||
.listener(new RequestListener<Object, BitmapPaletteWrapper>() {
|
||||
@Override
|
||||
public boolean onException(Exception e, Object model, Target<BitmapPaletteWrapper> target,
|
||||
boolean isFirstResource) {
|
||||
supportStartPostponedEnterTransition();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(BitmapPaletteWrapper resource, Object model,
|
||||
Target<BitmapPaletteWrapper> target, boolean isFromMemoryCache,
|
||||
boolean isFirstResource) {
|
||||
supportStartPostponedEnterTransition();
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(new RetroMusicColoredTarget(image) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
setColors(color);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setColors(int color) {
|
||||
int themeColor = PreferenceUtil.getInstance(this).getAdaptiveColor() ? color : ThemeStore.accentColor(this);
|
||||
songTitle.setTextColor(themeColor);
|
||||
moreTitle.setTextColor(themeColor);
|
||||
|
||||
TintHelper.setTintAuto(shuffleButton, themeColor, true);
|
||||
findViewById(R.id.root).setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_album_detail, menu);
|
||||
MenuItem sortOrder = menu.findItem(R.id.action_sort_order);
|
||||
setUpSortOrderMenu(sortOrder.getSubMenu());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
return handleSortOrderMenuItem(item);
|
||||
}
|
||||
|
||||
private boolean handleSortOrderMenuItem(@NonNull MenuItem item) {
|
||||
String sortOrder = null;
|
||||
final ArrayList<Song> songs = adapter.getDataSet();
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_play_next:
|
||||
MusicPlayerRemote.playNext(songs);
|
||||
return true;
|
||||
case R.id.action_add_to_current_playing:
|
||||
MusicPlayerRemote.enqueue(songs);
|
||||
return true;
|
||||
case R.id.action_add_to_playlist:
|
||||
AddToPlaylistDialog.create(songs).show(getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||
return true;
|
||||
case R.id.action_delete_from_device:
|
||||
DeleteSongsDialog.create(songs).show(getSupportFragmentManager(), "DELETE_SONGS");
|
||||
return true;
|
||||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_tag_editor:
|
||||
Intent intent = new Intent(this, AlbumTagEditorActivity.class);
|
||||
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, getAlbum().getId());
|
||||
startActivityForResult(intent, TAG_EDITOR_REQUEST);
|
||||
return true;
|
||||
case R.id.action_go_to_artist:
|
||||
NavigationUtil.goToArtist(this, getAlbum().getArtistId());
|
||||
return true;
|
||||
/*Sort*/
|
||||
case R.id.action_sort_order_title:
|
||||
sortOrder = AlbumSongSortOrder.SONG_A_Z;
|
||||
break;
|
||||
case R.id.action_sort_order_title_desc:
|
||||
sortOrder = AlbumSongSortOrder.SONG_Z_A;
|
||||
break;
|
||||
case R.id.action_sort_order_track_list:
|
||||
sortOrder = AlbumSongSortOrder.SONG_TRACK_LIST;
|
||||
break;
|
||||
case R.id.action_sort_order_artist_song_duration:
|
||||
sortOrder = AlbumSongSortOrder.SONG_DURATION;
|
||||
break;
|
||||
}
|
||||
if (sortOrder != null) {
|
||||
item.setChecked(true);
|
||||
setSaveSortOrder(sortOrder);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getSavedSortOrder() {
|
||||
return PreferenceUtil.getInstance(this).getAlbumDetailSongSortOrder();
|
||||
}
|
||||
|
||||
private void setUpSortOrderMenu(@NonNull SubMenu sortOrder) {
|
||||
switch (getSavedSortOrder()) {
|
||||
case AlbumSongSortOrder.SONG_A_Z:
|
||||
sortOrder.findItem(R.id.action_sort_order_title).setChecked(true);
|
||||
break;
|
||||
case AlbumSongSortOrder.SONG_Z_A:
|
||||
sortOrder.findItem(R.id.action_sort_order_title_desc).setChecked(true);
|
||||
break;
|
||||
case AlbumSongSortOrder.SONG_TRACK_LIST:
|
||||
sortOrder.findItem(R.id.action_sort_order_track_list).setChecked(true);
|
||||
break;
|
||||
case AlbumSongSortOrder.SONG_DURATION:
|
||||
sortOrder.findItem(R.id.action_sort_order_artist_song_duration).setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setSaveSortOrder(String sortOrder) {
|
||||
PreferenceUtil.getInstance(this).setAlbumDetailSongSortOrder(sortOrder);
|
||||
reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
super.onMediaStoreChanged();
|
||||
reload();
|
||||
}
|
||||
|
||||
private void reload() {
|
||||
albumDetailsPresenter.subscribe();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,429 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.CollapsingToolbarLayout;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.AppCompatTextView;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Html;
|
||||
import android.text.Spanned;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog;
|
||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.misc.AppBarStateChangeListener;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.contract.ArtistDetailContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter;
|
||||
import code.name.monkey.retromusic.rest.LastFMRestClient;
|
||||
import code.name.monkey.retromusic.rest.model.LastFmArtist;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import code.name.monkey.retromusic.ui.adapter.album.AlbumAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.album.HorizontalAlbumAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.SimpleSongAdapter;
|
||||
import code.name.monkey.retromusic.util.CustomArtistImageUtil;
|
||||
import code.name.monkey.retromusic.util.DensityUtil;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implements
|
||||
ArtistDetailContract.ArtistsDetailsView {
|
||||
|
||||
public static final String EXTRA_ARTIST_ID = "extra_artist_id";
|
||||
private static final int REQUEST_CODE_SELECT_IMAGE = 9003;
|
||||
@BindView(R.id.image)
|
||||
ImageView image;
|
||||
@BindView(R.id.biography)
|
||||
TextView biographyTextView;
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
@BindView(R.id.album_recycler_view)
|
||||
RecyclerView albumRecyclerView;
|
||||
@BindView(R.id.album_title)
|
||||
AppCompatTextView albumTitle;
|
||||
@BindView(R.id.song_title)
|
||||
AppCompatTextView songTitle;
|
||||
@BindView(R.id.biography_title)
|
||||
AppCompatTextView biographyTitle;
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.action_shuffle_all)
|
||||
FloatingActionButton shuffleButton;
|
||||
@BindView(R.id.collapsing_toolbar)
|
||||
@Nullable
|
||||
CollapsingToolbarLayout collapsingToolbarLayout;
|
||||
@BindView(R.id.app_bar)
|
||||
@Nullable
|
||||
AppBarLayout appBarLayout;
|
||||
@BindView(R.id.gradient_background)
|
||||
@Nullable
|
||||
View background;
|
||||
@BindView(R.id.image_container)
|
||||
@Nullable
|
||||
View imageContainer;
|
||||
@BindView(R.id.content)
|
||||
View contentContainer;
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@Nullable
|
||||
private Spanned biography;
|
||||
private Artist artist;
|
||||
private LastFMRestClient lastFMRestClient;
|
||||
private ArtistDetailsPresenter artistDetailsPresenter;
|
||||
private SimpleSongAdapter songAdapter;
|
||||
private AlbumAdapter albumAdapter;
|
||||
private boolean forceDownload;
|
||||
|
||||
@Override
|
||||
protected View createContentView() {
|
||||
return wrapSlidingMusicPanel(R.layout.activity_artist_details);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
setDrawUnderStatusbar(true);
|
||||
super.onCreate(bundle);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
supportPostponeEnterTransition();
|
||||
setBottomBarVisibility(View.GONE);
|
||||
setNavigationbarColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
lastFMRestClient = new LastFMRestClient(this);
|
||||
|
||||
setUpViews();
|
||||
|
||||
int artistID = getIntent().getIntExtra(EXTRA_ARTIST_ID, -1);
|
||||
artistDetailsPresenter = new ArtistDetailsPresenter(this, artistID);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
setupRecyclerView();
|
||||
setupToolbar();
|
||||
setupContainerHeight();
|
||||
}
|
||||
|
||||
private void setupContainerHeight() {
|
||||
if (imageContainer != null) {
|
||||
LayoutParams params = imageContainer.getLayoutParams();
|
||||
params.width = DensityUtil.getScreenHeight(this) / 2;
|
||||
imageContainer.setLayoutParams(params);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupToolbar() {
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
setSupportActionBar(toolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setTitle(null);
|
||||
|
||||
|
||||
if (toolbar != null && !PreferenceUtil.getInstance(this).getFullScreenMode()) {
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams();
|
||||
params.topMargin = RetroUtil.getStatusBarHeight(this);
|
||||
toolbar.setLayoutParams(params);
|
||||
}
|
||||
|
||||
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
TintHelper.setTintAuto(contentContainer, primaryColor, true);
|
||||
|
||||
if (appBarLayout != null) {
|
||||
appBarLayout.setBackgroundColor(primaryColor);
|
||||
appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
|
||||
@Override
|
||||
public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) {
|
||||
int color;
|
||||
switch (state) {
|
||||
case COLLAPSED:
|
||||
setLightStatusbar(!ATHUtil.isWindowBackgroundDark(ArtistDetailActivity.this));
|
||||
color = ATHUtil.resolveColor(ArtistDetailActivity.this, R.attr.iconColor);
|
||||
break;
|
||||
default:
|
||||
case EXPANDED:
|
||||
case IDLE:
|
||||
setLightStatusbar(false);
|
||||
color = ContextCompat.getColor(ArtistDetailActivity.this, R.color.md_white_1000);
|
||||
break;
|
||||
}
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, color, ArtistDetailActivity.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (collapsingToolbarLayout != null) {
|
||||
collapsingToolbarLayout.setContentScrimColor(primaryColor);
|
||||
collapsingToolbarLayout.setStatusBarScrimColor(ColorUtil.darkenColor(primaryColor));
|
||||
}
|
||||
}
|
||||
|
||||
private void setupRecyclerView() {
|
||||
albumAdapter = new HorizontalAlbumAdapter(this, new ArrayList<>(), false, null);
|
||||
albumRecyclerView.setItemAnimator(new DefaultItemAnimator());
|
||||
albumRecyclerView
|
||||
.setLayoutManager(new GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false));
|
||||
albumRecyclerView.setAdapter(albumAdapter);
|
||||
|
||||
songAdapter = new SimpleSongAdapter(this, new ArrayList<>(), R.layout.item_song);
|
||||
recyclerView.setItemAnimator(new DefaultItemAnimator());
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setAdapter(songAdapter);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case REQUEST_CODE_SELECT_IMAGE:
|
||||
if (resultCode == RESULT_OK) {
|
||||
CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist, data.getData());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (resultCode == RESULT_OK) {
|
||||
reload();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
artistDetailsPresenter.subscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
artistDetailsPresenter.unsubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
supportStartPostponedEnterTransition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(Artist artist) {
|
||||
setArtist(artist);
|
||||
}
|
||||
|
||||
private Artist getArtist() {
|
||||
if (artist == null) {
|
||||
artist = new Artist();
|
||||
}
|
||||
return artist;
|
||||
}
|
||||
|
||||
private void setArtist(Artist artist) {
|
||||
if (artist.getSongCount() <= 0) {
|
||||
finish();
|
||||
}
|
||||
this.artist = artist;
|
||||
loadArtistImage();
|
||||
|
||||
if (RetroUtil.isAllowedToDownloadMetadata(this)) {
|
||||
loadBiography();
|
||||
}
|
||||
title.setText(artist.getName());
|
||||
text.setText(String.format("%s • %s", MusicUtil.getArtistInfoString(this, artist), MusicUtil
|
||||
.getReadableDurationString(MusicUtil.getTotalDuration(this, artist.getSongs()))));
|
||||
|
||||
songAdapter.swapDataSet(artist.getSongs());
|
||||
albumAdapter.swapDataSet(artist.albums);
|
||||
}
|
||||
|
||||
private void loadBiography() {
|
||||
loadBiography(Locale.getDefault().getLanguage());
|
||||
}
|
||||
|
||||
private void loadBiography(@Nullable final String lang) {
|
||||
biography = null;
|
||||
|
||||
lastFMRestClient.getApiService()
|
||||
.getArtistInfo(getArtist().getName(), lang, null)
|
||||
.enqueue(new Callback<LastFmArtist>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<LastFmArtist> call,
|
||||
@NonNull Response<LastFmArtist> response) {
|
||||
final LastFmArtist lastFmArtist = response.body();
|
||||
if (lastFmArtist != null && lastFmArtist.getArtist() != null) {
|
||||
final String bioContent = lastFmArtist.getArtist().getBio().getContent();
|
||||
if (bioContent != null && !bioContent.trim().isEmpty()) {
|
||||
//TransitionManager.beginDelayedTransition(titleContainer);
|
||||
biographyTextView.setVisibility(View.VISIBLE);
|
||||
biographyTitle.setVisibility(View.VISIBLE);
|
||||
biography = Html.fromHtml(bioContent);
|
||||
biographyTextView.setText(biography);
|
||||
}
|
||||
}
|
||||
|
||||
// If the "lang" parameter is set and no biography is given, retry with default language
|
||||
if (biography == null && lang != null) {
|
||||
loadBiography(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<LastFmArtist> call, @NonNull Throwable t) {
|
||||
t.printStackTrace();
|
||||
biography = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@OnClick(R.id.biography)
|
||||
void toggleArtistBiography() {
|
||||
if (biographyTextView.getMaxLines() == 4) {
|
||||
biographyTextView.setMaxLines(Integer.MAX_VALUE);
|
||||
} else {
|
||||
biographyTextView.setMaxLines(4);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadArtistImage() {
|
||||
ArtistGlideRequest.Builder.from(Glide.with(this), artist)
|
||||
.forceDownload(forceDownload)
|
||||
.generatePalette(this).build()
|
||||
.dontAnimate()
|
||||
.into(new RetroMusicColoredTarget(image) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
setColors(color);
|
||||
}
|
||||
});
|
||||
forceDownload = false;
|
||||
}
|
||||
|
||||
private void setColors(int color) {
|
||||
|
||||
int textColor =
|
||||
PreferenceUtil.getInstance(this).getAdaptiveColor() ? color : ThemeStore.accentColor(this);
|
||||
|
||||
albumTitle.setTextColor(textColor);
|
||||
songTitle.setTextColor(textColor);
|
||||
biographyTitle.setTextColor(textColor);
|
||||
|
||||
TintHelper.setTintAuto(shuffleButton, textColor, true);
|
||||
|
||||
if (background != null) {
|
||||
background.setBackgroundTintList(ColorStateList.valueOf(color));
|
||||
}
|
||||
findViewById(R.id.root).setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
@OnClick({R.id.action_shuffle_all})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.action_shuffle_all:
|
||||
MusicPlayerRemote.openAndShuffleQueue(getArtist().getSongs(), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
return handleSortOrderMenuItem(item);
|
||||
}
|
||||
|
||||
private boolean handleSortOrderMenuItem(@NonNull MenuItem item) {
|
||||
final ArrayList<Song> songs = getArtist().getSongs();
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_play_next:
|
||||
MusicPlayerRemote.playNext(songs);
|
||||
return true;
|
||||
case R.id.action_add_to_current_playing:
|
||||
MusicPlayerRemote.enqueue(songs);
|
||||
return true;
|
||||
case R.id.action_add_to_playlist:
|
||||
AddToPlaylistDialog.create(songs).show(getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||
return true;
|
||||
case R.id.action_set_artist_image:
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("image/*");
|
||||
startActivityForResult(
|
||||
Intent.createChooser(intent, getString(R.string.pick_from_local_storage)),
|
||||
REQUEST_CODE_SELECT_IMAGE);
|
||||
return true;
|
||||
case R.id.action_reset_artist_image:
|
||||
Toast.makeText(ArtistDetailActivity.this, getResources().getString(R.string.updating),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
CustomArtistImageUtil.getInstance(ArtistDetailActivity.this).resetCustomArtistImage(artist);
|
||||
forceDownload = true;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_artist_detail, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
super.onMediaStoreChanged();
|
||||
reload();
|
||||
}
|
||||
|
||||
private void reload() {
|
||||
artistDetailsPresenter.unsubscribe();
|
||||
artistDetailsPresenter.subscribe();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.v7.widget.SwitchCompat;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.transition.TransitionManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.EqualizerHelper;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class EqualizerActivity extends AbsMusicServiceActivity implements
|
||||
AdapterView.OnItemSelectedListener {
|
||||
|
||||
@BindView(R.id.equalizer)
|
||||
SwitchCompat mEnable;
|
||||
@BindView(R.id.content)
|
||||
LinearLayout mContent;
|
||||
@BindView(R.id.bands)
|
||||
LinearLayout mLinearLayout;
|
||||
|
||||
@BindView(R.id.bass_boost_strength)
|
||||
SeekBar mBassBoostStrength;
|
||||
@BindView(R.id.virtualizer_strength)
|
||||
SeekBar mVirtualizerStrength;
|
||||
|
||||
@BindView(R.id.bass_boost)
|
||||
TextView mBassBoost;
|
||||
@BindView(R.id.virtualizer)
|
||||
TextView mVirtualizer;
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar mToolbar;
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout mAppBar;
|
||||
@BindView(R.id.presets)
|
||||
Spinner mPresets;
|
||||
|
||||
private CompoundButton.OnCheckedChangeListener mListener = (buttonView, isChecked) -> {
|
||||
switch (buttonView.getId()) {
|
||||
case R.id.equalizer:
|
||||
EqualizerHelper.getInstance().getEqualizer().setEnabled(isChecked);
|
||||
TransitionManager.beginDelayedTransition(mContent);
|
||||
mContent.setVisibility(isChecked ? View.VISIBLE : View.GONE);
|
||||
break;
|
||||
}
|
||||
};
|
||||
private SeekBar.OnSeekBarChangeListener mSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
if (seekBar == mBassBoostStrength) {
|
||||
mBassBoost.setEnabled(progress > 0);
|
||||
EqualizerHelper.getInstance().setBassBoostStrength(progress);
|
||||
EqualizerHelper.getInstance().setBassBoostEnabled(progress > 0);
|
||||
} else if (seekBar == mVirtualizerStrength) {
|
||||
mVirtualizer.setEnabled(progress > 0);
|
||||
EqualizerHelper.getInstance().setVirtualizerEnabled(progress > 0);
|
||||
EqualizerHelper.getInstance().setVirtualizerStrength(progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
};
|
||||
private ArrayAdapter<String> mPresetsNamesAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_equalizer);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
mToolbar.setBackgroundColor(primaryColor);
|
||||
mAppBar.setBackgroundColor(primaryColor);
|
||||
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onBackPressed();
|
||||
}
|
||||
});
|
||||
mToolbar.setTitle(R.string.equalizer);
|
||||
setSupportActionBar(mToolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
mEnable.setChecked(EqualizerHelper.getInstance().getEqualizer().getEnabled());
|
||||
mEnable.setOnCheckedChangeListener(mListener);
|
||||
|
||||
mPresetsNamesAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
|
||||
mPresets.setAdapter(mPresetsNamesAdapter);
|
||||
mPresets.setOnItemSelectedListener(this);
|
||||
|
||||
mBassBoostStrength.setProgress(EqualizerHelper.getInstance().getBassBoostStrength());
|
||||
mBassBoostStrength.setOnSeekBarChangeListener(mSeekBarChangeListener);
|
||||
|
||||
mVirtualizerStrength.setProgress(EqualizerHelper.getInstance().getVirtualizerStrength());
|
||||
mVirtualizerStrength.setOnSeekBarChangeListener(mSeekBarChangeListener);
|
||||
|
||||
setupUI();
|
||||
addPresets();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
||||
}
|
||||
|
||||
private void addPresets() {
|
||||
mPresetsNamesAdapter.clear();
|
||||
mPresetsNamesAdapter.add("Custom");
|
||||
for (int j = 0; j < EqualizerHelper.getInstance().getEqualizer().getNumberOfPresets(); j++) {
|
||||
mPresetsNamesAdapter
|
||||
.add(EqualizerHelper.getInstance().getEqualizer().getPresetName((short) j));
|
||||
mPresetsNamesAdapter.notifyDataSetChanged();
|
||||
}
|
||||
mPresets
|
||||
.setSelection((int) EqualizerHelper.getInstance().getEqualizer().getCurrentPreset() + 1);
|
||||
}
|
||||
|
||||
private void setupUI() {
|
||||
mLinearLayout.removeAllViews();
|
||||
short bands;
|
||||
try {
|
||||
// get number of supported bands
|
||||
bands = (short) EqualizerHelper.getInstance().getNumberOfBands();
|
||||
|
||||
// for each of the supported bands, we will set up a slider from -10dB to 10dB boost/attenuation,
|
||||
// as well as text labels to assist the user
|
||||
for (short i = 0; i < bands; i++) {
|
||||
final short band = i;
|
||||
|
||||
View view = LayoutInflater.from(this).inflate(R.layout.retro_seekbar, mLinearLayout, false);
|
||||
TextView freqTextView = view.findViewById(R.id.hurtz);
|
||||
freqTextView.setText(
|
||||
String.format("%d Hz", EqualizerHelper.getInstance().getCenterFreq((int) band) / 1000));
|
||||
|
||||
TextView minDbTextView = view.findViewById(R.id.minus_db);
|
||||
minDbTextView
|
||||
.setText(String.format("%d dB", EqualizerHelper.getInstance().getBandLevelLow() / 100));
|
||||
|
||||
TextView maxDbTextView = view.findViewById(R.id.plus_db);
|
||||
maxDbTextView.setText(
|
||||
String.format("%d dB", EqualizerHelper.getInstance().getBandLevelHigh() / 100));
|
||||
|
||||
SeekBar bar = view.findViewById(R.id.seekbar);
|
||||
bar.setMax(EqualizerHelper.getInstance().getBandLevelHigh() - EqualizerHelper.getInstance()
|
||||
.getBandLevelLow());
|
||||
bar.setProgress(
|
||||
EqualizerHelper.getInstance().getBandLevel((int) band) - EqualizerHelper.getInstance()
|
||||
.getBandLevelLow());
|
||||
bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
EqualizerHelper.getInstance().setBandLevel((int) band,
|
||||
(int) (progress + EqualizerHelper.getInstance().getBandLevelLow()));
|
||||
if (fromUser) {
|
||||
mPresets.setSelection(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
|
||||
mLinearLayout.addView(view);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (position == 0) {
|
||||
return;
|
||||
}
|
||||
EqualizerHelper.getInstance().getEqualizer().usePreset((short) (position - 1));
|
||||
setupUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.CollapsingToolbarLayout;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.materialcab.MaterialCab;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.menu.GenreMenuHelper;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.misc.AppBarStateChangeListener;
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.contract.GenreDetailsContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.GenreDetailsPresenter;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.SongAdapter;
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class GenreDetailsActivity extends AbsSlidingMusicPanelActivity implements
|
||||
GenreDetailsContract.GenreDetailsView, CabHolder {
|
||||
public static final String EXTRA_GENRE_ID = "extra_genre_id";
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@BindView(android.R.id.empty)
|
||||
TextView empty;
|
||||
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
@BindView(R.id.action_shuffle)
|
||||
FloatingActionButton shuffleButton;
|
||||
|
||||
@BindView(R.id.progress_bar)
|
||||
ProgressBar progressBar;
|
||||
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appBarLayout;
|
||||
|
||||
@BindView(R.id.collapsing_toolbar)
|
||||
CollapsingToolbarLayout toolbarLayout;
|
||||
|
||||
private Genre genre;
|
||||
private GenreDetailsPresenter presenter;
|
||||
private SongAdapter songAdapter;
|
||||
private MaterialCab cab;
|
||||
|
||||
private void checkIsEmpty() {
|
||||
empty.setVisibility(
|
||||
songAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setDrawUnderStatusbar(true);
|
||||
super.onCreate(savedInstanceState);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
setBottomBarVisibility(View.GONE);
|
||||
|
||||
RetroUtil.statusBarHeight(statusBar);
|
||||
|
||||
|
||||
genre = getIntent().getParcelableExtra(EXTRA_GENRE_ID);
|
||||
presenter = new GenreDetailsPresenter(this, genre.id);
|
||||
|
||||
setUpToolBar();
|
||||
setupRecyclerView();
|
||||
}
|
||||
|
||||
@OnClick({R.id.action_shuffle})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.action_shuffle:
|
||||
MusicPlayerRemote.openAndShuffleQueue(songAdapter.getDataSet(), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpToolBar() {
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
appBarLayout.setBackgroundColor(primaryColor);
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
setSupportActionBar(toolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setTitle(genre.name);
|
||||
setTitle(R.string.app_name);
|
||||
|
||||
appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
|
||||
@Override
|
||||
public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) {
|
||||
int color;
|
||||
switch (state) {
|
||||
default:
|
||||
case COLLAPSED:
|
||||
case EXPANDED:
|
||||
case IDLE:
|
||||
color = ATHUtil.resolveColor(GenreDetailsActivity.this, android.R.attr.textColorPrimary);
|
||||
break;
|
||||
}
|
||||
toolbarLayout.setExpandedTitleColor(color);
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, color, GenreDetailsActivity.this);
|
||||
}
|
||||
});
|
||||
|
||||
TintHelper.setTintAuto(shuffleButton, ThemeStore.accentColor(this), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
presenter.subscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
presenter.unsubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View createContentView() {
|
||||
return wrapSlidingMusicPanel(R.layout.activity_playlist_detail);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_genre_detail, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
}
|
||||
return GenreMenuHelper.handleMenuClick(this, genre, item);
|
||||
}
|
||||
|
||||
private void setupRecyclerView() {
|
||||
ViewUtil.setUpFastScrollRecyclerViewColor(this,
|
||||
((FastScrollRecyclerView) recyclerView), ThemeStore.accentColor(this));
|
||||
songAdapter = new SongAdapter(this, new ArrayList<Song>(), R.layout.item_list, false, this);
|
||||
recyclerView.setItemAnimator(new DefaultItemAnimator());
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
recyclerView.setAdapter(songAdapter);
|
||||
|
||||
songAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
super.onChanged();
|
||||
checkIsEmpty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Song> songs) {
|
||||
songAdapter.swapDataSet(songs);
|
||||
}
|
||||
|
||||
public void showHeartAnimation() {
|
||||
shuffleButton.clearAnimation();
|
||||
|
||||
shuffleButton.setScaleX(0.9f);
|
||||
shuffleButton.setScaleY(0.9f);
|
||||
shuffleButton.setVisibility(View.VISIBLE);
|
||||
shuffleButton.setPivotX(shuffleButton.getWidth() / 2);
|
||||
shuffleButton.setPivotY(shuffleButton.getHeight() / 2);
|
||||
|
||||
shuffleButton.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> shuffleButton.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MaterialCab openCab(final int menu, final MaterialCab.Callback callback) {
|
||||
if (cab != null && cab.isActive()) cab.finish();
|
||||
cab = new MaterialCab(this, R.id.cab_stub)
|
||||
.setMenu(menu)
|
||||
.setCloseDrawableRes(R.drawable.ic_close_white_24dp)
|
||||
.setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(this)))
|
||||
.start(callback);
|
||||
return cab;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (cab != null && cab.isActive()) cab.finish();
|
||||
else {
|
||||
recyclerView.stopScroll();
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
super.onMediaStoreChanged();
|
||||
presenter.subscribe();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
import android.webkit.WebView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
|
||||
|
||||
public class LicenseActivity extends AbsBaseActivity {
|
||||
@BindView(R.id.license)
|
||||
WebView mLicense;
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar mToolbar;
|
||||
@BindView(R.id.appbar)
|
||||
AppBarLayout mAppbar;
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_license);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
mLicense.loadUrl("file:///android_asset/index.html");
|
||||
|
||||
mToolbar.setTitle(R.string.licenses);
|
||||
mToolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
mToolbar.setNavigationOnClickListener(view -> onBackPressed());
|
||||
mToolbar.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
mAppbar.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
setSupportActionBar(mToolbar);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.r0adkll.slidr.Slidr;
|
||||
import com.r0adkll.slidr.model.SlidrConfig;
|
||||
import com.r0adkll.slidr.model.SlidrPosition;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.lockscreen.LockScreenPlayerControlsFragment;
|
||||
|
||||
public class LockScreenActivity extends AbsMusicServiceActivity {
|
||||
private LockScreenPlayerControlsFragment mFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
|
||||
| WindowManager.LayoutParams.FLAG_FULLSCREEN
|
||||
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
|
||||
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
|
||||
|
||||
setDrawUnderStatusbar(true);
|
||||
setContentView(R.layout.activity_lock_screen_old_style);
|
||||
|
||||
hideStatusBar();
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
SlidrConfig config = new SlidrConfig.Builder()
|
||||
.position(SlidrPosition.BOTTOM)
|
||||
.build();
|
||||
|
||||
Slidr.attach(this, config);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
mFragment = (LockScreenPlayerControlsFragment) getSupportFragmentManager().findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
findViewById(R.id.slide).setTranslationY(100f);
|
||||
findViewById(R.id.slide).setAlpha(0f);
|
||||
ViewCompat.animate(findViewById(R.id.slide))
|
||||
.translationY(0f)
|
||||
.alpha(1f)
|
||||
.setDuration(1500)
|
||||
.start();
|
||||
|
||||
findViewById(R.id.root_layout).setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSongs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
updateSongs();
|
||||
}
|
||||
|
||||
private void updateSongs() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
SongGlideRequest.Builder.from(Glide.with(this), song)
|
||||
.checkIgnoreMediaStore(this)
|
||||
.generatePalette(this)
|
||||
.build().into(new RetroMusicColoredTarget(findViewById(R.id.image)) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
mFragment.setDark(color);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,392 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.model.lyrics.Lyrics;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
|
||||
import code.name.monkey.retromusic.ui.activities.tageditor.WriteTagsAsyncTask;
|
||||
import code.name.monkey.retromusic.util.LyricUtil;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import code.name.monkey.retromusic.views.LyricView;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
||||
public class LyricsActivity extends AbsMusicServiceActivity implements MusicProgressViewUpdateHelper.Callback {
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView songTitle;
|
||||
@BindView(R.id.text)
|
||||
TextView songText;
|
||||
@BindView(R.id.lyrics)
|
||||
LyricView lyricView;
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.offline_lyrics)
|
||||
TextView offlineLyrics;
|
||||
@BindView(R.id.actions)
|
||||
RadioGroup actionsLayout;
|
||||
@BindView(R.id.gradient_background)
|
||||
View background;
|
||||
|
||||
private MusicProgressViewUpdateHelper updateHelper;
|
||||
private AsyncTask updateLyricsAsyncTask;
|
||||
private CompositeDisposable disposable;
|
||||
private Song song;
|
||||
private Lyrics lyrics;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_lyrics);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
updateHelper = new MusicProgressViewUpdateHelper(this, 500, 1000);
|
||||
|
||||
setupToolbar();
|
||||
setupLyricsView();
|
||||
setupWakelock();
|
||||
|
||||
actionsLayout.setOnCheckedChangeListener((group, checkedId) -> selectLyricsTye(checkedId));
|
||||
}
|
||||
|
||||
private void selectLyricsTye(int group) {
|
||||
|
||||
RadioButton radioButton = actionsLayout.findViewById(group);
|
||||
radioButton.setBackgroundTintList(ColorStateList.valueOf(ThemeStore.accentColor(this)));
|
||||
radioButton.setTextColor(ThemeStore.textColorPrimary(this));
|
||||
|
||||
offlineLyrics.setVisibility(View.GONE);
|
||||
lyricView.setVisibility(View.GONE);
|
||||
switch (group) {
|
||||
case R.id.synced_lyrics:
|
||||
loadLRCLyrics();
|
||||
lyricView.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
default:
|
||||
case R.id.normal_lyrics:
|
||||
loadSongLyrics();
|
||||
offlineLyrics.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void loadLRCLyrics() {
|
||||
if (LyricUtil.isLrcFileExist(song.title, song.artistName)) {
|
||||
showLyricsLocal(LyricUtil.getLocalLyricFile(song.title, song.artistName));
|
||||
}
|
||||
}
|
||||
|
||||
private void setupWakelock() {
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
}
|
||||
|
||||
private void setupLyricsView() {
|
||||
disposable = new CompositeDisposable();
|
||||
//lyricView.setLineSpace(15.0f);
|
||||
//lyricView.setTextSize(17.0f);
|
||||
//lyricView.setPlayable(true);
|
||||
//lyricView.setTranslationY(DensityUtil.getScreenWidth(this) + DensityUtil.dip2px(this, 120));
|
||||
lyricView.setOnPlayerClickListener((progress, content) -> MusicPlayerRemote.seekTo((int) progress));
|
||||
|
||||
//lyricView.setHighLightTextColor(ThemeStore.accentColor(this));
|
||||
lyricView.setDefaultColor(ContextCompat.getColor(this, R.color.md_grey_400));
|
||||
//lyricView.setTouchable(false);
|
||||
lyricView.setHintColor(Color.WHITE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void setupToolbar() {
|
||||
toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
toolbar.setTitle("");
|
||||
toolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
loadLrcFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
updateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
updateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
loadLrcFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
disposable.clear();
|
||||
lyricView.setOnPlayerClickListener(null);
|
||||
|
||||
if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask.isCancelled()) {
|
||||
updateLyricsAsyncTask.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
lyricView.setCurrentTimeMillis(progress);
|
||||
}
|
||||
|
||||
private void loadLrcFile() {
|
||||
song = MusicPlayerRemote.getCurrentSong();
|
||||
songTitle.setText(song.title);
|
||||
songText.setText(song.artistName);
|
||||
SongGlideRequest.Builder.from(Glide.with(this), song)
|
||||
.checkIgnoreMediaStore(this)
|
||||
.generatePalette(this)
|
||||
.build()
|
||||
.into(new RetroMusicColoredTarget(findViewById(R.id.image)) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
if (PreferenceUtil.getInstance(LyricsActivity.this).getAdaptiveColor()) {
|
||||
background.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
});
|
||||
selectLyricsTye(actionsLayout.getCheckedRadioButtonId());
|
||||
}
|
||||
|
||||
private void showLyricsLocal(File file) {
|
||||
if (file == null) {
|
||||
lyricView.reset();
|
||||
lyricView.setVisibility(View.GONE);
|
||||
} else {
|
||||
lyricView.setVisibility(View.VISIBLE);
|
||||
lyricView.setLyricFile(file, "UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick({R.id.edit_lyrics})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.edit_lyrics:
|
||||
switch (actionsLayout.getCheckedRadioButtonId()) {
|
||||
case R.id.synced_lyrics:
|
||||
showSyncedLyrics();
|
||||
break;
|
||||
case R.id.normal_lyrics:
|
||||
showLyricsSaveDialog();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private void loadSongLyrics() {
|
||||
if (updateLyricsAsyncTask != null) updateLyricsAsyncTask.cancel(false);
|
||||
final Song song = MusicPlayerRemote.getCurrentSong();
|
||||
updateLyricsAsyncTask = new AsyncTask<Void, Void, Lyrics>() {
|
||||
@Override
|
||||
protected Lyrics doInBackground(Void... params) {
|
||||
String data = MusicUtil.getLyrics(song);
|
||||
if (TextUtils.isEmpty(data)) {
|
||||
return null;
|
||||
}
|
||||
return Lyrics.parse(song, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
lyrics = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Lyrics l) {
|
||||
lyrics = l;
|
||||
offlineLyrics.setVisibility(View.VISIBLE);
|
||||
if (l == null) {
|
||||
offlineLyrics.setText(R.string.no_lyrics_found);
|
||||
return;
|
||||
}
|
||||
offlineLyrics.setText(l.data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(Lyrics s) {
|
||||
onPostExecute(null);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private void showSyncedLyrics() {
|
||||
String content = "";
|
||||
try {
|
||||
content = LyricUtil.getStringFromFile(song.title, song.artistName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
new MaterialDialog.Builder(this)
|
||||
.title("Add lyrics")
|
||||
.neutralText("Search")
|
||||
.content("Add time frame lyrics")
|
||||
.negativeText("Delete")
|
||||
.onNegative((dialog, which) -> {
|
||||
LyricUtil.deleteLrcFile(song.title, song.artistName);
|
||||
loadLrcFile();
|
||||
})
|
||||
.onNeutral((dialog, which) -> RetroUtil.openUrl(LyricsActivity.this, getGoogleSearchLrcUrl()))
|
||||
.inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE)
|
||||
.input("Paste lyrics here", content, (dialog, input) -> {
|
||||
LyricUtil.writeLrcToLoc(song.title, song.artistName, input.toString());
|
||||
loadLrcFile();
|
||||
}).show();
|
||||
}
|
||||
|
||||
private String getGoogleSearchLrcUrl() {
|
||||
String baseUrl = "http://www.google.com/search?";
|
||||
String query = song.title + "+" + song.artistName;
|
||||
query = "q=" + query.replace(" ", "+") + " .lrc";
|
||||
baseUrl += query;
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
private void showLyricsSaveDialog() {
|
||||
String content = "";
|
||||
if (lyrics == null) {
|
||||
content = "";
|
||||
} else {
|
||||
content = lyrics.data;
|
||||
}
|
||||
new MaterialDialog.Builder(this)
|
||||
.title("Add lyrics")
|
||||
.neutralText("Search")
|
||||
.onNeutral(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
||||
RetroUtil.openUrl(LyricsActivity.this, getGoogleSearchUrl(song.title, song.artistName));
|
||||
}
|
||||
})
|
||||
.inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE)
|
||||
.input("Paste lyrics here", content, (dialog, input) -> {
|
||||
Map<FieldKey, String> fieldKeyValueMap = new EnumMap<>(FieldKey.class);
|
||||
fieldKeyValueMap.put(FieldKey.LYRICS, input.toString());
|
||||
|
||||
new WriteTagsAsyncTask(LyricsActivity.this)
|
||||
.execute(new WriteTagsAsyncTask.LoadingInfo(getSongPaths(song), fieldKeyValueMap, null));
|
||||
loadLrcFile();
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
private ArrayList<String> getSongPaths(Song song) {
|
||||
ArrayList<String> paths = new ArrayList<>(1);
|
||||
paths.add(song.data);
|
||||
return paths;
|
||||
}
|
||||
|
||||
private String getGoogleSearchUrl(String title, String text) {
|
||||
String baseUrl = "http://www.google.com/search?";
|
||||
String query = title + "+" + text;
|
||||
query = "q=" + query.replace(" ", "+") + " lyrics";
|
||||
baseUrl += query;
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
/*
|
||||
private void loadLyricsWIki(String title, String artist) {
|
||||
offlineLyrics.setVisibility(View.GONE);
|
||||
if (lyricsWikiTask != null) {
|
||||
lyricsWikiTask.cancel(false);
|
||||
}
|
||||
lyricsWikiTask = new ParseLyrics(new ParseLyrics.LyricsCallback() {
|
||||
@Override
|
||||
public void onShowLyrics(String lyrics) {
|
||||
offlineLyrics.setVisibility(View.VISIBLE);
|
||||
offlineLyrics.setText(lyrics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError() {
|
||||
loadSongLyrics();
|
||||
}
|
||||
}).execute(title, artist);
|
||||
}
|
||||
|
||||
private void callAgain(final String title, final String artist) {
|
||||
disposable.clear();
|
||||
disposable.add(loadLyrics.downloadLrcFile(title, artist, MusicPlayerRemote.getSongDurationMillis())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.doOnSubscribe(disposable -> {
|
||||
refresh.startAnimation(rotateAnimation);
|
||||
})
|
||||
.subscribe(this::showLyricsLocal, throwable -> {
|
||||
refresh.clearAnimation();
|
||||
showLyricsLocal(null);
|
||||
//loadLyricsWIki(songTitle, artist);
|
||||
toggleSyncLyrics(View.GONE);
|
||||
}, () -> {
|
||||
refresh.clearAnimation();
|
||||
Toast.makeText(this, "Lyrics downloaded", Toast.LENGTH_SHORT).show();
|
||||
}));
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,336 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.BottomNavigationView;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.SearchQueryHelper;
|
||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
|
||||
import code.name.monkey.retromusic.loaders.AlbumLoader;
|
||||
import code.name.monkey.retromusic.loaders.ArtistLoader;
|
||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.mainactivity.LibraryFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.mainactivity.home.HomeFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
||||
public class MainActivity extends AbsSlidingMusicPanelActivity implements
|
||||
SharedPreferences.OnSharedPreferenceChangeListener,
|
||||
BottomNavigationView.OnNavigationItemSelectedListener {
|
||||
|
||||
public static final int APP_INTRO_REQUEST = 2323;
|
||||
private static final String TAG = "MainActivity";
|
||||
private static final int APP_USER_INFO_REQUEST = 9003;
|
||||
private static final int REQUEST_CODE_THEME = 9002;
|
||||
|
||||
@Nullable
|
||||
MainActivityFragmentCallbacks currentFragment;
|
||||
|
||||
@BindView(R.id.parent_container)
|
||||
FrameLayout drawerLayout;
|
||||
|
||||
private boolean blockRequestPermissions;
|
||||
private CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (action != null && action.equals(Intent.ACTION_SCREEN_OFF)) {
|
||||
if (PreferenceUtil.getInstance(context).getLockScreen() && MusicPlayerRemote.isPlaying()) {
|
||||
Intent activity = new Intent(context, LockScreenActivity.class);
|
||||
activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
activity.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||
ActivityCompat.startActivity(context, activity, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
protected View createContentView() {
|
||||
@SuppressLint("InflateParams")
|
||||
View contentView = getLayoutInflater().inflate(R.layout.activity_main_drawer_layout, null);
|
||||
ViewGroup drawerContent = contentView.findViewById(R.id.drawer_content_container);
|
||||
drawerContent.addView(wrapSlidingMusicPanel(R.layout.activity_main_content));
|
||||
return contentView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setDrawUnderStatusbar(true);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setBottomBarVisibility(View.VISIBLE);
|
||||
|
||||
drawerLayout.setOnApplyWindowInsetsListener((view, windowInsets) ->
|
||||
windowInsets.replaceSystemWindowInsets(0, 0, 0, 0));
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
setCurrentFragment(PreferenceUtil.getInstance(this).getLastPage());
|
||||
} else {
|
||||
restoreCurrentFragment();
|
||||
}
|
||||
/*if (!RetroApplication.isProVersion() &&
|
||||
!PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getBoolean("shown", false)) {
|
||||
showPromotionalOffer();
|
||||
}*/
|
||||
getBottomNavigationView().setOnNavigationItemSelectedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
IntentFilter screenOnOff = new IntentFilter();
|
||||
screenOnOff.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
registerReceiver(broadcastReceiver, screenOnOff);
|
||||
|
||||
PreferenceUtil.getInstance(this).registerOnSharedPreferenceChangedListener(this);
|
||||
|
||||
if (getIntent().hasExtra("expand")) {
|
||||
if (getIntent().getBooleanExtra("expand", false)) {
|
||||
expandPanel();
|
||||
getIntent().putExtra("expand", false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
disposable.clear();
|
||||
if (broadcastReceiver == null) {
|
||||
return;
|
||||
}
|
||||
unregisterReceiver(broadcastReceiver);
|
||||
PreferenceUtil.getInstance(this).unregisterOnSharedPreferenceChangedListener(this);
|
||||
}
|
||||
|
||||
public void setCurrentFragment(@Nullable Fragment fragment, boolean isStackAdd) {
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
fragmentTransaction.replace(R.id.fragment_container, fragment, TAG);
|
||||
if (isStackAdd) {
|
||||
fragmentTransaction.addToBackStack(TAG);
|
||||
}
|
||||
fragmentTransaction.commit();
|
||||
currentFragment = (MainActivityFragmentCallbacks) fragment;
|
||||
}
|
||||
|
||||
private void restoreCurrentFragment() {
|
||||
currentFragment = (MainActivityFragmentCallbacks) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.fragment_container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||
PreferenceUtil.getInstance(this).setLastPage(item.getItemId());
|
||||
disposable.add(Observable.just(item.getItemId())
|
||||
.throttleFirst(3, TimeUnit.SECONDS)
|
||||
.subscribe(this::setCurrentFragment));
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setCurrentFragment(int menuItem) {
|
||||
switch (menuItem) {
|
||||
case R.id.action_song:
|
||||
case R.id.action_album:
|
||||
case R.id.action_artist:
|
||||
case R.id.action_playlist:
|
||||
setCurrentFragment(LibraryFragment.newInstance(menuItem), false);
|
||||
break;
|
||||
default:
|
||||
case R.id.action_home:
|
||||
setCurrentFragment(HomeFragment.newInstance(), false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePlaybackIntent(@Nullable Intent intent) {
|
||||
if (intent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Uri uri = intent.getData();
|
||||
String mimeType = intent.getType();
|
||||
boolean handled = false;
|
||||
|
||||
if (intent.getAction() != null && intent.getAction()
|
||||
.equals(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH)) {
|
||||
final ArrayList<Song> songs = SearchQueryHelper.getSongs(this, intent.getExtras());
|
||||
|
||||
if (MusicPlayerRemote.getShuffleMode() == MusicService.SHUFFLE_MODE_SHUFFLE) {
|
||||
MusicPlayerRemote.openAndShuffleQueue(songs, true);
|
||||
} else {
|
||||
MusicPlayerRemote.openQueue(songs, 0, true);
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
|
||||
if (uri != null && uri.toString().length() > 0) {
|
||||
MusicPlayerRemote.playFromUri(uri);
|
||||
handled = true;
|
||||
} else if (MediaStore.Audio.Playlists.CONTENT_TYPE.equals(mimeType)) {
|
||||
final int id = (int) parseIdFromIntent(intent, "playlistId", "playlist");
|
||||
if (id >= 0) {
|
||||
int position = intent.getIntExtra("position", 0);
|
||||
ArrayList<Song> songs = new ArrayList<>(
|
||||
PlaylistSongsLoader.getPlaylistSongList(this, id).blockingFirst());
|
||||
MusicPlayerRemote.openQueue(songs, position, true);
|
||||
handled = true;
|
||||
}
|
||||
} else if (MediaStore.Audio.Albums.CONTENT_TYPE.equals(mimeType)) {
|
||||
final int id = (int) parseIdFromIntent(intent, "albumId", "album");
|
||||
if (id >= 0) {
|
||||
int position = intent.getIntExtra("position", 0);
|
||||
MusicPlayerRemote
|
||||
.openQueue(AlbumLoader.getAlbum(this, id).blockingFirst().songs, position, true);
|
||||
handled = true;
|
||||
}
|
||||
} else if (MediaStore.Audio.Artists.CONTENT_TYPE.equals(mimeType)) {
|
||||
final int id = (int) parseIdFromIntent(intent, "artistId", "artist");
|
||||
if (id >= 0) {
|
||||
int position = intent.getIntExtra("position", 0);
|
||||
MusicPlayerRemote.openQueue(ArtistLoader.getArtist(this, id).blockingFirst().getSongs(), position, true);
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
if (handled) {
|
||||
setIntent(new Intent());
|
||||
}
|
||||
}
|
||||
|
||||
private long parseIdFromIntent(@NonNull Intent intent, String longKey, String stringKey) {
|
||||
long id = intent.getLongExtra(longKey, -1);
|
||||
if (id < 0) {
|
||||
String idString = intent.getStringExtra(stringKey);
|
||||
if (idString != null) {
|
||||
try {
|
||||
id = Long.parseLong(idString);
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case APP_INTRO_REQUEST:
|
||||
blockRequestPermissions = false;
|
||||
if (!hasPermissions()) {
|
||||
requestPermissions();
|
||||
}
|
||||
|
||||
break;
|
||||
case REQUEST_CODE_THEME:
|
||||
case APP_USER_INFO_REQUEST:
|
||||
postRecreate();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleBackPress() {
|
||||
return super.handleBackPress() || (currentFragment != null &&
|
||||
currentFragment.handleBackPress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
handlePlaybackIntent(getIntent());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void requestPermissions() {
|
||||
if (!blockRequestPermissions) {
|
||||
super.requestPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (key.equalsIgnoreCase(PreferenceUtil.GENERAL_THEME) ||
|
||||
key.equalsIgnoreCase(PreferenceUtil.ADAPTIVE_COLOR_APP) ||
|
||||
key.equalsIgnoreCase(PreferenceUtil.DOMINANT_COLOR) ||
|
||||
key.equalsIgnoreCase(PreferenceUtil.USER_NAME) ||
|
||||
key.equalsIgnoreCase(PreferenceUtil.TOGGLE_FULL_SCREEN) ||
|
||||
key.equalsIgnoreCase(PreferenceUtil.TOGGLE_VOLUME) ||
|
||||
key.equalsIgnoreCase(PreferenceUtil.TOGGLE_TAB_TITLES) ||
|
||||
key.equalsIgnoreCase(PreferenceUtil.ROUND_CORNERS) ||
|
||||
key.equals(PreferenceUtil.CAROUSEL_EFFECT) ||
|
||||
key.equals(PreferenceUtil.NOW_PLAYING_SCREEN_ID) ||
|
||||
key.equals(PreferenceUtil.TOGGLE_GENRE) ||
|
||||
key.equals(PreferenceUtil.BANNER_IMAGE_PATH) ||
|
||||
key.equals(PreferenceUtil.PROFILE_IMAGE_PATH) ||
|
||||
key.equals(PreferenceUtil.CIRCULAR_ALBUM_ART) ||
|
||||
key.equals(PreferenceUtil.KEEP_SCREEN_ON) ||
|
||||
key.equals(PreferenceUtil.TOGGLE_SEPARATE_LINE)) {
|
||||
postRecreate();
|
||||
}
|
||||
}
|
||||
|
||||
private void showPromotionalOffer() {
|
||||
new MaterialDialog.Builder(this)
|
||||
.positiveText("Buy")
|
||||
.onPositive((dialog, which) ->
|
||||
startActivity(new Intent(MainActivity.this, ProVersionActivity.class)))
|
||||
.negativeText(android.R.string.cancel)
|
||||
.customView(R.layout.dialog_promotional_offer, false)
|
||||
.dismissListener(dialog -> {
|
||||
PreferenceManager.getDefaultSharedPreferences(MainActivity.this)
|
||||
.edit()
|
||||
.putBoolean("shown", true)
|
||||
.apply();
|
||||
})
|
||||
.show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.widget.TextView;
|
||||
import butterknife.BindDrawable;
|
||||
import butterknife.BindString;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.PlayingQueueFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
|
||||
|
||||
public class PlayingQueueActivity extends AbsMusicServiceActivity {
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar mToolbar;
|
||||
@BindDrawable(R.drawable.ic_close_white_24dp)
|
||||
Drawable mClose;
|
||||
@BindView(R.id.player_queue_sub_header)
|
||||
TextView mPlayerQueueSubHeader;
|
||||
@BindString(R.string.queue)
|
||||
String queue;
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout mAppBarLayout;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_playing_queue);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
setupToolbar();
|
||||
if (savedInstanceState == null) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.fragment_container, new PlayingQueueFragment())
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
protected String getUpNextAndQueueTime() {
|
||||
return getResources().getString(R.string.up_next) + " • " + MusicUtil
|
||||
.getReadableDurationString(
|
||||
MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.getPosition()));
|
||||
}
|
||||
|
||||
private void setupToolbar() {
|
||||
mPlayerQueueSubHeader.setText(getUpNextAndQueueTime());
|
||||
mPlayerQueueSubHeader.setTextColor(ThemeStore.accentColor(this));
|
||||
mAppBarLayout.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
mToolbar.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
mToolbar.setNavigationIcon(mClose);
|
||||
setSupportActionBar(mToolbar);
|
||||
setTitle(queue);
|
||||
mToolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,353 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.CollapsingToolbarLayout;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.materialcab.MaterialCab;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.loaders.PlaylistLoader;
|
||||
import code.name.monkey.retromusic.misc.AppBarStateChangeListener;
|
||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist;
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.PlaylistSong;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.contract.PlaylistSongsContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsPresenter;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.OrderablePlaylistSongAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.PlaylistSongAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.SongAdapter;
|
||||
import code.name.monkey.retromusic.util.PlaylistsUtil;
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
||||
public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity implements CabHolder,
|
||||
PlaylistSongsContract.PlaylistSongsView {
|
||||
|
||||
@NonNull
|
||||
public static String EXTRA_PLAYLIST = "extra_playlist";
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@BindView(android.R.id.empty)
|
||||
TextView empty;
|
||||
|
||||
@BindView(R.id.action_shuffle)
|
||||
FloatingActionButton shuffleButton;
|
||||
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appBarLayout;
|
||||
|
||||
@BindView(R.id.collapsing_toolbar)
|
||||
CollapsingToolbarLayout toolbarLayout;
|
||||
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
private Playlist playlist;
|
||||
private MaterialCab cab;
|
||||
private SongAdapter adapter;
|
||||
private RecyclerView.Adapter wrappedAdapter;
|
||||
private RecyclerViewDragDropManager recyclerViewDragDropManager;
|
||||
private PlaylistSongsPresenter songsPresenter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setDrawUnderStatusbar(true);
|
||||
super.onCreate(savedInstanceState);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
RetroUtil.statusBarHeight(statusBar);
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
setBottomBarVisibility(View.GONE);
|
||||
|
||||
playlist = getIntent().getExtras().getParcelable(EXTRA_PLAYLIST);
|
||||
|
||||
if (playlist != null) {
|
||||
songsPresenter = new PlaylistSongsPresenter(this, playlist);
|
||||
}
|
||||
|
||||
setUpToolBar();
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
public void showHeartAnimation() {
|
||||
shuffleButton.clearAnimation();
|
||||
|
||||
shuffleButton.setScaleX(0.9f);
|
||||
shuffleButton.setScaleY(0.9f);
|
||||
shuffleButton.setVisibility(View.VISIBLE);
|
||||
shuffleButton.setPivotX(shuffleButton.getWidth() / 2);
|
||||
shuffleButton.setPivotY(shuffleButton.getHeight() / 2);
|
||||
|
||||
shuffleButton.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> shuffleButton.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected View createContentView() {
|
||||
return wrapSlidingMusicPanel(R.layout.activity_playlist_detail);
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
ViewUtil.setUpFastScrollRecyclerViewColor(this, ((FastScrollRecyclerView) recyclerView),
|
||||
ThemeStore.accentColor(this));
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
if (playlist instanceof AbsCustomPlaylist) {
|
||||
adapter = new PlaylistSongAdapter(this, new ArrayList<Song>(), R.layout.item_list, false,
|
||||
this);
|
||||
recyclerView.setAdapter(adapter);
|
||||
} else {
|
||||
recyclerViewDragDropManager = new RecyclerViewDragDropManager();
|
||||
final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
|
||||
adapter = new OrderablePlaylistSongAdapter(this, new ArrayList<PlaylistSong>(),
|
||||
R.layout.item_list, false, this, (fromPosition, toPosition) -> {
|
||||
if (PlaylistsUtil
|
||||
.moveItem(PlaylistDetailActivity.this, playlist.id, fromPosition, toPosition)) {
|
||||
Song song = adapter.getDataSet().remove(fromPosition);
|
||||
adapter.getDataSet().add(toPosition, song);
|
||||
adapter.notifyItemMoved(fromPosition, toPosition);
|
||||
}
|
||||
});
|
||||
wrappedAdapter = recyclerViewDragDropManager.createWrappedAdapter(adapter);
|
||||
|
||||
recyclerView.setAdapter(wrappedAdapter);
|
||||
recyclerView.setItemAnimator(animator);
|
||||
|
||||
recyclerViewDragDropManager.attachRecyclerView(recyclerView);
|
||||
}
|
||||
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
super.onChanged();
|
||||
checkIsEmpty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
songsPresenter.subscribe();
|
||||
}
|
||||
|
||||
private void setUpToolBar() {
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
appBarLayout.setBackgroundColor(primaryColor);
|
||||
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
|
||||
setSupportActionBar(toolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setTitle(playlist.name);
|
||||
|
||||
appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
|
||||
@Override
|
||||
public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) {
|
||||
int color;
|
||||
switch (state) {
|
||||
default:
|
||||
case COLLAPSED:
|
||||
case EXPANDED:
|
||||
case IDLE:
|
||||
color = ThemeStore.textColorPrimary(PlaylistDetailActivity.this);
|
||||
break;
|
||||
}
|
||||
toolbarLayout.setExpandedTitleColor(color);
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, color, PlaylistDetailActivity.this);
|
||||
}
|
||||
});
|
||||
TintHelper.setTintAuto(shuffleButton, ThemeStore.accentColor(this), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(
|
||||
playlist instanceof AbsCustomPlaylist ? R.menu.menu_smart_playlist_detail
|
||||
: R.menu.menu_playlist_detail, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return PlaylistMenuHelper.handleMenuClick(this, playlist, item);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MaterialCab openCab(final int menu, final MaterialCab.Callback callback) {
|
||||
if (cab != null && cab.isActive()) {
|
||||
cab.finish();
|
||||
}
|
||||
cab = new MaterialCab(this, R.id.cab_stub)
|
||||
.setMenu(menu)
|
||||
.setCloseDrawableRes(R.drawable.ic_close_white_24dp)
|
||||
.setBackgroundColor(
|
||||
RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(this)))
|
||||
.start(callback);
|
||||
return cab;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (cab != null && cab.isActive()) {
|
||||
cab.finish();
|
||||
} else {
|
||||
recyclerView.stopScroll();
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
super.onMediaStoreChanged();
|
||||
|
||||
if (!(playlist instanceof AbsCustomPlaylist)) {
|
||||
// Playlist deleted
|
||||
if (!PlaylistsUtil.doesPlaylistExist(this, playlist.id)) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Playlist renamed
|
||||
final String playlistName = PlaylistsUtil.getNameForPlaylist(this, playlist.id);
|
||||
if (!playlistName.equals(playlist.name)) {
|
||||
playlist = PlaylistLoader.getPlaylist(this, playlist.id).blockingFirst();
|
||||
setToolbarTitle(playlist.name);
|
||||
}
|
||||
}
|
||||
songsPresenter.subscribe();
|
||||
}
|
||||
|
||||
private void setToolbarTitle(String title) {
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setTitle(title);
|
||||
}
|
||||
|
||||
private void checkIsEmpty() {
|
||||
empty.setVisibility(
|
||||
adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (recyclerViewDragDropManager != null) {
|
||||
recyclerViewDragDropManager.cancelDrag();
|
||||
}
|
||||
super.onPause();
|
||||
songsPresenter.unsubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (recyclerViewDragDropManager != null) {
|
||||
recyclerViewDragDropManager.release();
|
||||
recyclerViewDragDropManager = null;
|
||||
}
|
||||
|
||||
if (recyclerView != null) {
|
||||
recyclerView.setItemAnimator(null);
|
||||
recyclerView.setAdapter(null);
|
||||
recyclerView = null;
|
||||
}
|
||||
|
||||
if (wrappedAdapter != null) {
|
||||
WrapperAdapterUtils.releaseAll(wrappedAdapter);
|
||||
wrappedAdapter = null;
|
||||
}
|
||||
adapter = null;
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
songsPresenter.subscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
empty.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Song> songs) {
|
||||
adapter.swapDataSet(songs);
|
||||
}
|
||||
|
||||
@OnClick(R.id.action_shuffle)
|
||||
public void onViewClicked() {
|
||||
showHeartAnimation();
|
||||
if (adapter.getDataSet().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
MusicPlayerRemote.openAndShuffleQueue(adapter.getDataSet(), true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.anjlab.android.iab.v3.BillingProcessor;
|
||||
import com.anjlab.android.iab.v3.TransactionDetails;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.BuildConfig;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.RetroApplication;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class ProVersionActivity extends AbsBaseActivity implements
|
||||
BillingProcessor.IBillingHandler {
|
||||
|
||||
private static final String TAG = "ProVersionActivity";
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.restore_button)
|
||||
View restoreButton;
|
||||
@BindView(R.id.purchase_button)
|
||||
View purchaseButton;
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appBar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
private BillingProcessor billingProcessor;
|
||||
private AsyncTask restorePurchaseAsyncTask;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_pro_version);
|
||||
setDrawUnderStatusbar(true);
|
||||
ButterKnife.bind(this);
|
||||
RetroUtil.statusBarHeight(statusBar);
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
appBar.setBackgroundColor(primaryColor);
|
||||
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
toolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
setSupportActionBar(toolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setTitle("RetroMusic Pro");
|
||||
|
||||
restoreButton.setEnabled(false);
|
||||
purchaseButton.setEnabled(false);
|
||||
|
||||
billingProcessor = new BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSE_KEY, this);
|
||||
|
||||
}
|
||||
|
||||
private void restorePurchase() {
|
||||
if (restorePurchaseAsyncTask != null) {
|
||||
restorePurchaseAsyncTask.cancel(false);
|
||||
}
|
||||
restorePurchaseAsyncTask = new RestorePurchaseAsyncTask(this).execute();
|
||||
}
|
||||
|
||||
@OnClick({R.id.restore_button, R.id.purchase_button})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.restore_button:
|
||||
if (restorePurchaseAsyncTask == null
|
||||
|| restorePurchaseAsyncTask.getStatus() != AsyncTask.Status.RUNNING) {
|
||||
restorePurchase();
|
||||
}
|
||||
break;
|
||||
case R.id.purchase_button:
|
||||
billingProcessor.purchase(ProVersionActivity.this, RetroApplication.PRO_VERSION_PRODUCT_ID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProductPurchased(@NonNull String productId, @Nullable TransactionDetails details) {
|
||||
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show();
|
||||
setResult(RESULT_OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPurchaseHistoryRestored() {
|
||||
if (RetroApplication.isProVersion()) {
|
||||
Toast.makeText(this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
setResult(RESULT_OK);
|
||||
} else {
|
||||
Toast.makeText(this, R.string.no_purchase_found, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBillingError(int errorCode, @Nullable Throwable error) {
|
||||
Log.e(TAG, "Billing error: code = " + errorCode, error);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBillingInitialized() {
|
||||
restoreButton.setEnabled(true);
|
||||
purchaseButton.setEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (billingProcessor != null) {
|
||||
billingProcessor.release();
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private static class RestorePurchaseAsyncTask extends AsyncTask<Void, Void, Boolean> {
|
||||
|
||||
private final WeakReference<ProVersionActivity> buyActivityWeakReference;
|
||||
|
||||
RestorePurchaseAsyncTask(ProVersionActivity purchaseActivity) {
|
||||
this.buyActivityWeakReference = new WeakReference<>(purchaseActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
ProVersionActivity purchaseActivity = buyActivityWeakReference.get();
|
||||
if (purchaseActivity != null) {
|
||||
Toast.makeText(purchaseActivity, R.string.restoring_purchase, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
cancel(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
ProVersionActivity purchaseActivity = buyActivityWeakReference.get();
|
||||
if (purchaseActivity != null) {
|
||||
return purchaseActivity.billingProcessor.loadOwnedPurchasesFromGoogle();
|
||||
}
|
||||
cancel(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean b) {
|
||||
super.onPostExecute(b);
|
||||
ProVersionActivity purchaseActivity = buyActivityWeakReference.get();
|
||||
if (purchaseActivity == null || b == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (b) {
|
||||
purchaseActivity.onPurchaseHistoryRestored();
|
||||
} else {
|
||||
Toast.makeText(purchaseActivity, R.string.could_not_restore_purchase, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,267 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.app.SearchManager;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.speech.RecognizerIntent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.CoordinatorLayout;
|
||||
import android.support.transition.TransitionManager;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.SearchView.OnQueryTextListener;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.BufferType;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.mvp.contract.SearchContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.SearchPresenter;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
|
||||
import code.name.monkey.retromusic.ui.adapter.SearchAdapter;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
||||
public class SearchActivity extends AbsMusicServiceActivity implements OnQueryTextListener,
|
||||
SearchContract.SearchView, TextWatcher {
|
||||
|
||||
public static final String TAG = SearchActivity.class.getSimpleName();
|
||||
public static final String QUERY = "query";
|
||||
private static final int REQ_CODE_SPEECH_INPUT = 9002;
|
||||
@BindView(R.id.voice_search)
|
||||
View micIcon;
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(android.R.id.empty)
|
||||
TextView empty;
|
||||
@BindView(R.id.search_view)
|
||||
EditText searchView;
|
||||
@BindView(R.id.root)
|
||||
CoordinatorLayout container;
|
||||
@BindView(R.id.appbar)
|
||||
AppBarLayout appbar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
private SearchPresenter searchPresenter;
|
||||
private SearchAdapter adapter;
|
||||
private String query;
|
||||
|
||||
private boolean isMicSearch = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setDrawUnderStatusbar(true);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_search);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
ViewUtil.setStatusBarHeight(this, statusBar);
|
||||
|
||||
searchPresenter = new SearchPresenter(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
setupRecyclerview();
|
||||
setUpToolBar();
|
||||
setupSearchView();
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
query = savedInstanceState.getString(QUERY);
|
||||
searchPresenter.search(query);
|
||||
}
|
||||
|
||||
if (getIntent().getBooleanExtra("mic_search", false)) {
|
||||
startMicSearch();
|
||||
isMicSearch = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupRecyclerview() {
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
adapter = new SearchAdapter(this, Collections.emptyList());
|
||||
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
super.onChanged();
|
||||
empty.setVisibility(adapter.getItemCount() < 1 ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private void setupSearchView() {
|
||||
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
|
||||
if (searchManager != null) {
|
||||
searchView.addTextChangedListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
//Log.i(TAG, "onResume: " + query);
|
||||
searchPresenter.subscribe();
|
||||
searchPresenter.search(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
searchPresenter.unsubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(QUERY, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
searchPresenter.search(savedInstanceState.getString(QUERY, ""));
|
||||
}
|
||||
|
||||
private void setUpToolBar() {
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
appbar.setBackgroundColor(primaryColor);
|
||||
setSupportActionBar(toolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void search(@NonNull String query) {
|
||||
this.query = query.trim();
|
||||
TransitionManager.beginDelayedTransition(toolbar);
|
||||
micIcon.setVisibility(query.length() > 0 ? View.GONE : View.VISIBLE);
|
||||
searchPresenter.search(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
super.onMediaStoreChanged();
|
||||
searchPresenter.search(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
hideSoftKeyboard();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
search(newText);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void hideSoftKeyboard() {
|
||||
RetroUtil.hideSoftKeyboard(SearchActivity.this);
|
||||
if (searchView != null) {
|
||||
searchView.clearFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
adapter.swapDataSet(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Object> list) {
|
||||
adapter.swapDataSet(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case REQ_CODE_SPEECH_INPUT: {
|
||||
if (resultCode == RESULT_OK && null != data) {
|
||||
|
||||
ArrayList<String> result = data
|
||||
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
|
||||
query = result.get(0);
|
||||
searchView.setText(query, BufferType.EDITABLE);
|
||||
searchPresenter.search(query);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.voice_search)
|
||||
void searchImageView() {
|
||||
startMicSearch();
|
||||
}
|
||||
|
||||
private void startMicSearch() {
|
||||
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
|
||||
intent
|
||||
.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
|
||||
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
|
||||
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt));
|
||||
try {
|
||||
startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(this, getString(R.string.speech_not_supported), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence newText, int start, int before, int count) {
|
||||
search(newText.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.transition.TransitionManager;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.afollestad.materialdialogs.color.ColorChooserDialog;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.settings.MainSettingsFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
public class SettingsActivity extends AbsBaseActivity implements ColorChooserDialog.ColorCallback {
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appBarLayout;
|
||||
@BindView(R.id.detail_content_frame)
|
||||
@Nullable
|
||||
FrameLayout detailsFrame;
|
||||
|
||||
private FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
|
||||
@Override
|
||||
public void onColorSelection(@NonNull ColorChooserDialog dialog, @ColorInt int selectedColor) {
|
||||
switch (dialog.getTitle()) {
|
||||
case R.string.primary_color:
|
||||
int theme = ColorUtil.isColorLight(selectedColor) ?
|
||||
PreferenceUtil.getThemeResFromPrefValue("light") :
|
||||
PreferenceUtil.getThemeResFromPrefValue("dark");
|
||||
|
||||
ThemeStore.editTheme(this).activityTheme(theme).primaryColor(selectedColor).commit();
|
||||
break;
|
||||
case R.string.accent_color:
|
||||
ThemeStore.editTheme(this).accentColor(selectedColor).commit();
|
||||
break;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
new DynamicShortcutManager(this).updateDynamicShortcuts();
|
||||
}
|
||||
recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChooserDismissed(@NonNull ColorChooserDialog dialog) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
setContentView(R.layout.activity_settings);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
setupToolbar();
|
||||
|
||||
if (bundle == null) {
|
||||
fragmentManager.beginTransaction().replace(R.id.content_frame, new MainSettingsFragment()).commit();
|
||||
} else {
|
||||
restoreFragment();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupToolbar() {
|
||||
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
toolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
setTitle(R.string.action_settings);
|
||||
setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
private void restoreFragment() {
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
if (fragmentManager.getBackStackEntryCount() > 0) {
|
||||
appBarLayout.setExpanded(false, true);
|
||||
} else {
|
||||
appBarLayout.setExpanded(true, true);
|
||||
}
|
||||
setupToolbar();
|
||||
}
|
||||
|
||||
public void setupFragment(Fragment fragment) {
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.animator.slide_up, 0, 0, R.animator.slide_down);
|
||||
|
||||
if (detailsFrame == null) {
|
||||
fragmentTransaction.replace(R.id.content_frame, fragment, fragment.getTag());
|
||||
fragmentTransaction.addToBackStack(null);
|
||||
fragmentTransaction.commit();
|
||||
} else {
|
||||
fragmentTransaction.replace(R.id.detail_content_frame, fragment, fragment.getTag());
|
||||
fragmentTransaction.commit();
|
||||
}
|
||||
|
||||
fragmentManager.addOnBackStackChangedListener(() -> {
|
||||
if (fragmentManager.getBackStackEntryCount() > 0) {
|
||||
appBarLayout.setExpanded(false, true);
|
||||
} else {
|
||||
appBarLayout.setExpanded(true, true);
|
||||
}
|
||||
setupToolbar();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (fragmentManager.getBackStackEntryCount() == 0) {
|
||||
super.onBackPressed();
|
||||
} else {
|
||||
fragmentManager.popBackStack();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public void addAppbarLayoutElevation(float v) {
|
||||
TransitionManager.beginDelayedTransition(appBarLayout);
|
||||
appBarLayout.setElevation(v);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,318 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Paint;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.internal.MDTintHelper;
|
||||
import com.anjlab.android.iab.v3.BillingProcessor;
|
||||
import com.anjlab.android.iab.v3.SkuDetails;
|
||||
import com.anjlab.android.iab.v3.TransactionDetails;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.retromusic.BuildConfig;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import code.name.monkey.retromusic.views.IconImageView;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.PAYPAL_ME_URL;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class SupportDevelopmentActivity extends AbsBaseActivity implements BillingProcessor.IBillingHandler {
|
||||
public static final String TAG = SupportDevelopmentActivity.class.getSimpleName();
|
||||
private static final int DONATION_PRODUCT_IDS = R.array.donation_ids;
|
||||
@BindView(R.id.progress)
|
||||
ProgressBar mProgressBar;
|
||||
@BindView(R.id.progress_container)
|
||||
View mProgressContainer;
|
||||
@BindView(R.id.list)
|
||||
RecyclerView mListView;
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar mToolbar;
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout mAppBarLayout;
|
||||
@BindView(R.id.root)
|
||||
ViewGroup mViewGroup;
|
||||
private BillingProcessor mBillingProcessor;
|
||||
private AsyncTask skuDetailsLoadAsyncTask;
|
||||
|
||||
private static List<SkuDetails> getDetails() {
|
||||
List<SkuDetails> skuDetails = new ArrayList<>();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
jsonObject.put("songTitle", "Coffee");
|
||||
jsonObject.put("price", "$100");
|
||||
jsonObject.put("description", "" + i);
|
||||
skuDetails.add(new SkuDetails(jsonObject));
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return skuDetails;
|
||||
}
|
||||
|
||||
private void donate(int i) {
|
||||
final String[] ids = getResources().getStringArray(DONATION_PRODUCT_IDS);
|
||||
mBillingProcessor.purchase(this, ids[i]);
|
||||
}
|
||||
|
||||
@OnClick(R.id.donate)
|
||||
void donate() {
|
||||
RetroUtil.openUrl(this, PAYPAL_ME_URL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_donation);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
int primaryColor = ThemeStore.primaryColor(this);
|
||||
mAppBarLayout.setBackgroundColor(primaryColor);
|
||||
mToolbar.setBackgroundColor(primaryColor);
|
||||
setSupportActionBar(mToolbar);
|
||||
//noinspection ConstantConditions
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
mToolbar.setNavigationOnClickListener(view -> onBackPressed());
|
||||
|
||||
mBillingProcessor
|
||||
= new BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSE_KEY, this);
|
||||
MDTintHelper.setTint(mProgressBar, ThemeStore.accentColor(this));
|
||||
|
||||
((TextView) findViewById(R.id.donation)).setTextColor(ThemeStore.accentColor(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBillingInitialized() {
|
||||
loadSkuDetails();
|
||||
}
|
||||
|
||||
private void loadSkuDetails() {
|
||||
if (skuDetailsLoadAsyncTask != null) {
|
||||
skuDetailsLoadAsyncTask.cancel(false);
|
||||
}
|
||||
skuDetailsLoadAsyncTask = new SkuDetailsLoadAsyncTask(this).execute();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProductPurchased(@NonNull String productId, TransactionDetails details) {
|
||||
//loadSkuDetails();
|
||||
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBillingError(int errorCode, Throwable error) {
|
||||
Log.e(TAG, "Billing error: code = " + errorCode, error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPurchaseHistoryRestored() {
|
||||
//loadSkuDetails();
|
||||
Toast.makeText(this, R.string.restored_previous_purchases, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (!mBillingProcessor.handleActivityResult(requestCode, resultCode, data)) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (mBillingProcessor != null) {
|
||||
mBillingProcessor.release();
|
||||
}
|
||||
if (skuDetailsLoadAsyncTask != null) {
|
||||
skuDetailsLoadAsyncTask.cancel(true);
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private static class SkuDetailsLoadAsyncTask extends AsyncTask<Void, Void, List<SkuDetails>> {
|
||||
private final WeakReference<SupportDevelopmentActivity> donationDialogWeakReference;
|
||||
|
||||
public SkuDetailsLoadAsyncTask(SupportDevelopmentActivity donationsDialog) {
|
||||
this.donationDialogWeakReference = new WeakReference<>(donationsDialog);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
SupportDevelopmentActivity dialog = donationDialogWeakReference.get();
|
||||
if (dialog == null) return;
|
||||
|
||||
dialog.mProgressContainer.setVisibility(View.VISIBLE);
|
||||
dialog.mListView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<SkuDetails> doInBackground(Void... params) {
|
||||
SupportDevelopmentActivity dialog = donationDialogWeakReference.get();
|
||||
if (dialog != null) {
|
||||
final String[] ids = dialog.getResources().getStringArray(DONATION_PRODUCT_IDS);
|
||||
return dialog.mBillingProcessor.getPurchaseListingDetails(new ArrayList<>(Arrays.asList(ids)));
|
||||
}
|
||||
cancel(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<SkuDetails> skuDetails) {
|
||||
super.onPostExecute(skuDetails);
|
||||
SupportDevelopmentActivity dialog = donationDialogWeakReference.get();
|
||||
if (dialog == null) return;
|
||||
|
||||
if (skuDetails == null || skuDetails.isEmpty()) {
|
||||
//Toast.makeText(dialog, "Error loading items", Toast.LENGTH_SHORT).show();
|
||||
//dialog.finish();
|
||||
dialog.mProgressContainer.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
//noinspection ConstantConditions
|
||||
dialog.mProgressContainer.setVisibility(View.GONE);
|
||||
dialog.mListView.setItemAnimator(new DefaultItemAnimator());
|
||||
dialog.mListView.setLayoutManager(new GridLayoutManager(dialog, 2));
|
||||
dialog.mListView.setAdapter(new SkuDetailsAdapter(dialog, skuDetails));
|
||||
dialog.mListView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static class SkuDetailsAdapter extends RecyclerView.Adapter<SkuDetailsAdapter.ViewHolder> {
|
||||
@LayoutRes
|
||||
private static int LAYOUT_RES_ID = R.layout.item_donation_option;
|
||||
|
||||
SupportDevelopmentActivity donationsDialog;
|
||||
List<SkuDetails> skuDetailsList = new ArrayList<>();
|
||||
|
||||
public SkuDetailsAdapter(@NonNull SupportDevelopmentActivity donationsDialog, @NonNull List<SkuDetails> objects) {
|
||||
this.donationsDialog = donationsDialog;
|
||||
skuDetailsList = objects;
|
||||
}
|
||||
|
||||
private static void strikeThrough(TextView textView, boolean strikeThrough) {
|
||||
textView.setPaintFlags(strikeThrough ? textView.getPaintFlags() |
|
||||
Paint.STRIKE_THRU_TEXT_FLAG : textView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
|
||||
}
|
||||
|
||||
private int getIcon(int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
return R.drawable.ic_cookie_white_24dp;
|
||||
case 1:
|
||||
return R.drawable.ic_take_away_white_24dp;
|
||||
case 2:
|
||||
return R.drawable.ic_take_away_coffe_white_24dp;
|
||||
case 3:
|
||||
return R.drawable.ic_beer_white_24dp;
|
||||
case 4:
|
||||
return R.drawable.ic_fast_food_meal_white_24dp;
|
||||
case 5:
|
||||
return R.drawable.ic_popcorn_white_24dp;
|
||||
case 6:
|
||||
return R.drawable.ic_card_giftcard_white_24dp;
|
||||
default:
|
||||
return R.drawable.ic_card_giftcard_white_24dp;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
|
||||
return new ViewHolder(LayoutInflater.from(donationsDialog)
|
||||
.inflate(LAYOUT_RES_ID, viewGroup, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder viewHolder, int i) {
|
||||
SkuDetails skuDetails = skuDetailsList.get(i);
|
||||
if (skuDetails != null) {
|
||||
viewHolder.title.setText(skuDetails.title.replace("(Retro Music Player)", "").trim());
|
||||
viewHolder.text.setText(skuDetails.description);
|
||||
viewHolder.text.setVisibility(View.GONE);
|
||||
viewHolder.price.setText(skuDetails.priceText);
|
||||
viewHolder.image.setImageResource(getIcon(i));
|
||||
|
||||
final boolean purchased = donationsDialog.mBillingProcessor.isPurchased(skuDetails.productId);
|
||||
int titleTextColor = purchased ? ATHUtil.resolveColor(donationsDialog, android.R.attr.textColorHint) : ThemeStore.textColorPrimary(donationsDialog);
|
||||
int contentTextColor = purchased ? titleTextColor : ThemeStore.textColorSecondary(donationsDialog);
|
||||
|
||||
//noinspection ResourceAsColor
|
||||
viewHolder.title.setTextColor(titleTextColor);
|
||||
viewHolder.text.setTextColor(contentTextColor);
|
||||
viewHolder.price.setTextColor(titleTextColor);
|
||||
|
||||
strikeThrough(viewHolder.title, purchased);
|
||||
strikeThrough(viewHolder.text, purchased);
|
||||
strikeThrough(viewHolder.price, purchased);
|
||||
|
||||
viewHolder.itemView.setOnTouchListener((v, event) -> purchased);
|
||||
viewHolder.itemView.setOnClickListener(v -> donationsDialog.donate(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return skuDetailsList.size();
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.price)
|
||||
TextView price;
|
||||
@BindView(R.id.image)
|
||||
IconImageView image;
|
||||
|
||||
public ViewHolder(View view) {
|
||||
super(view);
|
||||
ButterKnife.bind(this, view);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package code.name.monkey.retromusic.ui.activities;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.intro.NameFragment;
|
||||
|
||||
public class UserInfoActivity extends AbsBaseActivity {
|
||||
private static final String TAG = "UserInfoActivity";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setDrawUnderStatusbar(true);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_user_info);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
setTaskDescriptionColorAuto();
|
||||
setLightNavigationBar(true);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.fragment_container, new NameFragment(), TAG)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
package code.name.monkey.retromusic.ui.activities.base;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;
|
||||
|
||||
|
||||
public abstract class AbsBaseActivity extends AbsThemeActivity {
|
||||
public static final int PERMISSION_REQUEST = 100;
|
||||
private boolean hadPermissions;
|
||||
private String[] permissions;
|
||||
private String permissionDeniedMessage;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
|
||||
permissions = getPermissionsToRequest();
|
||||
hadPermissions = hasPermissions();
|
||||
|
||||
setPermissionDeniedMessage(null);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
if (!hasPermissions()) {
|
||||
requestPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
final boolean hasPermissions = hasPermissions();
|
||||
if (hasPermissions != hadPermissions) {
|
||||
hadPermissions = hasPermissions;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
onHasPermissionsChanged(hasPermissions);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void onHasPermissionsChanged(boolean hasPermissions) {
|
||||
// implemented by sub classes
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
|
||||
if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && event.getAction() == KeyEvent.ACTION_UP) {
|
||||
showOverflowMenu();
|
||||
return true;
|
||||
}
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
protected void showOverflowMenu() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context newBase) {
|
||||
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String[] getPermissionsToRequest() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected View getSnackBarContainer() {
|
||||
return getWindow().getDecorView();
|
||||
}
|
||||
|
||||
private String getPermissionDeniedMessage() {
|
||||
return permissionDeniedMessage == null ? getString(R.string.permissions_denied) : permissionDeniedMessage;
|
||||
}
|
||||
|
||||
protected void setPermissionDeniedMessage(String message) {
|
||||
permissionDeniedMessage = message;
|
||||
}
|
||||
|
||||
protected void requestPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && permissions != null) {
|
||||
requestPermissions(permissions, PERMISSION_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean hasPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && permissions != null) {
|
||||
for (String permission : permissions) {
|
||||
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == PERMISSION_REQUEST) {
|
||||
for (int grantResult : grantResults) {
|
||||
if (grantResult != PackageManager.PERMISSION_GRANTED) {
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(AbsBaseActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
||||
//User has deny from permission dialog
|
||||
Snackbar.make(getSnackBarContainer(), getPermissionDeniedMessage(),
|
||||
Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction(R.string.action_grant, view -> requestPermissions())
|
||||
.setActionTextColor(ThemeStore.accentColor(this))
|
||||
.show();
|
||||
} else {
|
||||
// User has deny permission and checked never show permission dialog so you can redirect to Application settings page
|
||||
Snackbar.make(getSnackBarContainer(), getPermissionDeniedMessage(),
|
||||
Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction(R.string.action_settings, view -> {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
Uri uri = Uri.fromParts("package", AbsBaseActivity.this.getPackageName(), null);
|
||||
intent.setData(uri);
|
||||
startActivity(intent);
|
||||
})
|
||||
.setActionTextColor(ThemeStore.accentColor(this))
|
||||
.show();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
hadPermissions = true;
|
||||
onHasPermissionsChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
package code.name.monkey.retromusic.ui.activities.base;
|
||||
|
||||
import android.Manifest;
|
||||
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.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.MEDIA_STORE_CHANGED;
|
||||
import static code.name.monkey.retromusic.Constants.META_CHANGED;
|
||||
import static code.name.monkey.retromusic.Constants.PLAY_STATE_CHANGED;
|
||||
import static code.name.monkey.retromusic.Constants.QUEUE_CHANGED;
|
||||
import static code.name.monkey.retromusic.Constants.REPEAT_MODE_CHANGED;
|
||||
import static code.name.monkey.retromusic.Constants.SHUFFLE_MODE_CHANGED;
|
||||
|
||||
|
||||
public abstract class AbsMusicServiceActivity extends AbsBaseActivity implements MusicServiceEventListener {
|
||||
public static final String TAG = AbsMusicServiceActivity.class.getSimpleName();
|
||||
|
||||
private final ArrayList<MusicServiceEventListener> mMusicServiceEventListeners = new ArrayList<>();
|
||||
|
||||
private MusicPlayerRemote.ServiceToken serviceToken;
|
||||
private MusicStateReceiver musicStateReceiver;
|
||||
private boolean receiverRegistered;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
serviceToken = MusicPlayerRemote.bindToService(this, new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
AbsMusicServiceActivity.this.onServiceConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
AbsMusicServiceActivity.this.onServiceDisconnected();
|
||||
}
|
||||
});
|
||||
|
||||
setPermissionDeniedMessage(getString(R.string.permission_external_storage_denied));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
MusicPlayerRemote.unbindFromService(serviceToken);
|
||||
if (receiverRegistered) {
|
||||
unregisterReceiver(musicStateReceiver);
|
||||
receiverRegistered = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void addMusicServiceEventListener(final MusicServiceEventListener listener) {
|
||||
if (listener != null) {
|
||||
mMusicServiceEventListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeMusicServiceEventListener(final MusicServiceEventListener listener) {
|
||||
if (listener != null) {
|
||||
mMusicServiceEventListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
if (!receiverRegistered) {
|
||||
musicStateReceiver = new MusicStateReceiver(this);
|
||||
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(PLAY_STATE_CHANGED);
|
||||
filter.addAction(SHUFFLE_MODE_CHANGED);
|
||||
filter.addAction(REPEAT_MODE_CHANGED);
|
||||
filter.addAction(META_CHANGED);
|
||||
filter.addAction(QUEUE_CHANGED);
|
||||
filter.addAction(MEDIA_STORE_CHANGED);
|
||||
|
||||
registerReceiver(musicStateReceiver, filter);
|
||||
|
||||
receiverRegistered = true;
|
||||
}
|
||||
|
||||
for (MusicServiceEventListener listener : mMusicServiceEventListeners) {
|
||||
if (listener != null) {
|
||||
listener.onServiceConnected();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected() {
|
||||
if (receiverRegistered) {
|
||||
unregisterReceiver(musicStateReceiver);
|
||||
receiverRegistered = false;
|
||||
}
|
||||
|
||||
for (MusicServiceEventListener listener : mMusicServiceEventListeners) {
|
||||
if (listener != null) {
|
||||
listener.onServiceDisconnected();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
for (MusicServiceEventListener listener : mMusicServiceEventListeners) {
|
||||
if (listener != null) {
|
||||
listener.onPlayingMetaChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
for (MusicServiceEventListener listener : mMusicServiceEventListeners) {
|
||||
if (listener != null) {
|
||||
listener.onQueueChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
for (MusicServiceEventListener listener : mMusicServiceEventListeners) {
|
||||
if (listener != null) {
|
||||
listener.onPlayStateChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
for (MusicServiceEventListener listener : mMusicServiceEventListeners) {
|
||||
if (listener != null) {
|
||||
listener.onMediaStoreChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
for (MusicServiceEventListener listener : mMusicServiceEventListeners) {
|
||||
if (listener != null) {
|
||||
listener.onRepeatModeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
for (MusicServiceEventListener listener : mMusicServiceEventListeners) {
|
||||
if (listener != null) {
|
||||
listener.onShuffleModeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHasPermissionsChanged(boolean hasPermissions) {
|
||||
super.onHasPermissionsChanged(hasPermissions);
|
||||
Intent intent = new Intent(MEDIA_STORE_CHANGED);
|
||||
intent.putExtra("from_permissions_changed", true); // just in case we need to know this at some point
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected String[] getPermissionsToRequest() {
|
||||
return new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
|
||||
}
|
||||
|
||||
private static final class MusicStateReceiver extends BroadcastReceiver {
|
||||
|
||||
private final WeakReference<AbsMusicServiceActivity> reference;
|
||||
|
||||
public MusicStateReceiver(final AbsMusicServiceActivity activity) {
|
||||
reference = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, @NonNull final Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
AbsMusicServiceActivity activity = reference.get();
|
||||
if (activity != null && action != null) {
|
||||
switch (action) {
|
||||
case META_CHANGED:
|
||||
activity.onPlayingMetaChanged();
|
||||
break;
|
||||
case QUEUE_CHANGED:
|
||||
activity.onQueueChanged();
|
||||
break;
|
||||
case PLAY_STATE_CHANGED:
|
||||
activity.onPlayStateChanged();
|
||||
break;
|
||||
case REPEAT_MODE_CHANGED:
|
||||
activity.onRepeatModeChanged();
|
||||
break;
|
||||
case SHUFFLE_MODE_CHANGED:
|
||||
activity.onShuffleModeChanged();
|
||||
break;
|
||||
case MEDIA_STORE_CHANGED:
|
||||
activity.onMediaStoreChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,434 @@
|
|||
package code.name.monkey.retromusic.ui.activities.base;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.FloatRange;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelState;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.ui.fragments.MiniPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.NowPlayingScreen;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.adaptive.AdaptiveFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.blur.BlurPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.card.CardFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.cardblur.CardBlurFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.color.ColorFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.flat.FlatPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.full.FullPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.hmm.HmmPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.material.MaterialFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.plain.PlainPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.simple.SimplePlayerFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
import code.name.monkey.retromusic.views.BottomNavigationViewEx;
|
||||
|
||||
public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivity implements
|
||||
SlidingUpPanelLayout.PanelSlideListener,
|
||||
PlayerFragment.Callbacks {
|
||||
|
||||
public static final String TAG = AbsSlidingMusicPanelActivity.class.getSimpleName();
|
||||
|
||||
@BindView(R.id.bottom_navigation)
|
||||
BottomNavigationViewEx bottomNavigationView;
|
||||
@BindView(R.id.sliding_layout)
|
||||
SlidingUpPanelLayout slidingUpPanelLayout;
|
||||
|
||||
private int navigationbarColor;
|
||||
private int taskColor;
|
||||
private boolean lightStatusBar;
|
||||
private boolean lightNavigationBar;
|
||||
private NowPlayingScreen currentNowPlayingScreen;
|
||||
private AbsPlayerFragment playerFragment;
|
||||
private MiniPlayerFragment miniPlayerFragment;
|
||||
private ValueAnimator navigationBarColorAnimator;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(createContentView());
|
||||
ButterKnife.bind(this);
|
||||
choosFragmentForTheme();
|
||||
//noinspection ConstantConditions
|
||||
miniPlayerFragment.getView().setOnClickListener(v -> expandPanel());
|
||||
slidingUpPanelLayout.getViewTreeObserver()
|
||||
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
slidingUpPanelLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
|
||||
if (getPanelState() == PanelState.EXPANDED) {
|
||||
onPanelSlide(slidingUpPanelLayout, 1);
|
||||
onPanelExpanded(slidingUpPanelLayout);
|
||||
} else if (getPanelState() == PanelState.COLLAPSED) {
|
||||
onPanelCollapsed(slidingUpPanelLayout);
|
||||
} else {
|
||||
playerFragment.onHide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setupBottomView();
|
||||
slidingUpPanelLayout.addPanelSlideListener(this);
|
||||
|
||||
}
|
||||
|
||||
private void choosFragmentForTheme() {
|
||||
currentNowPlayingScreen = PreferenceUtil.getInstance(this).getNowPlayingScreen();
|
||||
|
||||
Fragment fragment; // must implement AbsPlayerFragment
|
||||
switch (currentNowPlayingScreen) {
|
||||
case MATERIAL:
|
||||
fragment = new MaterialFragment();
|
||||
break;
|
||||
case BLUR:
|
||||
fragment = new BlurPlayerFragment();
|
||||
break;
|
||||
case FLAT:
|
||||
fragment = new FlatPlayerFragment();
|
||||
break;
|
||||
case PLAIN:
|
||||
fragment = new PlainPlayerFragment();
|
||||
break;
|
||||
case FULL:
|
||||
fragment = new FullPlayerFragment();
|
||||
break;
|
||||
case COLOR:
|
||||
fragment = new ColorFragment();
|
||||
break;
|
||||
case CARD:
|
||||
fragment = new CardFragment();
|
||||
break;
|
||||
case SIMPLE:
|
||||
fragment = new SimplePlayerFragment();
|
||||
break;
|
||||
case TINY:
|
||||
fragment = new HmmPlayerFragment();
|
||||
break;
|
||||
case BLUR_CARD:
|
||||
fragment = new CardBlurFragment();
|
||||
break;
|
||||
case ADAPTIVE:
|
||||
fragment = new AdaptiveFragment();
|
||||
break;
|
||||
|
||||
case NORMAL:
|
||||
default:
|
||||
fragment = new PlayerFragment();
|
||||
break;
|
||||
}
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.player_fragment_container, fragment)
|
||||
.commit();
|
||||
getSupportFragmentManager().executePendingTransactions();
|
||||
|
||||
playerFragment = (AbsPlayerFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.player_fragment_container);
|
||||
miniPlayerFragment = (MiniPlayerFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.mini_player_fragment);
|
||||
}
|
||||
|
||||
private void setupBottomView() {
|
||||
bottomNavigationView.setSelectedItemId(PreferenceUtil.getInstance(this).getLastPage());
|
||||
bottomNavigationView.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
bottomNavigationView.enableAnimation(false);
|
||||
bottomNavigationView.enableItemShiftingMode(false);
|
||||
bottomNavigationView.enableShiftingMode(false);
|
||||
bottomNavigationView.setTextSize(10f);
|
||||
bottomNavigationView.setTextVisibility(PreferenceUtil.getInstance(this).tabTitles());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (currentNowPlayingScreen != PreferenceUtil.getInstance(this).getNowPlayingScreen()) {
|
||||
postRecreate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (navigationBarColorAnimator != null) {
|
||||
navigationBarColorAnimator.cancel(); // just in case
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected abstract View createContentView();
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
if (!MusicPlayerRemote.getPlayingQueue().isEmpty()) {
|
||||
slidingUpPanelLayout.getViewTreeObserver()
|
||||
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
slidingUpPanelLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
hideBottomBar(false);
|
||||
}
|
||||
});
|
||||
}// don't call hideBottomBar(true) here as it causes a bug with the SlidingUpPanelLayout
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
super.onQueueChanged();
|
||||
hideBottomBar(MusicPlayerRemote.getPlayingQueue().isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelSlide(View panel, @FloatRange(from = 0, to = 1) float slideOffset) {
|
||||
bottomNavigationView.setTranslationY(slideOffset * 400);
|
||||
setMiniPlayerAlphaProgress(slideOffset);
|
||||
//findViewById(R.id.player_fragment_container).setAlpha(slideOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelStateChanged(View panel, PanelState previousState, PanelState newState) {
|
||||
switch (newState) {
|
||||
case COLLAPSED:
|
||||
onPanelCollapsed(panel);
|
||||
break;
|
||||
case EXPANDED:
|
||||
onPanelExpanded(panel);
|
||||
break;
|
||||
case ANCHORED:
|
||||
collapsePanel(); // this fixes a bug where the panel would get stuck for some reason
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void onPanelCollapsed(View panel) {
|
||||
// restore values
|
||||
super.setLightStatusbar(lightStatusBar);
|
||||
super.setTaskDescriptionColor(taskColor);
|
||||
super.setNavigationbarColor(navigationbarColor);
|
||||
super.setLightNavigationBar(lightNavigationBar);
|
||||
|
||||
playerFragment.setMenuVisibility(false);
|
||||
playerFragment.setUserVisibleHint(false);
|
||||
playerFragment.onHide();
|
||||
}
|
||||
|
||||
public void onPanelExpanded(View panel) {
|
||||
// setting fragments values
|
||||
int playerFragmentColor = playerFragment.getPaletteColor();
|
||||
super.setTaskDescriptionColor(playerFragmentColor);
|
||||
|
||||
if (currentNowPlayingScreen == NowPlayingScreen.COLOR) {
|
||||
super.setNavigationbarColor(playerFragmentColor);
|
||||
} else {
|
||||
super.setNavigationbarColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
setLightStatusBar();
|
||||
|
||||
playerFragment.setMenuVisibility(true);
|
||||
playerFragment.setUserVisibleHint(true);
|
||||
playerFragment.onShow();
|
||||
}
|
||||
|
||||
private void setLightStatusBar() {
|
||||
super.setLightStatusbar(!PreferenceUtil.getInstance(this).getAdaptiveColor() &&
|
||||
ColorUtil.isColorLight(ThemeStore.primaryColor(this)) && (
|
||||
currentNowPlayingScreen == NowPlayingScreen.FLAT
|
||||
|| currentNowPlayingScreen == NowPlayingScreen.PLAIN
|
||||
|| currentNowPlayingScreen == NowPlayingScreen.SIMPLE
|
||||
|| currentNowPlayingScreen == NowPlayingScreen.NORMAL
|
||||
|| currentNowPlayingScreen == NowPlayingScreen.ADAPTIVE)
|
||||
|| currentNowPlayingScreen == NowPlayingScreen.TINY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLightStatusbar(boolean enabled) {
|
||||
lightStatusBar = enabled;
|
||||
if (getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
super.setLightStatusbar(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLightNavigationBar(boolean enabled) {
|
||||
lightNavigationBar = enabled;
|
||||
/*if (getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
super.setLightNavigationBar(enabled);
|
||||
}*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTaskDescriptionColor(@ColorInt int color) {
|
||||
taskColor = color;
|
||||
if (getPanelState() == null || getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
super.setTaskDescriptionColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNavigationbarColor(int color) {
|
||||
navigationbarColor = color;
|
||||
if (getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
if (navigationBarColorAnimator != null) {
|
||||
navigationBarColorAnimator.cancel();
|
||||
}
|
||||
super.setNavigationbarColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPaletteColorChanged() {
|
||||
int playerFragmentColor = playerFragment.getPaletteColor();
|
||||
|
||||
if (getPanelState() == PanelState.EXPANDED) {
|
||||
super.setTaskDescriptionColor(playerFragmentColor);
|
||||
if (currentNowPlayingScreen == NowPlayingScreen.COLOR) {
|
||||
super.setNavigationbarColor(playerFragmentColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setMiniPlayerAlphaProgress(@FloatRange(from = 0, to = 1) float progress) {
|
||||
if (miniPlayerFragment == null) {
|
||||
return;
|
||||
}
|
||||
float alpha = 1 - progress;
|
||||
miniPlayerFragment.getView().setAlpha(alpha);
|
||||
// necessary to make the views below clickable
|
||||
miniPlayerFragment.getView().setVisibility(alpha == 0 ? View.GONE : View.VISIBLE);
|
||||
|
||||
}
|
||||
|
||||
public void hideBottomBar(final boolean hide) {
|
||||
|
||||
int heightOfBar =
|
||||
getResources().getDimensionPixelSize(R.dimen.mini_player_height);
|
||||
int heightOfBarWithTabs =
|
||||
getResources().getDimensionPixelSize(R.dimen.mini_player_height_expanded);
|
||||
|
||||
if (hide) {
|
||||
slidingUpPanelLayout.setPanelHeight(0);
|
||||
collapsePanel();
|
||||
} else {
|
||||
if (!MusicPlayerRemote.getPlayingQueue().isEmpty()) {
|
||||
slidingUpPanelLayout.setPanelHeight(bottomNavigationView.getVisibility() == View.VISIBLE ?
|
||||
heightOfBarWithTabs : heightOfBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setBottomBarVisibility(int gone) {
|
||||
if (bottomNavigationView != null) {
|
||||
//TransitionManager.beginDelayedTransition(bottomNavigationView);
|
||||
bottomNavigationView.setVisibility(gone);
|
||||
hideBottomBar(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected View wrapSlidingMusicPanel(@LayoutRes int resId) {
|
||||
@SuppressLint("InflateParams")
|
||||
View slidingMusicPanelLayout = getLayoutInflater()
|
||||
.inflate(R.layout.sliding_music_panel_layout, null);
|
||||
ViewGroup contentContainer = slidingMusicPanelLayout.findViewById(R.id.content_container);
|
||||
getLayoutInflater().inflate(resId, contentContainer);
|
||||
return slidingMusicPanelLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (!handleBackPress()) {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean handleBackPress() {
|
||||
if (slidingUpPanelLayout.getPanelHeight() != 0 && playerFragment.onBackPressed()) {
|
||||
return true;
|
||||
}
|
||||
if (getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {
|
||||
collapsePanel();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void animateNavigationBarColor(int color) {
|
||||
if (navigationBarColorAnimator != null) {
|
||||
navigationBarColorAnimator.cancel();
|
||||
}
|
||||
navigationBarColorAnimator = ValueAnimator.ofArgb(getWindow().getNavigationBarColor(), color)
|
||||
.setDuration(ViewUtil.RETRO_MUSIC_ANIM_TIME);
|
||||
navigationBarColorAnimator.setInterpolator(new PathInterpolator(0.4f, 0f, 1f, 1f));
|
||||
navigationBarColorAnimator.addUpdateListener(animation -> {
|
||||
int playerFragmentColorDark = ColorUtil.darkenColor((Integer) animation.getAnimatedValue());
|
||||
|
||||
bottomNavigationView.setBackgroundColor(playerFragmentColorDark);
|
||||
miniPlayerFragment.setColor(playerFragmentColorDark);
|
||||
AbsSlidingMusicPanelActivity.super.setNavigationbarColor(playerFragmentColorDark);
|
||||
|
||||
View view = getWindow().getDecorView().getRootView();
|
||||
view.setBackgroundColor(playerFragmentColorDark);
|
||||
|
||||
if (view.findViewById(R.id.toolbar) != null) {
|
||||
view.findViewById(R.id.toolbar).setBackgroundColor(playerFragmentColorDark);
|
||||
}
|
||||
if (view.findViewById(R.id.appbar) != null) {
|
||||
view.findViewById(R.id.appbar).setBackgroundColor(playerFragmentColorDark);
|
||||
}
|
||||
if (view.findViewById(R.id.status_bar) != null) {
|
||||
view.findViewById(R.id.status_bar)
|
||||
.setBackgroundColor(ColorUtil.darkenColor(playerFragmentColorDark));
|
||||
}
|
||||
});
|
||||
navigationBarColorAnimator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View getSnackBarContainer() {
|
||||
return findViewById(R.id.content_container);
|
||||
}
|
||||
|
||||
public SlidingUpPanelLayout getSlidingUpPanelLayout() {
|
||||
return slidingUpPanelLayout;
|
||||
}
|
||||
|
||||
public MiniPlayerFragment getMiniPlayerFragment() {
|
||||
return miniPlayerFragment;
|
||||
}
|
||||
|
||||
public AbsPlayerFragment getPlayerFragment() {
|
||||
return playerFragment;
|
||||
}
|
||||
|
||||
public BottomNavigationViewEx getBottomNavigationView() {
|
||||
return bottomNavigationView;
|
||||
}
|
||||
|
||||
public SlidingUpPanelLayout.PanelState getPanelState() {
|
||||
return slidingUpPanelLayout == null ? null : slidingUpPanelLayout.getPanelState();
|
||||
}
|
||||
|
||||
public void collapsePanel() {
|
||||
slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
|
||||
}
|
||||
|
||||
public void expandPanel() {
|
||||
slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
package code.name.monkey.retromusic.ui.activities.base;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import code.name.monkey.appthemehelper.ATH;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialDialogsUtil;
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
public abstract class AbsThemeActivity extends ATHToolbarActivity implements Runnable {
|
||||
|
||||
private Handler handler = new Handler();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setTheme(PreferenceUtil.getInstance(this).getGeneralTheme());
|
||||
hideStatusBar();
|
||||
super.onCreate(savedInstanceState);
|
||||
MaterialDialogsUtil.updateMaterialDialogsThemeSingleton(this);
|
||||
|
||||
changeBackgroundShape();
|
||||
setImmersiveFullscreen();
|
||||
registerSystemUiVisibility();
|
||||
toggleScreenOn();
|
||||
|
||||
}
|
||||
|
||||
private void toggleScreenOn() {
|
||||
if (PreferenceUtil.getInstance(this).isScreenOnEnabled()) {
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
} else {
|
||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (hasFocus) {
|
||||
hideStatusBar();
|
||||
handler.removeCallbacks(this);
|
||||
handler.postDelayed(this, 300);
|
||||
} else {
|
||||
handler.removeCallbacks(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void hideStatusBar() {
|
||||
hideStatusBar(PreferenceUtil.getInstance(this).getFullScreenMode());
|
||||
}
|
||||
|
||||
private void hideStatusBar(boolean fullscreen) {
|
||||
final View statusBar = getWindow().getDecorView().getRootView().findViewById(R.id.status_bar);
|
||||
if (statusBar != null) {
|
||||
statusBar.setVisibility(fullscreen ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void changeBackgroundShape() {
|
||||
if (PreferenceUtil.getInstance(this).isRoundCorners()) {
|
||||
getWindow().setBackgroundDrawableResource(R.drawable.round_window);
|
||||
} else {
|
||||
getWindow().setBackgroundDrawableResource(R.drawable.square_window);
|
||||
}
|
||||
View decor = getWindow().getDecorView();
|
||||
GradientDrawable gradientDrawable = (GradientDrawable) decor.getBackground();
|
||||
gradientDrawable.setColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
protected void setDrawUnderStatusbar(boolean drawUnderStatusbar) {
|
||||
if (VersionUtils.hasLollipop()) {
|
||||
RetroUtil.setAllowDrawUnderStatusBar(getWindow());
|
||||
} else if (VersionUtils.hasKitKat()) {
|
||||
RetroUtil.setStatusBarTranslucent(getWindow());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will set the color of the view with the id "status_bar" on KitKat and Lollipop. On
|
||||
* Lollipop if no such view is found it will set the statusbar color using the native method.
|
||||
*
|
||||
* @param color the new statusbar color (will be shifted down on Lollipop and above)
|
||||
*/
|
||||
public void setStatusbarColor(int color) {
|
||||
if (VersionUtils.hasKitKat()) {
|
||||
final View statusBar = getWindow().getDecorView().getRootView().findViewById(R.id.status_bar);
|
||||
if (statusBar != null) {
|
||||
if (VersionUtils.hasLollipop()) {
|
||||
statusBar.setBackgroundColor(ColorUtil.darkenColor(color));
|
||||
setLightStatusbarAuto(color);
|
||||
} else {
|
||||
statusBar.setBackgroundColor(color);
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= 21) {
|
||||
getWindow().setStatusBarColor(ColorUtil.darkenColor(color));
|
||||
setLightStatusbarAuto(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setStatusbarColorAuto() {
|
||||
// we don't want to use statusbar color because we are doing the color darkening on our own to support KitKat
|
||||
setStatusbarColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
public void setTaskDescriptionColor(@ColorInt int color) {
|
||||
ATH.setTaskDescriptionColor(this, color);
|
||||
}
|
||||
|
||||
public void setTaskDescriptionColorAuto() {
|
||||
setTaskDescriptionColor(ThemeStore.primaryColor(this));
|
||||
}
|
||||
|
||||
public void setNavigationbarColor(int color) {
|
||||
if (ThemeStore.coloredNavigationBar(this)) {
|
||||
ATH.setNavigationbarColor(this, color);
|
||||
} else {
|
||||
ATH.setNavigationbarColor(this, Color.BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
public void setNavigationbarColorAuto() {
|
||||
setNavigationbarColor(ThemeStore.navigationBarColor(this));
|
||||
}
|
||||
|
||||
public void setLightStatusbar(boolean enabled) {
|
||||
ATH.setLightStatusbar(this, enabled);
|
||||
}
|
||||
|
||||
public void setLightStatusbarAuto(int bgColor) {
|
||||
setLightStatusbar(ColorUtil.isColorLight(bgColor));
|
||||
}
|
||||
|
||||
public void setLightNavigationBar(boolean enabled) {
|
||||
if (!ATHUtil.isWindowBackgroundDark(this) && ThemeStore.coloredNavigationBar(this)) {
|
||||
ATH.setLightNavigationbar(this, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerSystemUiVisibility() {
|
||||
final View decorView = getWindow().getDecorView();
|
||||
decorView.setOnSystemUiVisibilityChangeListener(visibility -> {
|
||||
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
|
||||
setImmersiveFullscreen();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void unregisterSystemUiVisibility() {
|
||||
final View decorView = getWindow().getDecorView();
|
||||
decorView.setOnSystemUiVisibilityChangeListener(null);
|
||||
}
|
||||
|
||||
public void setImmersiveFullscreen() {
|
||||
int flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
if (PreferenceUtil.getInstance(this).getFullScreenMode()) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(flags);
|
||||
}
|
||||
}
|
||||
|
||||
public void exitFullscreen() {
|
||||
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setImmersiveFullscreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
handler.removeCallbacks(this);
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
unregisterSystemUiVisibility();
|
||||
exitFullscreen();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
|
||||
handler.removeCallbacks(this);
|
||||
handler.postDelayed(this, 500);
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,367 @@
|
|||
package code.name.monkey.retromusic.ui.activities.tageditor;
|
||||
|
||||
import android.app.SearchManager;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
|
||||
import org.jaudiotagger.audio.AudioFile;
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
import org.jaudiotagger.tag.images.Artwork;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
public abstract class AbsTagEditorActivity extends AbsBaseActivity {
|
||||
|
||||
public static final String EXTRA_ID = "extra_id";
|
||||
public static final String EXTRA_PALETTE = "extra_palette";
|
||||
private static final String TAG = AbsTagEditorActivity.class.getSimpleName();
|
||||
private static final int REQUEST_CODE_SELECT_IMAGE = 1000;
|
||||
@BindView(R.id.save_fab)
|
||||
FloatingActionButton save;
|
||||
@BindView(R.id.image)
|
||||
ImageView image;
|
||||
@BindView(R.id.image_container)
|
||||
FrameLayout imageContainer;
|
||||
CharSequence[] items;
|
||||
private int id;
|
||||
private int paletteColorPrimary;
|
||||
private boolean isInNoImageMode;
|
||||
private List<String> songPaths;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(getContentViewLayout());
|
||||
ButterKnife.bind(this);
|
||||
|
||||
getIntentExtras();
|
||||
|
||||
songPaths = getSongPaths();
|
||||
if (songPaths.isEmpty()) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
setUpViews();
|
||||
setTaskDescriptionColorAuto();
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
setUpScrollView();
|
||||
setUpFab();
|
||||
setUpImageView();
|
||||
}
|
||||
|
||||
private void setUpScrollView() {
|
||||
//observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
||||
}
|
||||
|
||||
private void setUpImageView() {
|
||||
loadCurrentImage();
|
||||
items = new CharSequence[]{
|
||||
getString(R.string.download_from_last_fm),
|
||||
getString(R.string.pick_from_local_storage),
|
||||
getString(R.string.web_search),
|
||||
getString(R.string.remove_cover)
|
||||
};
|
||||
image.setOnClickListener(v -> getShow());
|
||||
}
|
||||
|
||||
protected MaterialDialog getShow() {
|
||||
return new MaterialDialog.Builder(AbsTagEditorActivity.this)
|
||||
.title(R.string.update_image)
|
||||
.items(items)
|
||||
.itemsCallback((dialog, itemView, position, text) -> {
|
||||
switch (position) {
|
||||
case 0:
|
||||
getImageFromLastFM();
|
||||
break;
|
||||
case 1:
|
||||
startImagePicker();
|
||||
break;
|
||||
case 2:
|
||||
searchImageOnWeb();
|
||||
break;
|
||||
case 3:
|
||||
deleteImage();
|
||||
break;
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
private void startImagePicker() {
|
||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
intent.setType("image/*");
|
||||
startActivityForResult(
|
||||
Intent.createChooser(intent, getString(R.string.pick_from_local_storage)),
|
||||
REQUEST_CODE_SELECT_IMAGE);
|
||||
}
|
||||
|
||||
protected abstract void loadCurrentImage();
|
||||
|
||||
protected abstract void getImageFromLastFM();
|
||||
|
||||
protected abstract void searchImageOnWeb();
|
||||
|
||||
protected abstract void deleteImage();
|
||||
|
||||
private void setUpFab() {
|
||||
save.setScaleX(0);
|
||||
save.setScaleY(0);
|
||||
save.setEnabled(false);
|
||||
save.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
save();
|
||||
}
|
||||
});
|
||||
|
||||
TintHelper.setTintAuto(save, ThemeStore.accentColor(this), true);
|
||||
}
|
||||
|
||||
protected abstract void save();
|
||||
|
||||
private void getIntentExtras() {
|
||||
Bundle intentExtras = getIntent().getExtras();
|
||||
if (intentExtras != null) {
|
||||
id = intentExtras.getInt(EXTRA_ID);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract int getContentViewLayout();
|
||||
|
||||
@NonNull
|
||||
protected abstract List<String> getSongPaths();
|
||||
|
||||
protected void searchWebFor(String... keys) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (String key : keys) {
|
||||
stringBuilder.append(key);
|
||||
stringBuilder.append(" ");
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
|
||||
intent.putExtra(SearchManager.QUERY, stringBuilder.toString());
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
protected void setNoImageMode() {
|
||||
isInNoImageMode = true;
|
||||
imageContainer.setVisibility(View.GONE);
|
||||
image.setVisibility(View.GONE);
|
||||
image.setEnabled(false);
|
||||
|
||||
setColors(getIntent().getIntExtra(EXTRA_PALETTE, ThemeStore.primaryColor(this)));
|
||||
}
|
||||
|
||||
protected void dataChanged() {
|
||||
showFab();
|
||||
}
|
||||
|
||||
private void showFab() {
|
||||
save.animate()
|
||||
.setDuration(500)
|
||||
.setInterpolator(new OvershootInterpolator())
|
||||
.scaleX(1)
|
||||
.scaleY(1)
|
||||
.start();
|
||||
save.setEnabled(true);
|
||||
}
|
||||
|
||||
protected void setImageBitmap(@Nullable final Bitmap bitmap, int bgColor) {
|
||||
if (bitmap == null) {
|
||||
image.setImageResource(R.drawable.default_album_art);
|
||||
} else {
|
||||
image.setImageBitmap(bitmap);
|
||||
}
|
||||
setColors(bgColor);
|
||||
}
|
||||
|
||||
protected void setColors(int color) {
|
||||
paletteColorPrimary = color;
|
||||
}
|
||||
|
||||
protected void writeValuesToFiles(@NonNull final Map<FieldKey, String> fieldKeyValueMap,
|
||||
@Nullable final ArtworkInfo artworkInfo) {
|
||||
RetroUtil.hideSoftKeyboard(this);
|
||||
|
||||
new WriteTagsAsyncTask(this)
|
||||
.execute(new WriteTagsAsyncTask.LoadingInfo(getSongPaths(), fieldKeyValueMap, artworkInfo));
|
||||
}
|
||||
|
||||
protected int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode,
|
||||
@NonNull Intent imageReturnedIntent) {
|
||||
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
|
||||
switch (requestCode) {
|
||||
case REQUEST_CODE_SELECT_IMAGE:
|
||||
if (resultCode == RESULT_OK) {
|
||||
Uri selectedImage = imageReturnedIntent.getData();
|
||||
loadImageFromFile(selectedImage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void loadImageFromFile(Uri selectedFile);
|
||||
|
||||
@NonNull
|
||||
private AudioFile getAudioFile(@NonNull String path) {
|
||||
try {
|
||||
return AudioFileIO.read(new File(path));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not read audio file " + path, e);
|
||||
return new AudioFile();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
String getAlbumArtist() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault()
|
||||
.getFirst(FieldKey.ALBUM_ARTIST);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getSongTitle() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.TITLE);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getAlbumTitle() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ALBUM);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getArtistName() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ARTIST);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getAlbumArtistName() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault()
|
||||
.getFirst(FieldKey.ALBUM_ARTIST);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getGenreName() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.GENRE);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getSongYear() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.YEAR);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getTrackNumber() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.TRACK);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getLyrics() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.LYRICS);
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Bitmap getAlbumArt() {
|
||||
try {
|
||||
Artwork artworkTag = getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault()
|
||||
.getFirstArtwork();
|
||||
if (artworkTag != null) {
|
||||
byte[] artworkBinaryData = artworkTag.getBinaryData();
|
||||
return BitmapFactory.decodeByteArray(artworkBinaryData, 0, artworkBinaryData.length);
|
||||
}
|
||||
return null;
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ArtworkInfo {
|
||||
|
||||
public final int albumId;
|
||||
final Bitmap artwork;
|
||||
|
||||
ArtworkInfo(int albumId, Bitmap artwork) {
|
||||
this.albumId = albumId;
|
||||
this.artwork = artwork;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,281 @@
|
|||
package code.name.monkey.retromusic.ui.activities.tageditor;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.animation.GlideAnimation;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
|
||||
import code.name.monkey.retromusic.loaders.AlbumLoader;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.rest.LastFMRestClient;
|
||||
import code.name.monkey.retromusic.rest.model.LastFmAlbum;
|
||||
import code.name.monkey.retromusic.util.ImageUtil;
|
||||
import code.name.monkey.retromusic.util.LastFMUtil;
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
|
||||
public class AlbumTagEditorActivity extends AbsTagEditorActivity implements TextWatcher {
|
||||
|
||||
public static final String TAG = AlbumTagEditorActivity.class.getSimpleName();
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appBarLayout;
|
||||
@BindView(R.id.title)
|
||||
EditText albumTitle;
|
||||
@BindView(R.id.album_artist)
|
||||
EditText albumArtist;
|
||||
@BindView(R.id.genre)
|
||||
EditText genre;
|
||||
@BindView(R.id.year)
|
||||
EditText year;
|
||||
@BindView(R.id.gradient_background)
|
||||
View background;
|
||||
private Bitmap albumArtBitmap;
|
||||
private boolean deleteAlbumArt;
|
||||
private LastFMRestClient lastFMRestClient;
|
||||
|
||||
private void setupToolbar() {
|
||||
//toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
toolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
setTitle(R.string.action_tag_editor);
|
||||
setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
@OnClick(R.id.edit)
|
||||
void edit() {
|
||||
getShow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
lastFMRestClient = new LastFMRestClient(this);
|
||||
|
||||
setUpViews();
|
||||
setupToolbar();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContentViewLayout() {
|
||||
return R.layout.activity_album_tag_editor;
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
fillViewsWithFileTags();
|
||||
albumTitle.addTextChangedListener(this);
|
||||
albumArtist.addTextChangedListener(this);
|
||||
genre.addTextChangedListener(this);
|
||||
year.addTextChangedListener(this);
|
||||
}
|
||||
|
||||
|
||||
private void fillViewsWithFileTags() {
|
||||
albumTitle.setText(getAlbumTitle());
|
||||
albumArtist.setText(getAlbumArtistName());
|
||||
genre.setText(getGenreName());
|
||||
year.setText(getSongYear());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadCurrentImage() {
|
||||
Bitmap bitmap = getAlbumArt();
|
||||
setImageBitmap(bitmap, RetroColorUtil.getColor(RetroColorUtil.generatePalette(bitmap),
|
||||
ATHUtil.resolveColor(this, R.attr.defaultFooterColor)));
|
||||
deleteAlbumArt = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getImageFromLastFM() {
|
||||
String albumTitleStr = albumTitle.getText().toString();
|
||||
String albumArtistNameStr = albumArtist.getText().toString();
|
||||
if (albumArtistNameStr.trim().equals("") || albumTitleStr.trim().equals("")) {
|
||||
Toast.makeText(this, getResources().getString(R.string.album_or_artist_empty),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
lastFMRestClient.getApiService()
|
||||
.getAlbumInfo(albumTitleStr, albumArtistNameStr, null)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.subscribe(this::extractDetails);
|
||||
}
|
||||
|
||||
private void extractDetails(@NonNull LastFmAlbum lastFmAlbum) {
|
||||
if (lastFmAlbum.getAlbum() != null) {
|
||||
|
||||
String url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.getAlbum().getImage());
|
||||
|
||||
if (!TextUtils.isEmpty(url) && url.trim().length() > 0) {
|
||||
Glide.with(this)
|
||||
.load(url)
|
||||
.asBitmap()
|
||||
.transcode(new BitmapPaletteTranscoder(this), BitmapPaletteWrapper.class)
|
||||
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
|
||||
.error(R.drawable.default_album_art)
|
||||
.into(new SimpleTarget<BitmapPaletteWrapper>() {
|
||||
@Override
|
||||
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||
super.onLoadFailed(e, errorDrawable);
|
||||
e.printStackTrace();
|
||||
Toast.makeText(AlbumTagEditorActivity.this, e.toString(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(BitmapPaletteWrapper resource,
|
||||
GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
|
||||
albumArtBitmap = ImageUtil.resizeBitmap(resource.getBitmap(), 2048);
|
||||
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.getPalette(),
|
||||
ContextCompat.getColor(AlbumTagEditorActivity.this, R.color.md_grey_500)));
|
||||
deleteAlbumArt = false;
|
||||
dataChanged();
|
||||
setResult(RESULT_OK);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (lastFmAlbum.getAlbum().getTags().getTag().size() > 0) {
|
||||
genre.setText(lastFmAlbum.getAlbum().getTags().getTag().get(0).getName());
|
||||
}
|
||||
|
||||
}
|
||||
toastLoadingFailed();
|
||||
}
|
||||
|
||||
private void toastLoadingFailed() {
|
||||
Toast.makeText(AlbumTagEditorActivity.this,
|
||||
R.string.could_not_download_album_cover, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void searchImageOnWeb() {
|
||||
searchWebFor(albumTitle.getText().toString(), albumArtist.getText().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteImage() {
|
||||
setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.default_album_art),
|
||||
ATHUtil.resolveColor(this, R.attr.defaultFooterColor));
|
||||
deleteAlbumArt = true;
|
||||
dataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void save() {
|
||||
Map<FieldKey, String> fieldKeyValueMap = new EnumMap<>(FieldKey.class);
|
||||
fieldKeyValueMap.put(FieldKey.ALBUM, albumTitle.getText().toString());
|
||||
//android seems not to recognize album_artist field so we additionally write the normal artist field
|
||||
fieldKeyValueMap.put(FieldKey.ARTIST, albumArtist.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.ALBUM_ARTIST, albumArtist.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.GENRE, genre.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString());
|
||||
|
||||
writeValuesToFiles(fieldKeyValueMap, deleteAlbumArt ? new ArtworkInfo(getId(), null)
|
||||
: albumArtBitmap == null ? null : new ArtworkInfo(getId(), albumArtBitmap));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<String> getSongPaths() {
|
||||
ArrayList<Song> songs = AlbumLoader.getAlbum(this, getId()).blockingFirst().songs;
|
||||
ArrayList<String> paths = new ArrayList<>(songs.size());
|
||||
for (Song song : songs) {
|
||||
paths.add(song.data);
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadImageFromFile(@NonNull final Uri selectedFileUri) {
|
||||
Glide.with(AlbumTagEditorActivity.this)
|
||||
.load(selectedFileUri)
|
||||
.asBitmap()
|
||||
.transcode(new BitmapPaletteTranscoder(AlbumTagEditorActivity.this),
|
||||
BitmapPaletteWrapper.class)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.skipMemoryCache(true)
|
||||
.into(new SimpleTarget<BitmapPaletteWrapper>() {
|
||||
@Override
|
||||
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||
super.onLoadFailed(e, errorDrawable);
|
||||
e.printStackTrace();
|
||||
Toast.makeText(AlbumTagEditorActivity.this, e.toString(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(BitmapPaletteWrapper resource,
|
||||
GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
|
||||
RetroColorUtil.getColor(resource.getPalette(), Color.TRANSPARENT);
|
||||
albumArtBitmap = ImageUtil.resizeBitmap(resource.getBitmap(), 2048);
|
||||
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.getPalette(),
|
||||
ATHUtil.resolveColor(AlbumTagEditorActivity.this, R.attr.defaultFooterColor)));
|
||||
deleteAlbumArt = false;
|
||||
dataChanged();
|
||||
setResult(RESULT_OK);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
dataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setColors(int color) {
|
||||
super.setColors(color);
|
||||
background.setBackgroundColor(color);
|
||||
toolbar.setBackgroundColor(color);
|
||||
setStatusbarColor(ColorUtil.darkenColor(color));
|
||||
setNavigationbarColor(ColorUtil.darkenColor(color));
|
||||
setSupportActionBar(toolbar);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
package code.name.monkey.retromusic.ui.activities.tageditor;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.EditText;
|
||||
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
|
||||
|
||||
public class SongTagEditorActivity extends AbsTagEditorActivity implements TextWatcher {
|
||||
|
||||
public static final String TAG = SongTagEditorActivity.class.getSimpleName();
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.app_bar)
|
||||
AppBarLayout appBarLayout;
|
||||
@BindView(R.id.title1)
|
||||
EditText songTitle;
|
||||
@BindView(R.id.title2)
|
||||
EditText albumTitle;
|
||||
@BindView(R.id.artist)
|
||||
EditText artist;
|
||||
@BindView(R.id.genre)
|
||||
EditText genre;
|
||||
@BindView(R.id.year)
|
||||
EditText year;
|
||||
@BindView(R.id.image_text)
|
||||
EditText trackNumber;
|
||||
@BindView(R.id.lyrics)
|
||||
EditText lyrics;
|
||||
@BindView(R.id.album_artist)
|
||||
EditText albumArtist;
|
||||
|
||||
private void setupToolbar() {
|
||||
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
|
||||
toolbar.setNavigationOnClickListener(v -> onBackPressed());
|
||||
setTitle(R.string.action_tag_editor);
|
||||
setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
setStatusbarColorAuto();
|
||||
setNavigationbarColorAuto();
|
||||
|
||||
setNoImageMode();
|
||||
setUpViews();
|
||||
setupToolbar();
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
fillViewsWithFileTags();
|
||||
albumArtist.addTextChangedListener(this);
|
||||
songTitle.addTextChangedListener(this);
|
||||
albumTitle.addTextChangedListener(this);
|
||||
artist.addTextChangedListener(this);
|
||||
genre.addTextChangedListener(this);
|
||||
year.addTextChangedListener(this);
|
||||
trackNumber.addTextChangedListener(this);
|
||||
lyrics.addTextChangedListener(this);
|
||||
|
||||
}
|
||||
|
||||
private void fillViewsWithFileTags() {
|
||||
songTitle.setText(getSongTitle());
|
||||
albumArtist.setText(getAlbumArtist());
|
||||
albumTitle.setText(getAlbumTitle());
|
||||
artist.setText(getArtistName());
|
||||
genre.setText(getGenreName());
|
||||
year.setText(getSongYear());
|
||||
trackNumber.setText(getTrackNumber());
|
||||
lyrics.setText(getLyrics());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadCurrentImage() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getImageFromLastFM() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void searchImageOnWeb() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteImage() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void save() {
|
||||
Map<FieldKey, String> fieldKeyValueMap = new EnumMap<>(FieldKey.class);
|
||||
fieldKeyValueMap.put(FieldKey.TITLE, songTitle.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.ALBUM, albumTitle.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.ARTIST, artist.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.GENRE, genre.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.TRACK, trackNumber.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.LYRICS, lyrics.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.ALBUM_ARTIST, albumArtist.getText().toString());
|
||||
writeValuesToFiles(fieldKeyValueMap, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContentViewLayout() {
|
||||
return R.layout.activity_song_tag_editor;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<String> getSongPaths() {
|
||||
ArrayList<String> paths = new ArrayList<>(1);
|
||||
paths.add(SongLoader.getSong(this, getId()).blockingFirst().data);
|
||||
return paths;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadImageFromFile(Uri imageFilePath) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
dataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setColors(int color) {
|
||||
super.setColors(color);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
package code.name.monkey.retromusic.ui.activities.tageditor;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.misc.DialogAsyncTask;
|
||||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import org.jaudiotagger.audio.AudioFile;
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.audio.exceptions.CannotReadException;
|
||||
import org.jaudiotagger.audio.exceptions.CannotWriteException;
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
import org.jaudiotagger.tag.Tag;
|
||||
import org.jaudiotagger.tag.TagException;
|
||||
import org.jaudiotagger.tag.images.Artwork;
|
||||
import org.jaudiotagger.tag.images.ArtworkFactory;
|
||||
|
||||
public class WriteTagsAsyncTask extends
|
||||
DialogAsyncTask<WriteTagsAsyncTask.LoadingInfo, Integer, String[]> {
|
||||
|
||||
private Context applicationContext;
|
||||
|
||||
public WriteTagsAsyncTask(Context context) {
|
||||
super(context);
|
||||
applicationContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] doInBackground(LoadingInfo... params) {
|
||||
try {
|
||||
LoadingInfo info = params[0];
|
||||
|
||||
Artwork artwork = null;
|
||||
File albumArtFile = null;
|
||||
if (info.artworkInfo != null && info.artworkInfo.artwork != null) {
|
||||
try {
|
||||
albumArtFile = MusicUtil.createAlbumArtFile().getCanonicalFile();
|
||||
info.artworkInfo.artwork
|
||||
.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
|
||||
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
int counter = 0;
|
||||
boolean wroteArtwork = false;
|
||||
boolean deletedArtwork = false;
|
||||
for (String filePath : info.filePaths) {
|
||||
publishProgress(++counter, info.filePaths.size());
|
||||
try {
|
||||
AudioFile audioFile = AudioFileIO.read(new File(filePath));
|
||||
Tag tag = audioFile.getTagOrCreateAndSetDefault();
|
||||
|
||||
if (info.fieldKeyValueMap != null) {
|
||||
for (Map.Entry<FieldKey, String> entry : info.fieldKeyValueMap.entrySet()) {
|
||||
try {
|
||||
tag.setField(entry.getKey(), entry.getValue());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (info.artworkInfo != null) {
|
||||
if (info.artworkInfo.artwork == null) {
|
||||
tag.deleteArtworkField();
|
||||
deletedArtwork = true;
|
||||
} else if (artwork != null) {
|
||||
tag.deleteArtworkField();
|
||||
tag.setField(artwork);
|
||||
wroteArtwork = true;
|
||||
}
|
||||
}
|
||||
|
||||
audioFile.commit();
|
||||
} catch (@NonNull CannotReadException | IOException | CannotWriteException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Context context = getContext();
|
||||
if (context != null) {
|
||||
if (wroteArtwork) {
|
||||
MusicUtil.insertAlbumArt(context, info.artworkInfo.albumId, albumArtFile.getPath());
|
||||
} else if (deletedArtwork) {
|
||||
MusicUtil.deleteAlbumArt(context, info.artworkInfo.albumId);
|
||||
}
|
||||
}
|
||||
|
||||
return info.filePaths.toArray(new String[info.filePaths.size()]);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String[] toBeScanned) {
|
||||
super.onPostExecute(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(String[] toBeScanned) {
|
||||
super.onCancelled(toBeScanned);
|
||||
scan(toBeScanned);
|
||||
}
|
||||
|
||||
private void scan(String[] toBeScanned) {
|
||||
Context context = getContext();
|
||||
MediaScannerConnection.scanFile(applicationContext, toBeScanned, null,
|
||||
context instanceof Activity ? new UpdateToastMediaScannerCompletionListener(
|
||||
(Activity) context, toBeScanned) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog createDialog(@NonNull Context context) {
|
||||
return new MaterialDialog.Builder(context)
|
||||
.title(R.string.saving_changes)
|
||||
.cancelable(false)
|
||||
.progress(false, 0)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(@NonNull Dialog dialog, Integer... values) {
|
||||
super.onProgressUpdate(dialog, values);
|
||||
((MaterialDialog) dialog).setMaxProgress(values[1]);
|
||||
((MaterialDialog) dialog).setProgress(values[0]);
|
||||
}
|
||||
|
||||
public static class LoadingInfo {
|
||||
|
||||
final Collection<String> filePaths;
|
||||
@Nullable
|
||||
final Map<FieldKey, String> fieldKeyValueMap;
|
||||
@Nullable
|
||||
private AbsTagEditorActivity.ArtworkInfo artworkInfo;
|
||||
|
||||
public LoadingInfo(Collection<String> filePaths,
|
||||
@Nullable Map<FieldKey, String> fieldKeyValueMap,
|
||||
@Nullable AbsTagEditorActivity.ArtworkInfo artworkInfo) {
|
||||
this.filePaths = filePaths;
|
||||
this.fieldKeyValueMap = fieldKeyValueMap;
|
||||
this.artworkInfo = artworkInfo;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package code.name.monkey.retromusic.ui.adapter;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import butterknife.BindViews;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.ui.adapter.CollageSongAdapter.CollageSongViewHolder;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import com.bumptech.glide.Glide;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
public class CollageSongAdapter extends RecyclerView.Adapter<CollageSongViewHolder> {
|
||||
|
||||
private AppCompatActivity activity;
|
||||
private ArrayList<Album> dataSet;
|
||||
private int itemLayoutRes;
|
||||
|
||||
public CollageSongAdapter(AppCompatActivity activity, ArrayList<Album> dataSet,
|
||||
int itemLayoutRes) {
|
||||
this.activity = activity;
|
||||
this.dataSet = dataSet;
|
||||
this.itemLayoutRes = itemLayoutRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull CollageSongViewHolder holder, int position) {
|
||||
ArrayList<Album> albums = dataSet;
|
||||
|
||||
holder.bindSongs(albums);
|
||||
|
||||
if (albums.size() > 9) {
|
||||
for (int i = 0; i < albums.subList(0, 9).size(); i++) {
|
||||
if (holder.imageViews != null) {
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), albums.get(i).safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(activity).build().into(holder.imageViews.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public CollageSongViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new CollageSongViewHolder(
|
||||
LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false));
|
||||
}
|
||||
|
||||
class CollageSongViewHolder extends MediaEntryViewHolder {
|
||||
|
||||
@BindViews({R.id.image_1, R.id.image_2, R.id.image_3, R.id.image_4, R.id.image_5, R.id.image_6,
|
||||
R.id.image_7, R.id.image_8, R.id.image_9})
|
||||
@Nullable
|
||||
List<ImageView> imageViews;
|
||||
|
||||
CollageSongViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
super.onClick(v);
|
||||
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition() + 1).getId());
|
||||
}
|
||||
|
||||
void bindSongs(ArrayList<Album> albums) {
|
||||
if (imageViews != null) {
|
||||
for (int i = 0; i < imageViews.size(); i++) {
|
||||
final int startPosition = i;
|
||||
ImageView imageView = imageViews.get(i);
|
||||
imageView.setOnClickListener(
|
||||
v -> NavigationUtil.goToAlbum(activity, albums.get(startPosition).getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package code.name.monkey.retromusic.ui.adapter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class GenreAdapter extends RecyclerView.Adapter<GenreAdapter.ViewHolder> {
|
||||
private ArrayList<Genre> mGenres = new ArrayList<>();
|
||||
private Activity mActivity;
|
||||
private int mItemLayoutRes;
|
||||
|
||||
public GenreAdapter(@NonNull Activity activity, ArrayList<Genre> dataSet, int itemLayoutRes) {
|
||||
mActivity = activity;
|
||||
mGenres = dataSet;
|
||||
mItemLayoutRes = itemLayoutRes;
|
||||
}
|
||||
|
||||
public ArrayList<Genre> getDataSet() {
|
||||
return mGenres;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenreAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new ViewHolder(LayoutInflater.from(mActivity).inflate(mItemLayoutRes, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(GenreAdapter.ViewHolder holder, int position) {
|
||||
Genre genre = mGenres.get(position);
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(genre.name);
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setText(String.format(Locale.getDefault(), "%d %s", genre.songCount, genre.songCount > 1 ?
|
||||
mActivity.getString(R.string.songs) :
|
||||
mActivity.getString(R.string.song)));
|
||||
}
|
||||
if (holder.image != null) {
|
||||
holder.image.setImageResource(R.drawable.ic_recent_actors_white_24dp);
|
||||
}
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mGenres.size();
|
||||
}
|
||||
|
||||
public void swapDataSet(ArrayList<Genre> list) {
|
||||
mGenres = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
if (menu != null) {
|
||||
menu.setVisibility(View.GONE);
|
||||
}
|
||||
if (image != null) {
|
||||
int iconPadding = mActivity.getResources().getDimensionPixelSize(R.dimen.list_item_image_icon_padding);
|
||||
image.setPadding(iconPadding, iconPadding, iconPadding, iconPadding);
|
||||
image.setColorFilter(ATHUtil.resolveColor(mActivity, R.attr.iconColor), PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
super.onClick(v);
|
||||
Genre genre = mGenres.get(getAdapterPosition());
|
||||
NavigationUtil.goToGenre(mActivity, genre);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
package code.name.monkey.retromusic.ui.adapter;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
|
||||
|
||||
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder> {
|
||||
|
||||
private static final int HEADER = 0;
|
||||
private static final int ALBUM = 1;
|
||||
private static final int ARTIST = 2;
|
||||
private static final int SONG = 3;
|
||||
|
||||
private final AppCompatActivity activity;
|
||||
private List<Object> dataSet;
|
||||
|
||||
public SearchAdapter(@NonNull AppCompatActivity activity, @NonNull List<Object> dataSet) {
|
||||
this.activity = activity;
|
||||
this.dataSet = dataSet;
|
||||
}
|
||||
|
||||
public void swapDataSet(@NonNull ArrayList<Object> dataSet) {
|
||||
this.dataSet = dataSet;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (dataSet.get(position) instanceof Album) return ALBUM;
|
||||
if (dataSet.get(position) instanceof Artist) return ARTIST;
|
||||
if (dataSet.get(position) instanceof Song) return SONG;
|
||||
return HEADER;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
if (viewType == HEADER)
|
||||
return new ViewHolder(LayoutInflater.from(activity).inflate(R.layout.sub_header, parent, false), viewType);
|
||||
return new ViewHolder(LayoutInflater.from(activity).inflate(R.layout.item_list, parent, false), viewType);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||
switch (getItemViewType(position)) {
|
||||
case ALBUM:
|
||||
final Album album = (Album) dataSet.get(position);
|
||||
holder.title.setText(album.getTitle());
|
||||
holder.text.setText(album.getArtistName());
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(activity).build()
|
||||
.into(holder.image);
|
||||
break;
|
||||
case ARTIST:
|
||||
final Artist artist = (Artist) dataSet.get(position);
|
||||
holder.title.setText(artist.getName());
|
||||
holder.text.setText(MusicUtil.getArtistInfoString(activity, artist));
|
||||
ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
|
||||
.build().into(holder.image);
|
||||
break;
|
||||
case SONG:
|
||||
final Song song = (Song) dataSet.get(position);
|
||||
holder.title.setText(song.title);
|
||||
holder.text.setText(song.albumName);
|
||||
break;
|
||||
default:
|
||||
holder.title.setText(dataSet.get(position).toString());
|
||||
holder.title.setTextColor(ThemeStore.accentColor(activity));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataSet.size();
|
||||
}
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
public ViewHolder(@NonNull View itemView, int itemViewType) {
|
||||
super(itemView);
|
||||
itemView.setOnLongClickListener(null);
|
||||
|
||||
if (itemViewType != HEADER) {
|
||||
if (separator != null) {
|
||||
separator.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (menu != null) {
|
||||
if (itemViewType == SONG) {
|
||||
menu.setVisibility(View.VISIBLE);
|
||||
menu.setOnClickListener(new SongMenuHelper.OnClickSongMenu(activity) {
|
||||
@Override
|
||||
public Song getSong() {
|
||||
return (Song) dataSet.get(getAdapterPosition());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
menu.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
switch (itemViewType) {
|
||||
case ALBUM:
|
||||
setImageTransitionName(activity.getString(R.string.transition_album_art));
|
||||
break;
|
||||
case ARTIST:
|
||||
setImageTransitionName(activity.getString(R.string.transition_artist_image));
|
||||
break;
|
||||
default:
|
||||
View container = itemView.findViewById(R.id.image_container);
|
||||
if (container != null) {
|
||||
container.setVisibility(View.GONE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Object item = dataSet.get(getAdapterPosition());
|
||||
switch (getItemViewType()) {
|
||||
case ALBUM:
|
||||
NavigationUtil.goToAlbum(activity,
|
||||
((Album) item).getId(), Pair.create(image, activity.getResources().getString(R.string.transition_album_art)));
|
||||
break;
|
||||
case ARTIST:
|
||||
NavigationUtil.goToArtist(activity,
|
||||
((Artist) item).getId(), Pair.create(image, activity.getResources().getString(R.string.transition_artist_image)));
|
||||
break;
|
||||
case SONG:
|
||||
ArrayList<Song> playList = new ArrayList<>();
|
||||
playList.add((Song) item);
|
||||
MusicPlayerRemote.openQueue(playList, 0, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
package code.name.monkey.retromusic.ui.adapter;
|
||||
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.signature.MediaStoreSignature;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.AbsMultiSelectAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
public class SongFileAdapter extends AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File> implements FastScrollRecyclerView.SectionedAdapter {
|
||||
|
||||
private static final int FILE = 0;
|
||||
private static final int FOLDER = 1;
|
||||
|
||||
private final AppCompatActivity activity;
|
||||
private List<File> dataSet;
|
||||
private final int itemLayoutRes;
|
||||
@Nullable
|
||||
private final Callbacks callbacks;
|
||||
|
||||
public SongFileAdapter(@NonNull AppCompatActivity activity, @NonNull List<File> songFiles, @LayoutRes int itemLayoutRes, @Nullable Callbacks callback, @Nullable CabHolder cabHolder) {
|
||||
super(activity, cabHolder, R.menu.menu_media_selection);
|
||||
this.activity = activity;
|
||||
this.dataSet = songFiles;
|
||||
this.itemLayoutRes = itemLayoutRes;
|
||||
this.callbacks = callback;
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return dataSet.get(position).isDirectory() ? FOLDER : FILE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return dataSet.get(position).hashCode();
|
||||
}
|
||||
|
||||
public void swapDataSet(@NonNull List<File> songFiles) {
|
||||
this.dataSet = songFiles;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final ViewHolder holder, int index) {
|
||||
final File file = dataSet.get(index);
|
||||
|
||||
holder.itemView.setActivated(isChecked(file));
|
||||
|
||||
if (holder.getAdapterPosition() == getItemCount() - 1) {
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(getFileTitle(file));
|
||||
}
|
||||
if (holder.text != null) {
|
||||
if (holder.getItemViewType() == FILE) {
|
||||
holder.text.setText(getFileText(file));
|
||||
} else {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (holder.image != null) {
|
||||
loadFileImage(file, holder);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getFileTitle(File file) {
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
protected String getFileText(File file) {
|
||||
return file.isDirectory() ? null : readableFileSize(file.length());
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
protected void loadFileImage(File file, final ViewHolder holder) {
|
||||
final int iconColor = ATHUtil.resolveColor(activity, R.attr.iconColor);
|
||||
if (file.isDirectory()) {
|
||||
holder.image.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN);
|
||||
holder.image.setImageResource(R.drawable.ic_folder_white_24dp);
|
||||
} else {
|
||||
Drawable error = RetroUtil.getTintedVectorDrawable(activity, R.drawable.ic_file_music_white_24dp, iconColor);
|
||||
Glide.with(activity)
|
||||
.load(new AudioFileCover(file.getPath()))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.error(error)
|
||||
.placeholder(error)
|
||||
.animate(android.R.anim.fade_in)
|
||||
.signature(new MediaStoreSignature("", file.lastModified(), 0))
|
||||
.into(holder.image);
|
||||
}
|
||||
}
|
||||
|
||||
public static String readableFileSize(long size) {
|
||||
if (size <= 0) return size + " B";
|
||||
final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
|
||||
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
|
||||
return new DecimalFormat("#,##0.##").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataSet.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected File getIdentifier(int position) {
|
||||
return dataSet.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName(File object) {
|
||||
return getFileTitle(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMultipleItemAction(MenuItem menuItem, ArrayList<File> selection) {
|
||||
if (callbacks == null) return;
|
||||
callbacks.onMultipleItemAction(menuItem, selection);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getSectionName(int position) {
|
||||
return String.valueOf(dataSet.get(position).getName().charAt(0)).toUpperCase();
|
||||
}
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
if (menu != null && callbacks != null) {
|
||||
menu.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int position = getAdapterPosition();
|
||||
if (isPositionInRange(position)) {
|
||||
callbacks.onFileMenuClicked(dataSet.get(position), v);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int position = getAdapterPosition();
|
||||
if (isPositionInRange(position)) {
|
||||
if (isInQuickSelectMode()) {
|
||||
toggleChecked(position);
|
||||
} else {
|
||||
if (callbacks != null) {
|
||||
callbacks.onFileSelected(dataSet.get(position));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
int position = getAdapterPosition();
|
||||
return isPositionInRange(position) && toggleChecked(position);
|
||||
}
|
||||
|
||||
private boolean isPositionInRange(int position) {
|
||||
return position >= 0 && position < dataSet.size();
|
||||
}
|
||||
}
|
||||
|
||||
public interface Callbacks {
|
||||
void onFileSelected(File file);
|
||||
|
||||
void onFileMenuClicked(File file, View view);
|
||||
|
||||
void onMultipleItemAction(MenuItem item, ArrayList<File> files);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.album;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.SortOrder;
|
||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.AbsMultiSelectAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
|
||||
public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album> implements
|
||||
FastScrollRecyclerView.SectionedAdapter {
|
||||
|
||||
public static final String TAG = AlbumAdapter.class.getSimpleName();
|
||||
|
||||
protected final AppCompatActivity activity;
|
||||
protected ArrayList<Album> dataSet;
|
||||
|
||||
protected int itemLayoutRes;
|
||||
|
||||
protected boolean usePalette = false;
|
||||
private int textColor;
|
||||
|
||||
public AlbumAdapter(@NonNull AppCompatActivity activity, ArrayList<Album> dataSet,
|
||||
@LayoutRes int itemLayoutRes, boolean usePalette,
|
||||
@Nullable CabHolder cabHolder) {
|
||||
super(activity, cabHolder, R.menu.menu_media_selection);
|
||||
this.activity = activity;
|
||||
this.dataSet = dataSet;
|
||||
this.itemLayoutRes = itemLayoutRes;
|
||||
this.usePalette = usePalette;
|
||||
setHasStableIds(true);
|
||||
this.textColor = ThemeStore.textColorPrimary(activity);
|
||||
Typeface mTypeface = Typeface
|
||||
.createFromAsset(activity.getAssets(), activity.getString(R.string.sans_regular));
|
||||
}
|
||||
|
||||
public void useItemLayout(int itemLayoutRes) {
|
||||
this.itemLayoutRes = itemLayoutRes;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void usePalette(boolean usePalette) {
|
||||
this.usePalette = usePalette;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void swapDataSet(ArrayList<Album> dataSet) {
|
||||
this.dataSet = dataSet;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public ArrayList<Album> getDataSet() {
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false);
|
||||
return createViewHolder(view, viewType);
|
||||
}
|
||||
|
||||
protected ViewHolder createViewHolder(View view, int viewType) {
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
private String getAlbumTitle(Album album) {
|
||||
return album.getTitle();
|
||||
}
|
||||
|
||||
protected String getAlbumText(Album album) {
|
||||
return album.getArtistName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||
final Album album = dataSet.get(position);
|
||||
|
||||
final boolean isChecked = isChecked(album);
|
||||
holder.itemView.setActivated(isChecked);
|
||||
|
||||
if (holder.getAdapterPosition() == getItemCount() - 1) {
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(getAlbumTitle(album));
|
||||
holder.title.setTextColor(textColor);
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setText(getAlbumText(album));
|
||||
}
|
||||
if (holder.playSongs != null) {
|
||||
holder.playSongs.setOnClickListener(v -> MusicPlayerRemote.openQueue(album.songs, 0, true));
|
||||
}
|
||||
loadAlbumCover(album, holder);
|
||||
}
|
||||
|
||||
protected void setColors(int color, ViewHolder holder) {
|
||||
if (holder.paletteColorContainer != null) {
|
||||
holder.paletteColorContainer.setBackgroundColor(color);
|
||||
if (holder.title != null) {
|
||||
holder.title.setTextColor(
|
||||
MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)));
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setTextColor(
|
||||
MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadAlbumCover(Album album, final ViewHolder holder) {
|
||||
if (holder.image == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity).build()
|
||||
.into(new RetroMusicColoredTarget(holder.image) {
|
||||
@Override
|
||||
public void onLoadCleared(Drawable placeholder) {
|
||||
super.onLoadCleared(placeholder);
|
||||
setColors(getDefaultFooterColor(), holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
setColors(color, holder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataSet.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return dataSet.get(position).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Album getIdentifier(int position) {
|
||||
return dataSet.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName(Album album) {
|
||||
return album.getTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMultipleItemAction(@NonNull MenuItem menuItem,
|
||||
@NonNull ArrayList<Album> selection) {
|
||||
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.getItemId());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private ArrayList<Song> getSongList(@NonNull List<Album> albums) {
|
||||
final ArrayList<Song> songs = new ArrayList<>();
|
||||
for (Album album : albums) {
|
||||
songs.addAll(album.songs);
|
||||
}
|
||||
return songs;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getSectionName(int position) {
|
||||
@Nullable String sectionName = null;
|
||||
switch (PreferenceUtil.getInstance(activity).getAlbumSortOrder()) {
|
||||
case SortOrder.AlbumSortOrder.ALBUM_A_Z:
|
||||
case SortOrder.AlbumSortOrder.ALBUM_Z_A:
|
||||
sectionName = dataSet.get(position).getTitle();
|
||||
break;
|
||||
case SortOrder.AlbumSortOrder.ALBUM_ARTIST:
|
||||
sectionName = dataSet.get(position).getArtistName();
|
||||
break;
|
||||
case SortOrder.AlbumSortOrder.ALBUM_YEAR:
|
||||
return MusicUtil.getYearString(dataSet.get(position).getYear());
|
||||
}
|
||||
|
||||
return MusicUtil.getSectionName(sectionName);
|
||||
}
|
||||
|
||||
public void setTextColor(int textColor) {
|
||||
this.textColor = textColor;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
|
||||
public ViewHolder(@NonNull final View itemView) {
|
||||
super(itemView);
|
||||
setImageTransitionName(activity.getString(R.string.transition_album_art));
|
||||
if (menu != null) {
|
||||
menu.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (isInQuickSelectMode()) {
|
||||
toggleChecked(getAdapterPosition());
|
||||
} else {
|
||||
Pair[] albumPairs = new Pair[]{
|
||||
Pair.create(image, activity.getResources().getString(R.string.transition_album_art))};
|
||||
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).getId(), albumPairs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
toggleChecked(getAdapterPosition());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.album;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.activities.LyricsActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.NowPlayingScreen;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
|
||||
public class AlbumCoverPagerAdapter extends CustomFragmentStatePagerAdapter {
|
||||
|
||||
public static final String TAG = AlbumCoverPagerAdapter.class.getSimpleName();
|
||||
|
||||
private ArrayList<Song> dataSet;
|
||||
|
||||
private AlbumCoverFragment.ColorReceiver currentColorReceiver;
|
||||
private int currentColorReceiverPosition = -1;
|
||||
|
||||
public AlbumCoverPagerAdapter(FragmentManager fm, ArrayList<Song> dataSet) {
|
||||
super(fm);
|
||||
this.dataSet = dataSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(final int position) {
|
||||
return AlbumCoverFragment.newInstance(dataSet.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return dataSet.size();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
Object o = super.instantiateItem(container, position);
|
||||
if (currentColorReceiver != null && currentColorReceiverPosition == position) {
|
||||
receiveColor(currentColorReceiver, currentColorReceiverPosition);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only the latest passed {@link AlbumCoverFragment.ColorReceiver} is guaranteed to receive a
|
||||
* response
|
||||
*/
|
||||
public void receiveColor(AlbumCoverFragment.ColorReceiver colorReceiver, int position) {
|
||||
AlbumCoverFragment fragment = (AlbumCoverFragment) getFragment(position);
|
||||
if (fragment != null) {
|
||||
currentColorReceiver = null;
|
||||
currentColorReceiverPosition = -1;
|
||||
fragment.receiveColor(colorReceiver, position);
|
||||
} else {
|
||||
currentColorReceiver = colorReceiver;
|
||||
currentColorReceiverPosition = position;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AlbumCoverFragment extends Fragment {
|
||||
|
||||
private static final String SONG_ARG = "song";
|
||||
@BindView(R.id.player_image)
|
||||
ImageView albumCover;
|
||||
private Unbinder unbinder;
|
||||
private boolean isColorReady;
|
||||
private int color;
|
||||
private Song song;
|
||||
private ColorReceiver colorReceiver;
|
||||
private int request;
|
||||
|
||||
public static AlbumCoverFragment newInstance(final Song song) {
|
||||
AlbumCoverFragment frag = new AlbumCoverFragment();
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(SONG_ARG, song);
|
||||
frag.setArguments(args);
|
||||
return frag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) {
|
||||
song = getArguments().getParcelable(SONG_ARG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
int layout = getLayout();
|
||||
View view = inflater.inflate(layout, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
private int getLayout() {
|
||||
int layout;
|
||||
//noinspection ConstantConditions
|
||||
switch (PreferenceUtil.getInstance(getContext()).getNowPlayingScreen()) {
|
||||
case BLUR_CARD:
|
||||
layout = R.layout.fragment_album_card_cover;
|
||||
break;
|
||||
case MATERIAL:
|
||||
layout = R.layout.fragment_album_material_cover;
|
||||
break;
|
||||
case PLAIN:
|
||||
case FLAT:
|
||||
layout = R.layout.fragment_album_flat_cover;
|
||||
break;
|
||||
case CARD:
|
||||
case FULL:
|
||||
case ADAPTIVE:
|
||||
layout = R.layout.fragment_album_full_cover;
|
||||
break;
|
||||
default:
|
||||
case NORMAL:
|
||||
layout = R.layout.fragment_album_cover;
|
||||
break;
|
||||
|
||||
}
|
||||
if (PreferenceUtil.getInstance(getContext()).carouselEffect() &&
|
||||
!(PreferenceUtil.getInstance(getContext()).getNowPlayingScreen()
|
||||
== NowPlayingScreen.FULL)) {
|
||||
layout = R.layout.fragment_carousal_album_cover;
|
||||
}
|
||||
if (PreferenceUtil.getInstance(getContext()).circularAlbumArt()) {
|
||||
layout = R.layout.fragment_album_circle_cover;
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
loadAlbumCover();
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_image)
|
||||
void showLyrics() {
|
||||
startActivity(new Intent(getContext(), LyricsActivity.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
colorReceiver = null;
|
||||
}
|
||||
|
||||
private void loadAlbumCover() {
|
||||
SongGlideRequest.Builder.from(Glide.with(this), song)
|
||||
.checkIgnoreMediaStore(getActivity())
|
||||
.generatePalette(getActivity()).build()
|
||||
.into(new RetroMusicColoredTarget(albumCover) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
setColor(color);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setColor(int color) {
|
||||
this.color = color;
|
||||
isColorReady = true;
|
||||
if (colorReceiver != null) {
|
||||
colorReceiver.onColorReady(color, request);
|
||||
colorReceiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void receiveColor(ColorReceiver colorReceiver, int request) {
|
||||
if (isColorReady) {
|
||||
colorReceiver.onColorReady(color, request);
|
||||
} else {
|
||||
this.colorReceiver = colorReceiver;
|
||||
this.request = request;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ColorReceiver {
|
||||
|
||||
void onColorReady(int color, int request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (C) 2017. Alexander Bilchuk <a.bilchuk@sandrlab.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package code.name.monkey.retromusic.ui.adapter.album;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.views.MetalRecyclerViewPager;
|
||||
import com.bumptech.glide.Glide;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AlbumFullWithAdapter extends
|
||||
MetalRecyclerViewPager.MetalAdapter<AlbumFullWithAdapter.FullMetalViewHolder> {
|
||||
|
||||
private Activity activity;
|
||||
private List<Album> dataSet = new ArrayList<>();
|
||||
|
||||
public AlbumFullWithAdapter(@NonNull Activity activity,
|
||||
@NonNull DisplayMetrics metrics) {
|
||||
super(metrics);
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
public void swapData(ArrayList<Album> list) {
|
||||
dataSet = list;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FullMetalViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View viewItem = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.pager_item, parent, false);
|
||||
return new FullMetalViewHolder(viewItem);
|
||||
}
|
||||
|
||||
private Bitmap combineImageIntoOne(ArrayList<Bitmap> bitmap) {
|
||||
int w = 0, h = 0;
|
||||
for (int i = 0; i < bitmap.size(); i++) {
|
||||
if (i < bitmap.size() - 1) {
|
||||
h = bitmap.get(i).getWidth() > bitmap.get(i + 1).getWidth() ? bitmap.get(i).getWidth()
|
||||
: bitmap.get(i + 1).getWidth();
|
||||
}
|
||||
w += bitmap.get(i).getHeight();
|
||||
}
|
||||
|
||||
Bitmap temp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(temp);
|
||||
int top = 0, left = 0;
|
||||
for (int i = 0; i < bitmap.size(); i++) {
|
||||
Log.d("HTML", "Combine: " + i + "/" + bitmap.size() + 1);
|
||||
|
||||
top = (i == 0 ? 0 : top + bitmap.get(i).getHeight());
|
||||
left = (i == 0 ? 0 : top + bitmap.get(i).getWidth());
|
||||
canvas.drawBitmap(bitmap.get(i), left, 0f, null);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(FullMetalViewHolder holder, int position) {
|
||||
// don't forget about calling supper.onBindViewHolder!
|
||||
super.onBindViewHolder(holder, position);
|
||||
|
||||
final Album album = dataSet.get(position);
|
||||
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(getAlbumTitle(album));
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setText(getAlbumText(album));
|
||||
}
|
||||
if (holder.playSongs != null) {
|
||||
holder.playSongs.setOnClickListener(v -> MusicPlayerRemote.openQueue(album.songs, 0, true));
|
||||
}
|
||||
loadAlbumCover(album, holder);
|
||||
}
|
||||
|
||||
private String getAlbumTitle(Album album) {
|
||||
return album.getTitle();
|
||||
}
|
||||
|
||||
private String getAlbumText(Album album) {
|
||||
return album.getArtistName();
|
||||
}
|
||||
|
||||
private void loadAlbumCover(Album album, FullMetalViewHolder holder) {
|
||||
if (holder.image == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity).build()
|
||||
.into(new RetroMusicColoredTarget(holder.image) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataSet.size();
|
||||
}
|
||||
|
||||
class FullMetalViewHolder extends MetalRecyclerViewPager.MetalViewHolder {
|
||||
|
||||
FullMetalViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Pair[] albumPairs = new Pair[]{
|
||||
Pair.create(image, activity.getResources().getString(R.string.transition_album_art))};
|
||||
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition()).getId(), albumPairs);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.album;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.helper.HorizontalAdapterHelper;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
|
||||
|
||||
public class HorizontalAlbumAdapter extends AlbumAdapter {
|
||||
public static final String TAG = AlbumAdapter.class.getSimpleName();
|
||||
|
||||
public HorizontalAlbumAdapter(@NonNull AppCompatActivity activity, ArrayList<Album> dataSet, boolean usePalette, @Nullable CabHolder cabHolder) {
|
||||
super(activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, usePalette, cabHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ViewHolder createViewHolder(View view, int viewType) {
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
|
||||
HorizontalAdapterHelper.applyMarginToLayoutParams(activity, params, viewType);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setColors(int color, ViewHolder holder) {
|
||||
if (holder.itemView != null) {
|
||||
if (holder.title != null) {
|
||||
holder.title.setTextColor(MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)));
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAlbumCover(Album album, final ViewHolder holder) {
|
||||
if (holder.image == null) return;
|
||||
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity).build()
|
||||
.into(new RetroMusicColoredTarget(holder.image) {
|
||||
@Override
|
||||
public void onLoadCleared(Drawable placeholder) {
|
||||
super.onLoadCleared(placeholder);
|
||||
setColors(getAlbumArtistFooterColor(), holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
if (usePalette)
|
||||
setColors(color, holder);
|
||||
else
|
||||
setColors(getAlbumArtistFooterColor(), holder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAlbumText(Album album) {
|
||||
return MusicUtil.getYearString(album.getYear());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return HorizontalAdapterHelper.getItemViewtype(position, getItemCount());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.artist;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.ArtistGlideRequest;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.AbsMultiSelectAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ArtistAdapter extends
|
||||
AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist> implements
|
||||
FastScrollRecyclerView.SectionedAdapter {
|
||||
|
||||
protected final AppCompatActivity activity;
|
||||
protected ArrayList<Artist> dataSet;
|
||||
|
||||
protected int itemLayoutRes;
|
||||
|
||||
protected boolean usePalette = false;
|
||||
|
||||
|
||||
public ArtistAdapter(@NonNull AppCompatActivity activity, ArrayList<Artist> dataSet,
|
||||
@LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder) {
|
||||
super(activity, cabHolder, R.menu.menu_media_selection);
|
||||
this.activity = activity;
|
||||
this.dataSet = dataSet;
|
||||
this.itemLayoutRes = itemLayoutRes;
|
||||
this.usePalette = usePalette;
|
||||
//setHasStableIds(true);
|
||||
}
|
||||
|
||||
public void swapDataSet(ArrayList<Artist> dataSet) {
|
||||
this.dataSet = dataSet;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public ArrayList<Artist> getDataSet() {
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
public void usePalette(boolean usePalette) {
|
||||
this.usePalette = usePalette;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return dataSet.get(position).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false);
|
||||
return createViewHolder(view);
|
||||
}
|
||||
|
||||
protected ViewHolder createViewHolder(View view) {
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||
final Artist artist = dataSet.get(position);
|
||||
|
||||
boolean isChecked = isChecked(artist);
|
||||
holder.itemView.setActivated(isChecked);
|
||||
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(artist.getName());
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
}
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
loadArtistImage(artist, holder);
|
||||
}
|
||||
|
||||
protected void setColors(int color, ViewHolder holder) {
|
||||
if (holder.paletteColorContainer != null) {
|
||||
holder.paletteColorContainer.setBackgroundColor(color);
|
||||
if (holder.title != null) {
|
||||
holder.title.setTextColor(
|
||||
MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadArtistImage(Artist artist, final ViewHolder holder) {
|
||||
if (holder.image == null) {
|
||||
return;
|
||||
}
|
||||
ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
|
||||
.generatePalette(activity).build()
|
||||
.into(new RetroMusicColoredTarget(holder.image) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
setColors(color, holder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataSet.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Artist getIdentifier(int position) {
|
||||
return dataSet.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName(Artist artist) {
|
||||
return artist.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMultipleItemAction(@NonNull MenuItem menuItem,
|
||||
@NonNull ArrayList<Artist> selection) {
|
||||
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.getItemId());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private ArrayList<Song> getSongList(@NonNull List<Artist> artists) {
|
||||
final ArrayList<Song> songs = new ArrayList<>();
|
||||
for (Artist artist : artists) {
|
||||
songs.addAll(artist.getSongs()); // maybe async in future?
|
||||
}
|
||||
return songs;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getSectionName(int position) {
|
||||
return MusicUtil.getSectionName(dataSet.get(position).getName());
|
||||
}
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
setImageTransitionName(activity.getString(R.string.transition_artist_image));
|
||||
if (menu != null) {
|
||||
menu.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (isInQuickSelectMode()) {
|
||||
toggleChecked(getAdapterPosition());
|
||||
} else {
|
||||
Pair[] artistPairs = new Pair[]{Pair.create(image,
|
||||
activity.getResources().getString(R.string.transition_artist_image))};
|
||||
NavigationUtil.goToArtist(activity, dataSet.get(getAdapterPosition()).getId(), artistPairs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
toggleChecked(getAdapterPosition());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.MenuRes;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.afollestad.materialcab.MaterialCab;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
|
||||
|
||||
public abstract class AbsMultiSelectAdapter<VH extends RecyclerView.ViewHolder, I> extends RecyclerView.Adapter<VH> implements MaterialCab.Callback {
|
||||
@Nullable
|
||||
private final CabHolder cabHolder;
|
||||
private final Context context;
|
||||
private MaterialCab cab;
|
||||
private ArrayList<I> checked;
|
||||
private int menuRes;
|
||||
|
||||
public AbsMultiSelectAdapter(Context context, @Nullable CabHolder cabHolder, @MenuRes int menuRes) {
|
||||
this.cabHolder = cabHolder;
|
||||
checked = new ArrayList<>();
|
||||
this.menuRes = menuRes;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
protected void setMultiSelectMenuRes(@MenuRes int menuRes) {
|
||||
this.menuRes = menuRes;
|
||||
}
|
||||
|
||||
protected boolean toggleChecked(final int position) {
|
||||
if (cabHolder != null) {
|
||||
I identifier = getIdentifier(position);
|
||||
if (identifier == null) return false;
|
||||
|
||||
if (!checked.remove(identifier)) checked.add(identifier);
|
||||
|
||||
notifyItemChanged(position);
|
||||
updateCab();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void checkAll() {
|
||||
if (cabHolder != null) {
|
||||
checked.clear();
|
||||
for (int i = 0; i < getItemCount(); i++) {
|
||||
I identifier = getIdentifier(i);
|
||||
if (identifier != null) {
|
||||
checked.add(identifier);
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
updateCab();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCab() {
|
||||
if (cabHolder != null) {
|
||||
if (cab == null || !cab.isActive()) {
|
||||
cab = cabHolder.openCab(menuRes, this);
|
||||
}
|
||||
final int size = checked.size();
|
||||
if (size <= 0) cab.finish();
|
||||
else if (size == 1) cab.setTitle(getName(checked.get(0)));
|
||||
else cab.setTitle(context.getString(R.string.x_selected, size));
|
||||
}
|
||||
}
|
||||
|
||||
private void clearChecked() {
|
||||
checked.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
protected boolean isChecked(I identifier) {
|
||||
return checked.contains(identifier);
|
||||
}
|
||||
|
||||
protected boolean isInQuickSelectMode() {
|
||||
return cab != null && cab.isActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCabCreated(MaterialCab materialCab, Menu menu) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCabItemClicked(MenuItem menuItem) {
|
||||
if (menuItem.getItemId() == R.id.action_multi_select_adapter_check_all) {
|
||||
checkAll();
|
||||
} else {
|
||||
onMultipleItemAction(menuItem, new ArrayList<>(checked));
|
||||
cab.finish();
|
||||
clearChecked();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCabFinished(MaterialCab materialCab) {
|
||||
clearChecked();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected String getName(I object) {
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected abstract I getIdentifier(int position);
|
||||
|
||||
protected abstract void onMultipleItemAction(MenuItem menuItem, ArrayList<I> selection);
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.base;
|
||||
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
|
||||
public class MediaEntryViewHolder extends RecyclerView.ViewHolder
|
||||
implements View.OnClickListener, View.OnLongClickListener {
|
||||
|
||||
@Nullable
|
||||
@BindView(R.id.image)
|
||||
public ImageView image;
|
||||
@Nullable
|
||||
@BindView(R.id.image_text)
|
||||
public TextView imageText;
|
||||
@Nullable
|
||||
@BindView(R.id.title)
|
||||
public TextView title;
|
||||
@Nullable
|
||||
@BindView(R.id.text)
|
||||
public TextView text;
|
||||
@Nullable
|
||||
@BindView(R.id.image_container)
|
||||
public ViewGroup imageContainer;
|
||||
@Nullable
|
||||
@BindView(R.id.image_container_card)
|
||||
public CardView imageContainerCard;
|
||||
@Nullable
|
||||
@BindView(R.id.menu)
|
||||
public View menu;
|
||||
@Nullable
|
||||
@BindView(R.id.separator)
|
||||
public View separator;
|
||||
@Nullable
|
||||
@BindView(R.id.short_separator)
|
||||
public View shortSeparator;
|
||||
@Nullable
|
||||
@BindView(R.id.drag_view)
|
||||
public View dragView;
|
||||
@Nullable
|
||||
@BindView(R.id.palette_color_container)
|
||||
public View paletteColorContainer;
|
||||
@BindView(R.id.time)
|
||||
@Nullable
|
||||
public TextView time;
|
||||
@BindView(R.id.recycler_view)
|
||||
@Nullable
|
||||
public RecyclerView recyclerView;
|
||||
@BindView(R.id.play_songs)
|
||||
@Nullable
|
||||
public ImageButton playSongs;
|
||||
@BindView(R.id.image_text_container)
|
||||
@Nullable
|
||||
public CardView imageTextContainer;
|
||||
|
||||
|
||||
public MediaEntryViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
itemView.setOnLongClickListener(this);
|
||||
|
||||
if (imageTextContainer != null) {
|
||||
imageTextContainer.setCardBackgroundColor(ThemeStore.primaryColor(itemView.getContext()));
|
||||
}
|
||||
if (imageContainerCard != null) {
|
||||
imageContainerCard.setCardBackgroundColor(ThemeStore.primaryColor(itemView.getContext()));
|
||||
}
|
||||
}
|
||||
|
||||
protected void setImageTransitionName(@NonNull String transitionName) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && image != null) {
|
||||
image.setTransitionName(transitionName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.home;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
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 butterknife.BindView;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.HistoryPlaylist;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist;
|
||||
import code.name.monkey.retromusic.ui.adapter.album.AlbumAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.artist.ArtistAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.SongAdapter;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class HomeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private static final int SUB_HEADER = 0;
|
||||
private static final int ABS_PLAYLITS = 1;
|
||||
private static final int DATA = 2;
|
||||
private ArrayList<Object> dataSet = new ArrayList<>();
|
||||
private AppCompatActivity activity;
|
||||
|
||||
public HomeAdapter(@NonNull AppCompatActivity activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
|
||||
switch (i) {
|
||||
|
||||
case ABS_PLAYLITS:
|
||||
return new ViewHolder(LayoutInflater.from(activity)
|
||||
.inflate(R.layout.abs_playlists, viewGroup, false));
|
||||
default:
|
||||
case DATA:
|
||||
return new ViewHolder(LayoutInflater.from(activity)
|
||||
.inflate(R.layout.recycler_view_sec, viewGroup, false));
|
||||
case SUB_HEADER:
|
||||
return new ViewHolder(LayoutInflater.from(activity)
|
||||
.inflate(R.layout.sub_header, viewGroup, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (dataSet.get(position) instanceof String) {
|
||||
return SUB_HEADER;
|
||||
} else if (dataSet.get(position) instanceof Integer) {
|
||||
return ABS_PLAYLITS;
|
||||
} else if (dataSet.get(position) instanceof ArrayList) {
|
||||
return DATA;
|
||||
}
|
||||
return super.getItemViewType(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) {
|
||||
ViewHolder viewholder = (ViewHolder) holder;
|
||||
switch (getItemViewType(i)) {
|
||||
case ABS_PLAYLITS:
|
||||
bindAbsActions(viewholder);
|
||||
break;
|
||||
case SUB_HEADER:
|
||||
String title = (String) dataSet.get(i);
|
||||
if (viewholder.title != null) {
|
||||
viewholder.title.setText(title);
|
||||
}
|
||||
break;
|
||||
case DATA:
|
||||
parseAllSections(i, viewholder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void bindAbsActions(ViewHolder viewholder) {
|
||||
|
||||
|
||||
if (viewholder.shuffle != null) {
|
||||
viewholder.shuffle.setOnClickListener(view -> MusicPlayerRemote
|
||||
.openAndShuffleQueue(SongLoader.getAllSongs(activity).blockingFirst(), true));
|
||||
}
|
||||
/*if (viewholder.search != null) {
|
||||
viewholder.search.setBackgroundTintList(ColorStateList.valueOf(ColorUtil.withAlpha(ThemeStore.textColorPrimary(activity), 0.2f)));
|
||||
viewholder.search.setOnClickListener(view -> {
|
||||
activity.startActivity(new Intent(activity, SearchActivity.class));
|
||||
});
|
||||
}*/
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void parseAllSections(int i, ViewHolder viewholder) {
|
||||
if (viewholder.recyclerView != null) {
|
||||
ArrayList arrayList = (ArrayList) dataSet.get(i);
|
||||
if (arrayList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Object something = arrayList.get(0);
|
||||
if (something instanceof Artist) {
|
||||
layoutManager(viewholder);
|
||||
viewholder.recyclerView.setAdapter(
|
||||
new ArtistAdapter(activity, (ArrayList<Artist>) arrayList, R.layout.item_artist, false,
|
||||
null));
|
||||
} else if (something instanceof Album) {
|
||||
layoutManager(viewholder);
|
||||
viewholder.recyclerView.setItemAnimator(new DefaultItemAnimator());
|
||||
viewholder.recyclerView.setAdapter(
|
||||
new AlbumAdapter(activity, (ArrayList<Album>) arrayList, R.layout.item_image, false,
|
||||
null));
|
||||
} else if (something instanceof Song) {
|
||||
GridLayoutManager layoutManager = new GridLayoutManager(activity, 1,
|
||||
LinearLayoutManager.HORIZONTAL, false);
|
||||
viewholder.recyclerView.setLayoutManager(layoutManager);
|
||||
viewholder.recyclerView.setAdapter(
|
||||
new SongAdapter(activity, (ArrayList<Song>) arrayList, R.layout.item_image, false,
|
||||
null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void layoutManager(ViewHolder viewholder) {
|
||||
if (viewholder.recyclerView != null) {
|
||||
viewholder.recyclerView.setLayoutManager(
|
||||
new GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false));
|
||||
viewholder.recyclerView.setItemAnimator(new DefaultItemAnimator());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataSet.size();
|
||||
}
|
||||
|
||||
public void swapDataSet(@NonNull ArrayList<Object> data) {
|
||||
dataSet = data;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public ArrayList<Object> getDataset() {
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
|
||||
|
||||
@BindView(R.id.action_shuffle)
|
||||
@Nullable
|
||||
View shuffle;
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,300 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.playlist;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.dialogs.ClearSmartPlaylistDialog;
|
||||
import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog;
|
||||
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper;
|
||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
|
||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist;
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.AbsMultiSelectAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import io.reactivex.Observable;
|
||||
|
||||
/**
|
||||
* Created by BlackFootSanji on 9/19/2016.
|
||||
*/
|
||||
public class PlaylistAdapter extends AbsMultiSelectAdapter<PlaylistAdapter.ViewHolder, Playlist> {
|
||||
|
||||
public static final String TAG = PlaylistAdapter.class.getSimpleName();
|
||||
|
||||
private static final int SMART_PLAYLIST = 0;
|
||||
private static final int DEFAULT_PLAYLIST = 1;
|
||||
|
||||
protected final AppCompatActivity activity;
|
||||
protected ArrayList<Playlist> dataSet;
|
||||
protected int itemLayoutRes;
|
||||
private ArrayList<Song> mSongs = new ArrayList<>();
|
||||
|
||||
|
||||
public PlaylistAdapter(AppCompatActivity activity, ArrayList<Playlist> dataSet,
|
||||
@LayoutRes int itemLayoutRes, @Nullable CabHolder cabHolder) {
|
||||
super(activity, cabHolder, R.menu.menu_playlists_selection);
|
||||
this.activity = activity;
|
||||
this.dataSet = dataSet;
|
||||
this.itemLayoutRes = itemLayoutRes;
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
public ArrayList<Playlist> getDataSet() {
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
public void swapDataSet(ArrayList<Playlist> dataSet) {
|
||||
this.dataSet = dataSet;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return dataSet.get(position).id;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(activity)
|
||||
.inflate(itemLayoutRes, parent, false);
|
||||
return createViewHolder(view, viewType);
|
||||
}
|
||||
|
||||
protected ViewHolder createViewHolder(View view, int viewType) {
|
||||
return new ViewHolder(view, viewType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
/* if (getItemViewType(position) == SMART_PLAYLIST) {
|
||||
if (holder.viewList != null) {
|
||||
holder.viewList.get(0).setOnClickListener(
|
||||
v -> NavigationUtil.goToPlaylistNew(activity, new HistoryPlaylist(activity)));
|
||||
holder.viewList.get(1).setOnClickListener(
|
||||
v -> NavigationUtil.goToPlaylistNew(activity, new LastAddedPlaylist(activity)));
|
||||
holder.viewList.get(2).setOnClickListener(
|
||||
v -> NavigationUtil.goToPlaylistNew(activity, new MyTopTracksPlaylist(activity)));
|
||||
}
|
||||
return;
|
||||
}*/
|
||||
final Playlist playlist = dataSet.get(position);
|
||||
ArrayList<Song> songs = getSongs(playlist);
|
||||
holder.itemView.setActivated(isChecked(playlist));
|
||||
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(playlist.name);
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setText(String.format(Locale.getDefault(), "%d Songs", songs.size()));
|
||||
}
|
||||
if (holder.image != null) {
|
||||
holder.image.setImageResource(getIconRes(playlist));
|
||||
}
|
||||
if (holder.getAdapterPosition() == getItemCount() - 1) {
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
if (holder.shortSeparator != null && !(dataSet.get(position) instanceof AbsSmartPlaylist)) {
|
||||
holder.shortSeparator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getIconRes(Playlist playlist) {
|
||||
if (playlist instanceof AbsSmartPlaylist) {
|
||||
return ((AbsSmartPlaylist) playlist).iconRes;
|
||||
}
|
||||
return MusicUtil.isFavoritePlaylist(activity, playlist) ? R.drawable.ic_favorite_white_24dp
|
||||
: R.drawable.ic_playlist_play_white_24dp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return dataSet.get(position) instanceof AbsSmartPlaylist ? SMART_PLAYLIST : DEFAULT_PLAYLIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataSet.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Playlist getIdentifier(int position) {
|
||||
return dataSet.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName(Playlist playlist) {
|
||||
return playlist.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMultipleItemAction(@NonNull MenuItem menuItem,
|
||||
@NonNull ArrayList<Playlist> selection) {
|
||||
switch (menuItem.getItemId()) {
|
||||
case R.id.action_delete_playlist:
|
||||
for (int i = 0; i < selection.size(); i++) {
|
||||
Playlist playlist = selection.get(i);
|
||||
if (playlist instanceof AbsSmartPlaylist) {
|
||||
AbsSmartPlaylist absSmartPlaylist = (AbsSmartPlaylist) playlist;
|
||||
ClearSmartPlaylistDialog.create(absSmartPlaylist)
|
||||
.show(activity.getSupportFragmentManager(),
|
||||
"CLEAR_PLAYLIST_" + absSmartPlaylist.name);
|
||||
selection.remove(playlist);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (selection.size() > 0) {
|
||||
DeletePlaylistDialog.create(selection)
|
||||
.show(activity.getSupportFragmentManager(), "DELETE_PLAYLIST");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SongsMenuHelper.handleMenuClick(activity, getSongList(selection), menuItem.getItemId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Song> getSongs() {
|
||||
return mSongs;
|
||||
}
|
||||
|
||||
public void setSongs(ArrayList<Song> songs) {
|
||||
mSongs = songs;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private ArrayList<Song> getSongList(@NonNull List<Playlist> playlists) {
|
||||
final ArrayList<Song> songs = new ArrayList<>();
|
||||
for (Playlist playlist : playlists) {
|
||||
if (playlist instanceof AbsCustomPlaylist) {
|
||||
songs.addAll(((AbsCustomPlaylist) playlist).getSongs(activity).blockingFirst());
|
||||
//((AbsCustomPlaylist) playlist).getSongs(activity).subscribe(this::setSongs);
|
||||
} else {
|
||||
songs
|
||||
.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id).blockingFirst());
|
||||
}
|
||||
}
|
||||
return songs;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ArrayList<Song> getSongs(@NonNull Playlist playlist) {
|
||||
final ArrayList<Song> songs = new ArrayList<>();
|
||||
if (playlist instanceof AbsSmartPlaylist) {
|
||||
songs.addAll(((AbsSmartPlaylist) playlist).getSongs(activity).blockingFirst());
|
||||
} else {
|
||||
songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id).blockingFirst());
|
||||
}
|
||||
return songs;
|
||||
}
|
||||
|
||||
private Observable<ArrayList<Bitmap>> loadBitmaps(@NonNull ArrayList<Song> songs) {
|
||||
return Observable.create(e -> {
|
||||
ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
|
||||
for (Song song : songs) {
|
||||
try {
|
||||
Bitmap bitmap = Glide.with(activity)
|
||||
.load(RetroUtil.getAlbumArtUri(song.albumId))
|
||||
.asBitmap()
|
||||
.into(500, 500)
|
||||
.get();
|
||||
if (bitmap != null) {
|
||||
Log.i(TAG, "loadBitmaps: has");
|
||||
bitmaps.add(bitmap);
|
||||
}
|
||||
if (bitmaps.size() == 4) {
|
||||
break;
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
e.onNext(bitmaps);
|
||||
e.onComplete();
|
||||
});
|
||||
}
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
public ViewHolder(@NonNull View itemView, int itemViewType) {
|
||||
super(itemView);
|
||||
ButterKnife.bind(this, itemView);
|
||||
if (image != null) {
|
||||
int iconPadding = activity.getResources()
|
||||
.getDimensionPixelSize(R.dimen.list_item_image_icon_padding);
|
||||
image.setPadding(iconPadding, iconPadding, iconPadding, iconPadding);
|
||||
image.setColorFilter(ATHUtil.resolveColor(activity, R.attr.iconColor),
|
||||
PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
if (menu != null) {
|
||||
menu.setOnClickListener(view -> {
|
||||
final Playlist playlist = dataSet.get(getAdapterPosition());
|
||||
final PopupMenu popupMenu = new PopupMenu(activity, view);
|
||||
popupMenu.inflate(getItemViewType() == SMART_PLAYLIST ? R.menu.menu_item_smart_playlist
|
||||
: R.menu.menu_item_playlist);
|
||||
if (playlist instanceof LastAddedPlaylist) {
|
||||
popupMenu.getMenu().findItem(R.id.action_clear_playlist).setVisible(false);
|
||||
}
|
||||
popupMenu.setOnMenuItemClickListener(item -> {
|
||||
if (item.getItemId() == R.id.action_clear_playlist) {
|
||||
if (playlist instanceof AbsSmartPlaylist) {
|
||||
ClearSmartPlaylistDialog.create((AbsSmartPlaylist) playlist)
|
||||
.show(activity.getSupportFragmentManager(),
|
||||
"CLEAR_SMART_PLAYLIST_" + playlist.name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return PlaylistMenuHelper.handleMenuClick(
|
||||
activity, dataSet.get(getAdapterPosition()), item);
|
||||
});
|
||||
popupMenu.show();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (isInQuickSelectMode()) {
|
||||
toggleChecked(getAdapterPosition());
|
||||
} else {
|
||||
Playlist playlist = dataSet.get(getAdapterPosition());
|
||||
NavigationUtil.goToPlaylistNew(activity, playlist);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
toggleChecked(getAdapterPosition());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.song;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
|
||||
|
||||
public abstract class AbsOffsetSongAdapter extends SongAdapter {
|
||||
|
||||
protected static final int OFFSET_ITEM = 0;
|
||||
protected static final int SONG = 1;
|
||||
|
||||
public AbsOffsetSongAdapter(AppCompatActivity activity, ArrayList<Song> dataSet, @LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder) {
|
||||
super(activity, dataSet, itemLayoutRes, usePalette, cabHolder);
|
||||
}
|
||||
|
||||
public AbsOffsetSongAdapter(AppCompatActivity activity, ArrayList<Song> dataSet, @LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder, boolean showSectionName) {
|
||||
super(activity, dataSet, itemLayoutRes, usePalette, cabHolder, showSectionName);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SongAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
if (viewType == OFFSET_ITEM) {
|
||||
View view = LayoutInflater.from(activity).inflate(R.layout.item_list_single_row, parent, false);
|
||||
return createViewHolder(view);
|
||||
}
|
||||
return super.onCreateViewHolder(parent, viewType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SongAdapter.ViewHolder createViewHolder(View view) {
|
||||
return new AbsOffsetSongAdapter.ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
position--;
|
||||
if (position < 0) return -2;
|
||||
return super.getItemId(position);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Song getIdentifier(int position) {
|
||||
position--;
|
||||
if (position < 0) return null;
|
||||
return super.getIdentifier(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
int superItemCount = super.getItemCount();
|
||||
return superItemCount == 0 ? 0 : superItemCount + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return position == 0 ? OFFSET_ITEM : SONG;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getSectionName(int position) {
|
||||
position--;
|
||||
if (position < 0) return "";
|
||||
return super.getSectionName(position);
|
||||
}
|
||||
|
||||
public class ViewHolder extends SongAdapter.ViewHolder {
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Song getSong() {
|
||||
if (getItemViewType() == OFFSET_ITEM)
|
||||
return Song.EMPTY_SONG; // could also return null, just to be safe return empty song
|
||||
return dataSet.get(getAdapterPosition() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (isInQuickSelectMode() && getItemViewType() != OFFSET_ITEM) {
|
||||
toggleChecked(getAdapterPosition());
|
||||
} else {
|
||||
MusicPlayerRemote.openQueue(dataSet, getAdapterPosition() - 1, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
if (getItemViewType() == OFFSET_ITEM) return false;
|
||||
toggleChecked(getAdapterPosition());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.song;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemViewHolder;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags;
|
||||
import code.name.monkey.retromusic.model.PlaylistSong;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.dialogs.RemoveFromPlaylistDialog;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class OrderablePlaylistSongAdapter extends PlaylistSongAdapter
|
||||
implements DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
||||
|
||||
public static final String TAG = OrderablePlaylistSongAdapter.class.getSimpleName();
|
||||
|
||||
private OnMoveItemListener onMoveItemListener;
|
||||
|
||||
public OrderablePlaylistSongAdapter(@NonNull AppCompatActivity activity,
|
||||
@NonNull ArrayList<PlaylistSong> dataSet,
|
||||
@LayoutRes int itemLayoutRes,
|
||||
boolean usePalette,
|
||||
@Nullable CabHolder cabHolder,
|
||||
@Nullable OnMoveItemListener onMoveItemListener) {
|
||||
super(activity, (ArrayList<Song>) (List) dataSet, itemLayoutRes, usePalette, cabHolder);
|
||||
setMultiSelectMenuRes(R.menu.menu_playlists_songs_selection);
|
||||
this.onMoveItemListener = onMoveItemListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SongAdapter.ViewHolder createViewHolder(View view) {
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
position--;
|
||||
if (position < 0) return -2;
|
||||
return ((ArrayList<PlaylistSong>) (List) dataSet).get(position).idInPlayList; // important!
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMultipleItemAction(@NonNull MenuItem menuItem, @NonNull ArrayList<Song> selection) {
|
||||
switch (menuItem.getItemId()) {
|
||||
case R.id.action_remove_from_playlist:
|
||||
RemoveFromPlaylistDialog.create((ArrayList<PlaylistSong>) (List) selection).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||
return;
|
||||
}
|
||||
super.onMultipleItemAction(menuItem, selection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCheckCanStartDrag(ViewHolder holder, int position, int x, int y) {
|
||||
return onMoveItemListener != null && position > 0 &&
|
||||
(ViewUtil.hitTest(holder.dragView, x, y) || ViewUtil.hitTest(holder.image, x, y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemDraggableRange onGetItemDraggableRange(ViewHolder holder, int position) {
|
||||
return new ItemDraggableRange(1, dataSet.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveItem(int fromPosition, int toPosition) {
|
||||
if (onMoveItemListener != null && fromPosition != toPosition) {
|
||||
onMoveItemListener.onMoveItem(fromPosition - 1, toPosition - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCheckCanDrop(int draggingPosition, int dropPosition) {
|
||||
return dropPosition > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemDragStarted(int position) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemDragFinished(int fromPosition, int toPosition, boolean result) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public interface OnMoveItemListener {
|
||||
void onMoveItem(int fromPosition, int toPosition);
|
||||
}
|
||||
|
||||
public class ViewHolder extends PlaylistSongAdapter.ViewHolder implements DraggableItemViewHolder {
|
||||
@DraggableItemStateFlags
|
||||
private int mDragStateFlags;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
if (dragView != null) {
|
||||
if (onMoveItemListener != null) {
|
||||
dragView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
dragView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSongMenuRes() {
|
||||
return R.menu.menu_item_playlist_song;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onSongMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_remove_from_playlist:
|
||||
RemoveFromPlaylistDialog.create((PlaylistSong) getSong()).show(activity.getSupportFragmentManager(), "REMOVE_FROM_PLAYLIST");
|
||||
return true;
|
||||
}
|
||||
return super.onSongMenuItemClick(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DraggableItemStateFlags
|
||||
public int getDragStateFlags() {
|
||||
return mDragStateFlags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDragStateFlags(@DraggableItemStateFlags int flags) {
|
||||
mDragStateFlags = flags;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.song;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemViewHolder;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
||||
|
||||
public class PlayingQueueAdapter extends SongAdapter implements
|
||||
DraggableItemAdapter<PlayingQueueAdapter.ViewHolder> {
|
||||
|
||||
private static final int HISTORY = 0;
|
||||
private static final int CURRENT = 1;
|
||||
private static final int UP_NEXT = 2;
|
||||
|
||||
private int current;
|
||||
|
||||
public PlayingQueueAdapter(AppCompatActivity activity, ArrayList<Song> dataSet, int current,
|
||||
@LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder) {
|
||||
super(activity, dataSet, itemLayoutRes, usePalette, cabHolder);
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SongAdapter.ViewHolder createViewHolder(View view) {
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull SongAdapter.ViewHolder holder, int position) {
|
||||
super.onBindViewHolder(holder, position);
|
||||
if (holder.imageText != null) {
|
||||
holder.imageText.setText(String.valueOf(position - current));
|
||||
}
|
||||
if (holder.time != null) {
|
||||
holder.time.setText(MusicUtil.getReadableDurationString(getDataSet().get(position).duration));
|
||||
}
|
||||
if (holder.getItemViewType() == HISTORY || holder.getItemViewType() == CURRENT) {
|
||||
setAlpha(holder, 0.5f);
|
||||
}
|
||||
if (usePalette) {
|
||||
setColor(holder, Color.WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setColor(SongAdapter.ViewHolder holder, int white) {
|
||||
|
||||
if (holder.title != null) {
|
||||
holder.title.setTextColor(white);
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setTextColor(white);
|
||||
}
|
||||
if (holder.time != null) {
|
||||
holder.time.setTextColor(white);
|
||||
}
|
||||
if (holder.imageText != null) {
|
||||
holder.imageText.setTextColor(white);
|
||||
}
|
||||
if (holder.menu != null) {
|
||||
((ImageView) holder.menu).setColorFilter(white, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void usePalette(boolean color) {
|
||||
super.usePalette(color);
|
||||
usePalette = color;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position < current) {
|
||||
return HISTORY;
|
||||
} else if (position > current) {
|
||||
return UP_NEXT;
|
||||
}
|
||||
return CURRENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAlbumCover(Song song, SongAdapter.ViewHolder holder) {
|
||||
// We don't want to load it in this adapter
|
||||
}
|
||||
|
||||
public void swapDataSet(ArrayList<Song> dataSet, int position) {
|
||||
this.dataSet = dataSet;
|
||||
current = position;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setCurrent(int current) {
|
||||
this.current = current;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void setAlpha(SongAdapter.ViewHolder holder, float alpha) {
|
||||
if (holder.image != null) {
|
||||
holder.image.setAlpha(alpha);
|
||||
}
|
||||
if (holder.title != null) {
|
||||
holder.title.setAlpha(alpha);
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setAlpha(alpha);
|
||||
}
|
||||
if (holder.imageText != null) {
|
||||
holder.imageText.setAlpha(alpha);
|
||||
}
|
||||
if (holder.paletteColorContainer != null) {
|
||||
holder.paletteColorContainer.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCheckCanStartDrag(ViewHolder holder, int position, int x, int y) {
|
||||
return ViewUtil.hitTest(holder.imageText, x, y) || (ViewUtil.hitTest(holder.dragView, x, y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemDraggableRange onGetItemDraggableRange(ViewHolder holder, int position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveItem(int fromPosition, int toPosition) {
|
||||
MusicPlayerRemote.moveSong(fromPosition, toPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCheckCanDrop(int draggingPosition, int dropPosition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemDragStarted(int position) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemDragFinished(int fromPosition, int toPosition, boolean result) {
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public class ViewHolder extends SongAdapter.ViewHolder implements DraggableItemViewHolder {
|
||||
|
||||
@DraggableItemStateFlags
|
||||
private int mDragStateFlags;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
if (imageText != null) {
|
||||
imageText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (image != null) {
|
||||
image.setVisibility(View.GONE);
|
||||
}
|
||||
if (dragView != null) {
|
||||
dragView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSongMenuRes() {
|
||||
return R.menu.menu_item_playing_queue_song;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onSongMenuItemClick(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_remove_from_playing_queue:
|
||||
MusicPlayerRemote.removeFromQueue(getAdapterPosition());
|
||||
return true;
|
||||
}
|
||||
return super.onSongMenuItemClick(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DraggableItemStateFlags
|
||||
public int getDragStateFlags() {
|
||||
return mDragStateFlags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDragStateFlags(@DraggableItemStateFlags int flags) {
|
||||
mDragStateFlags = flags;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.song;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
|
||||
|
||||
public class PlaylistSongAdapter extends AbsOffsetSongAdapter {
|
||||
|
||||
public static final String TAG = PlaylistSongAdapter.class.getSimpleName();
|
||||
|
||||
public PlaylistSongAdapter(AppCompatActivity activity, @NonNull ArrayList<Song> dataSet, @LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder) {
|
||||
super(activity, dataSet, itemLayoutRes, usePalette, cabHolder, false);
|
||||
setMultiSelectMenuRes(R.menu.menu_cannot_delete_single_songs_playlist_songs_selection);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SongAdapter.ViewHolder createViewHolder(View view) {
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final SongAdapter.ViewHolder holder, int position) {
|
||||
if (holder.getItemViewType() == OFFSET_ITEM) {
|
||||
int textColor = ThemeStore.textColorSecondary(activity);
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(MusicUtil.getPlaylistInfoString(activity, dataSet));
|
||||
holder.title.setTextColor(textColor);
|
||||
}
|
||||
|
||||
|
||||
if (holder.text != null) {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
}
|
||||
if (holder.menu != null) {
|
||||
holder.menu.setVisibility(View.GONE);
|
||||
}
|
||||
if (holder.image != null) {
|
||||
final int padding = activity.getResources().getDimensionPixelSize(R.dimen.default_item_margin) / 2;
|
||||
holder.image.setPadding(padding, padding, padding, padding);
|
||||
holder.image.setColorFilter(textColor);
|
||||
holder.image.setImageResource(R.drawable.ic_timer_white_24dp);
|
||||
}
|
||||
if (holder.dragView != null) {
|
||||
holder.dragView.setVisibility(View.GONE);
|
||||
}
|
||||
if (holder.separator != null) {
|
||||
holder.separator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewHolder extends AbsOffsetSongAdapter.ViewHolder {
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSongMenuRes() {
|
||||
return R.menu.menu_item_cannot_delete_single_songs_playlist_song;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onSongMenuItemClick(MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_go_to_album) {
|
||||
Pair[] albumPairs = new Pair[]{
|
||||
Pair.create(image, activity.getString(R.string.transition_album_art))};
|
||||
NavigationUtil.goToAlbum(activity, dataSet.get(getAdapterPosition() - 1).albumId, albumPairs);
|
||||
return true;
|
||||
}
|
||||
return super.onSongMenuItemClick(item);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.song;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class ShuffleButtonSongAdapter extends AbsOffsetSongAdapter {
|
||||
|
||||
public ShuffleButtonSongAdapter(AppCompatActivity activity, ArrayList<Song> dataSet,
|
||||
@LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder) {
|
||||
super(activity, dataSet, itemLayoutRes, usePalette, cabHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SongAdapter.ViewHolder createViewHolder(View view) {
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final SongAdapter.ViewHolder holder, int position) {
|
||||
if (holder.getItemViewType() == OFFSET_ITEM) {
|
||||
int accentColor = ThemeStore.accentColor(activity);
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(activity.getResources().getString(R.string.action_shuffle_all));
|
||||
holder.title.setTextColor(accentColor);
|
||||
/*((GradientTextView) holder.title).setLinearGradient(ThemeStore.accentColor(activity),
|
||||
PhonographColorUtil.getMatColor(activity, "A400"), GradientTextView.LG_VERTICAL);
|
||||
*/
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setVisibility(View.GONE);
|
||||
}
|
||||
if (holder.menu != null) {
|
||||
holder.menu.setVisibility(View.GONE);
|
||||
}
|
||||
if (holder.image != null) {
|
||||
final int padding =
|
||||
activity.getResources().getDimensionPixelSize(R.dimen.default_item_margin) / 2;
|
||||
holder.image.setPadding(padding, padding, padding, padding);
|
||||
holder.image.setColorFilter(accentColor);
|
||||
holder.image.setImageResource(R.drawable.ic_shuffle_white_24dp);
|
||||
}
|
||||
if (holder.separator != null) {
|
||||
holder.separator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewHolder extends AbsOffsetSongAdapter.ViewHolder {
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getItemViewType() == OFFSET_ITEM) {
|
||||
MusicPlayerRemote.openAndShuffleQueue(dataSet, true);
|
||||
return;
|
||||
}
|
||||
super.onClick(v);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.song;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
|
||||
/**
|
||||
* Created by Monkey D Luffy on 3/31/2016.
|
||||
*/
|
||||
public class SimpleSongAdapter extends SongAdapter {
|
||||
|
||||
private int textColor;
|
||||
|
||||
public SimpleSongAdapter(AppCompatActivity context, ArrayList<Song> songs, @LayoutRes int i) {
|
||||
super(context, songs, i, false, null);
|
||||
textColor = ThemeStore.textColorPrimary(context);
|
||||
}
|
||||
|
||||
public void swapDataSet(ArrayList<Song> arrayList) {
|
||||
this.dataSet.clear();
|
||||
this.dataSet = arrayList;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
return new ViewHolder(LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
super.onBindViewHolder(holder, position);
|
||||
int fixedTrackNumber = MusicUtil.getFixedTrackNumber(dataSet.get(position).trackNumber);
|
||||
|
||||
if (holder.imageText != null) {
|
||||
holder.imageText.setText(fixedTrackNumber > 0 ? String.valueOf(fixedTrackNumber) : "-");
|
||||
holder.imageText.setTextColor(textColor);
|
||||
}
|
||||
|
||||
if (holder.time != null) {
|
||||
holder.time.setText(MusicUtil.getReadableDurationString(dataSet.get(position).duration));
|
||||
holder.time.setTextColor(textColor);
|
||||
}
|
||||
if (holder.title != null) {
|
||||
holder.title.setTextColor(textColor);
|
||||
}
|
||||
if (holder.menu != null) {
|
||||
TintHelper.setTintAuto(holder.menu, textColor, false);
|
||||
}
|
||||
}
|
||||
|
||||
public int getItemCount() {
|
||||
return dataSet.size();
|
||||
}
|
||||
|
||||
public void setTextColor(int textColor) {
|
||||
this.textColor = textColor;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,294 @@
|
|||
package code.name.monkey.retromusic.ui.adapter.song;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.afollestad.materialcab.MaterialCab;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.SortOrder;
|
||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper;
|
||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.AbsMultiSelectAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.base.MediaEntryViewHolder;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 13/08/17.
|
||||
*/
|
||||
|
||||
public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song>
|
||||
implements MaterialCab.Callback, FastScrollRecyclerView.SectionedAdapter {
|
||||
|
||||
public static final String TAG = SongAdapter.class.getSimpleName();
|
||||
|
||||
protected final AppCompatActivity activity;
|
||||
protected ArrayList<Song> dataSet;
|
||||
|
||||
protected int itemLayoutRes;
|
||||
|
||||
protected boolean usePalette = false;
|
||||
private boolean showSectionName = true;
|
||||
|
||||
|
||||
public SongAdapter(AppCompatActivity activity, ArrayList<Song> dataSet,
|
||||
@LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder) {
|
||||
this(activity, dataSet, itemLayoutRes, usePalette, cabHolder, true);
|
||||
}
|
||||
|
||||
public SongAdapter(AppCompatActivity activity, ArrayList<Song> dataSet,
|
||||
@LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder,
|
||||
boolean showSectionName) {
|
||||
super(activity, cabHolder, R.menu.menu_media_selection);
|
||||
this.activity = activity;
|
||||
this.dataSet = dataSet;
|
||||
this.itemLayoutRes = itemLayoutRes;
|
||||
this.usePalette = usePalette;
|
||||
this.showSectionName = showSectionName;
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
public void swapDataSet(ArrayList<Song> dataSet) {
|
||||
this.dataSet = dataSet;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void usePalette(boolean usePalette) {
|
||||
this.usePalette = usePalette;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public ArrayList<Song> getDataSet() {
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return dataSet.get(position).id;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(activity).inflate(itemLayoutRes, parent, false);
|
||||
return createViewHolder(view);
|
||||
}
|
||||
|
||||
protected ViewHolder createViewHolder(View view) {
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||
final Song song = dataSet.get(position);
|
||||
|
||||
boolean isChecked = isChecked(song);
|
||||
holder.itemView.setActivated(isChecked);
|
||||
|
||||
if (holder.getAdapterPosition() == getItemCount() - 1) {
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
if (holder.shortSeparator != null) {
|
||||
holder.shortSeparator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (holder.title != null) {
|
||||
holder.title.setText(getSongTitle(song));
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setText(getSongText(song));
|
||||
}
|
||||
|
||||
loadAlbumCover(song, holder);
|
||||
|
||||
}
|
||||
|
||||
private void setColors(int color, ViewHolder holder) {
|
||||
if (holder.paletteColorContainer != null) {
|
||||
holder.paletteColorContainer.setBackgroundColor(color);
|
||||
if (holder.title != null) {
|
||||
holder.title.setTextColor(
|
||||
MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)));
|
||||
}
|
||||
if (holder.text != null) {
|
||||
holder.text.setTextColor(
|
||||
MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadAlbumCover(Song song, final ViewHolder holder) {
|
||||
if (holder.image == null) {
|
||||
return;
|
||||
}
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), song)
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity).build()
|
||||
.into(new RetroMusicColoredTarget(holder.image) {
|
||||
@Override
|
||||
public void onLoadCleared(Drawable placeholder) {
|
||||
super.onLoadCleared(placeholder);
|
||||
setColors(getDefaultFooterColor(), holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
setColors(color, holder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String getSongTitle(Song song) {
|
||||
return song.title;
|
||||
}
|
||||
|
||||
private String getSongText(Song song) {
|
||||
return song.artistName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataSet.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Song getIdentifier(int position) {
|
||||
return dataSet.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName(Song song) {
|
||||
return song.title;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMultipleItemAction(@NonNull MenuItem menuItem,
|
||||
@NonNull ArrayList<Song> selection) {
|
||||
SongsMenuHelper.handleMenuClick(activity, selection, menuItem.getItemId());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getSectionName(int position) {
|
||||
if (!showSectionName) {
|
||||
return "";
|
||||
}
|
||||
@Nullable String sectionName = null;
|
||||
switch (PreferenceUtil.getInstance(activity).getSongSortOrder()) {
|
||||
case SortOrder.SongSortOrder.SONG_A_Z:
|
||||
case SortOrder.SongSortOrder.SONG_Z_A:
|
||||
sectionName = dataSet.get(position).title;
|
||||
break;
|
||||
case SortOrder.SongSortOrder.SONG_ALBUM:
|
||||
sectionName = dataSet.get(position).albumName;
|
||||
break;
|
||||
case SortOrder.SongSortOrder.SONG_ARTIST:
|
||||
sectionName = dataSet.get(position).artistName;
|
||||
break;
|
||||
case SortOrder.SongSortOrder.SONG_YEAR:
|
||||
return MusicUtil.getYearString(dataSet.get(position).year);
|
||||
}
|
||||
|
||||
return MusicUtil.getSectionName(sectionName);
|
||||
}
|
||||
|
||||
public class ViewHolder extends MediaEntryViewHolder {
|
||||
|
||||
int DEFAULT_MENU_RES = SongMenuHelper.MENU_RES;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
setImageTransitionName(activity.getString(R.string.transition_album_art));
|
||||
|
||||
/*if (mItemView != null) {
|
||||
mItemView.setOnMenuItemClickListener(new ListItemView.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public void onActionMenuItemSelected(MenuItem item) {
|
||||
SongMenuHelper.handleMenuClick(activity, dataSet.get(getAdapterPosition()), item.getItemId());
|
||||
}
|
||||
});
|
||||
}*/
|
||||
|
||||
if (menu == null) {
|
||||
return;
|
||||
}
|
||||
menu.setOnClickListener(new SongMenuHelper.OnClickSongMenu(activity) {
|
||||
@Override
|
||||
public Song getSong() {
|
||||
return ViewHolder.this.getSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMenuRes() {
|
||||
return getSongMenuRes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
return onSongMenuItemClick(item) || super.onMenuItemClick(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected Song getSong() {
|
||||
return dataSet.get(getAdapterPosition());
|
||||
}
|
||||
|
||||
protected int getSongMenuRes() {
|
||||
return DEFAULT_MENU_RES;
|
||||
}
|
||||
|
||||
protected boolean onSongMenuItemClick(MenuItem item) {
|
||||
if (image != null && image.getVisibility() == View.VISIBLE) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_go_to_album:
|
||||
Pair[] albumPairs = new Pair[]{
|
||||
Pair.create(imageContainer,
|
||||
activity.getResources().getString(R.string.transition_album_art))
|
||||
};
|
||||
NavigationUtil.goToAlbum(activity, getSong().albumId, albumPairs);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (isInQuickSelectMode()) {
|
||||
toggleChecked(getAdapterPosition());
|
||||
} else {
|
||||
MusicPlayerRemote.openQueue(dataSet, getAdapterPosition(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
return toggleChecked(getAdapterPosition());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
package code.name.monkey.retromusic.ui.fragments;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMusicServiceFragment;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
|
||||
|
||||
public class MiniPlayerFragment extends AbsMusicServiceFragment implements
|
||||
MusicProgressViewUpdateHelper.Callback {
|
||||
|
||||
@BindView(R.id.mini_player_title)
|
||||
TextView miniPlayerTitle;
|
||||
@BindView(R.id.mini_player_play_pause_button)
|
||||
ImageView miniPlayerPlayPauseButton;
|
||||
@BindView(R.id.progress_bar)
|
||||
MaterialProgressBar progressBar;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable miniPlayerPlayPauseDrawable;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View layout = inflater.inflate(R.layout.fragment_mini_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, layout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
view.setBackgroundColor(ThemeStore.primaryColor(getContext()));
|
||||
view.setOnTouchListener(new FlingPlayBackController(getActivity()));
|
||||
setUpMiniPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"ConstantConditions"})
|
||||
private void setUpMiniPlayer() {
|
||||
setUpPlayPauseButton();
|
||||
progressBar.setProgressTintList(ColorStateList.valueOf(ThemeStore.accentColor(getActivity())));
|
||||
}
|
||||
|
||||
private void setUpPlayPauseButton() {
|
||||
//noinspection ConstantConditions
|
||||
miniPlayerPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
miniPlayerPlayPauseButton.setImageDrawable(miniPlayerPlayPauseDrawable);
|
||||
miniPlayerPlayPauseButton.setColorFilter(ATHUtil.resolveColor(getActivity(),
|
||||
R.attr.iconColor,
|
||||
ThemeStore.textColorSecondary(getActivity())), PorterDuff.Mode.SRC_IN);
|
||||
miniPlayerPlayPauseButton.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
}
|
||||
|
||||
private void updateSongTitle() {
|
||||
miniPlayerTitle.setText(MusicPlayerRemote.getCurrentSong().title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateSongTitle();
|
||||
updatePlayPauseDrawableState(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateSongTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressBar.setMax(total);
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressBar, "progress", progress);
|
||||
animator.setDuration(1000);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
animator.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
miniPlayerPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
miniPlayerPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColor(int playerFragmentColor) {
|
||||
//noinspection ConstantConditions
|
||||
getView().setBackgroundColor(playerFragmentColor);
|
||||
}
|
||||
|
||||
public static class FlingPlayBackController implements View.OnTouchListener {
|
||||
|
||||
GestureDetector flingPlayBackController;
|
||||
|
||||
public FlingPlayBackController(Context context) {
|
||||
flingPlayBackController = new GestureDetector(context,
|
||||
new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
|
||||
float velocityY) {
|
||||
if (Math.abs(velocityX) > Math.abs(velocityY)) {
|
||||
if (velocityX < 0) {
|
||||
MusicPlayerRemote.playNextSong();
|
||||
return true;
|
||||
} else if (velocityX > 0) {
|
||||
MusicPlayerRemote.playPreviousSong();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
return flingPlayBackController.onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package code.name.monkey.retromusic.ui.fragments;
|
||||
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.StringRes;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
|
||||
public enum NowPlayingScreen {
|
||||
NORMAL(R.string.normal, R.drawable.np_normal, 0),
|
||||
FLAT(R.string.flat, R.drawable.np_flat, 1),
|
||||
FULL(R.string.full, R.drawable.np_full, 2),
|
||||
PLAIN(R.string.plain, R.drawable.np_plain, 3),
|
||||
BLUR(R.string.blur, R.drawable.np_blur, 4),
|
||||
COLOR(R.string.color, R.drawable.np_color, 5),
|
||||
CARD(R.string.card, R.drawable.np_card, 6),
|
||||
TINY(R.string.tiny, R.drawable.np_tiny, 7),
|
||||
SIMPLE(R.string.simple, R.drawable.np_simple, 8),
|
||||
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
|
||||
ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
|
||||
MATERIAL(R.string.material, R.drawable.np_normal, 11);
|
||||
|
||||
@StringRes
|
||||
public final int titleRes;
|
||||
@DrawableRes
|
||||
public final int drawableResId;
|
||||
public final int id;
|
||||
|
||||
NowPlayingScreen(@StringRes int titleRes, @DrawableRes int drawableResId, int id) {
|
||||
this.titleRes = titleRes;
|
||||
this.drawableResId = drawableResId;
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
package code.name.monkey.retromusic.ui.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
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 butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.PlayingQueueAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMusicServiceFragment;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
|
||||
|
||||
public class PlayingQueueFragment extends AbsMusicServiceFragment {
|
||||
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView mRecyclerView;
|
||||
Unbinder unbinder;
|
||||
private RecyclerView.Adapter mWrappedAdapter;
|
||||
private RecyclerViewDragDropManager mRecyclerViewDragDropManager;
|
||||
private PlayingQueueAdapter mPlayingQueueAdapter;
|
||||
private LinearLayoutManager mLayoutManager;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_main_activity_recycler_view, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
mRecyclerViewDragDropManager = new RecyclerViewDragDropManager();
|
||||
final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
|
||||
|
||||
mPlayingQueueAdapter = new PlayingQueueAdapter(
|
||||
(AppCompatActivity) getActivity(),
|
||||
MusicPlayerRemote.getPlayingQueue(),
|
||||
MusicPlayerRemote.getPosition(),
|
||||
R.layout.item_list,
|
||||
false,
|
||||
null);
|
||||
mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(mPlayingQueueAdapter);
|
||||
|
||||
mLayoutManager = new LinearLayoutManager(getContext());
|
||||
|
||||
mRecyclerView.setLayoutManager(mLayoutManager);
|
||||
mRecyclerView.setAdapter(mWrappedAdapter);
|
||||
mRecyclerView.setItemAnimator(animator);
|
||||
mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView);
|
||||
mLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void updateCurrentSong() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
//updateCurrentSong();
|
||||
//updateIsFavorite();
|
||||
updateQueuePosition();
|
||||
//updateLyrics();
|
||||
}
|
||||
|
||||
private void updateQueuePosition() {
|
||||
mPlayingQueueAdapter.setCurrent(MusicPlayerRemote.getPosition());
|
||||
// if (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
resetToCurrentPosition();
|
||||
//}
|
||||
}
|
||||
|
||||
private void updateQueue() {
|
||||
mPlayingQueueAdapter
|
||||
.swapDataSet(MusicPlayerRemote.getPlayingQueue(), MusicPlayerRemote.getPosition());
|
||||
resetToCurrentPosition();
|
||||
}
|
||||
|
||||
private void resetToCurrentPosition() {
|
||||
mRecyclerView.stopScroll();
|
||||
mLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (mRecyclerViewDragDropManager != null) {
|
||||
mRecyclerViewDragDropManager.cancelDrag();
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
if (mRecyclerViewDragDropManager != null) {
|
||||
mRecyclerViewDragDropManager.release();
|
||||
mRecyclerViewDragDropManager = null;
|
||||
}
|
||||
|
||||
if (mRecyclerView != null) {
|
||||
mRecyclerView.setItemAnimator(null);
|
||||
mRecyclerView.setAdapter(null);
|
||||
mRecyclerView = null;
|
||||
}
|
||||
|
||||
if (mWrappedAdapter != null) {
|
||||
WrapperAdapterUtils.releaseAll(mWrappedAdapter);
|
||||
mWrappedAdapter = null;
|
||||
}
|
||||
mPlayingQueueAdapter = null;
|
||||
mLayoutManager = null;
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
}
|
158
app/src/main/java/code/name/monkey/retromusic/ui/fragments/VolumeFragment.java
Executable file
158
app/src/main/java/code/name/monkey/retromusic/ui/fragments/VolumeFragment.java
Executable file
|
@ -0,0 +1,158 @@
|
|||
package code.name.monkey.retromusic.ui.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.volume.AudioVolumeObserver;
|
||||
import code.name.monkey.retromusic.volume.OnAudioVolumeChangedListener;
|
||||
|
||||
public class VolumeFragment extends Fragment implements SeekBar.OnSeekBarChangeListener,
|
||||
OnAudioVolumeChangedListener {
|
||||
|
||||
@BindView(R.id.volume_seekbar)
|
||||
SeekBar volumeSeekbar;
|
||||
@BindView(R.id.volume_down)
|
||||
ImageView volumeDown;
|
||||
@BindView(R.id.container)
|
||||
ViewGroup viewGroup;
|
||||
@BindView(R.id.volume_up)
|
||||
ImageView volumeUp;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private AudioVolumeObserver mAudioVolumeObserver;
|
||||
|
||||
public static VolumeFragment newInstance() {
|
||||
return new VolumeFragment();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_volume, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
//noinspection ConstantConditions
|
||||
setColor(ThemeStore.textColorSecondary(getContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (mAudioVolumeObserver == null) {
|
||||
//noinspection ConstantConditions
|
||||
mAudioVolumeObserver = new AudioVolumeObserver(getActivity());
|
||||
}
|
||||
mAudioVolumeObserver.register(AudioManager.STREAM_MUSIC, this);
|
||||
|
||||
AudioManager audioManager = getAudioManager();
|
||||
if (audioManager != null) {
|
||||
volumeSeekbar.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
|
||||
volumeSeekbar.setProgress(audioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
|
||||
}
|
||||
volumeSeekbar.setOnSeekBarChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioVolumeChanged(int currentVolume, int maxVolume) {
|
||||
if (volumeSeekbar == null) {
|
||||
return;
|
||||
}
|
||||
volumeSeekbar.setMax(maxVolume);
|
||||
volumeSeekbar.setProgress(currentVolume);
|
||||
volumeDown.setImageResource(currentVolume == 0 ? R.drawable.ic_volume_off_white_24dp : R.drawable.ic_volume_down_white_24dp);
|
||||
}
|
||||
|
||||
private AudioManager getAudioManager() {
|
||||
//noinspection ConstantConditions
|
||||
return (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
if (mAudioVolumeObserver != null) {
|
||||
mAudioVolumeObserver.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
|
||||
AudioManager audioManager = getAudioManager();
|
||||
if (audioManager != null) {
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, i, 0);
|
||||
}
|
||||
volumeDown.setImageResource(
|
||||
i == 0 ? R.drawable.ic_volume_off_white_24dp : R.drawable.ic_volume_down_white_24dp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@OnClick({R.id.volume_down, R.id.volume_up})
|
||||
public void onViewClicked(View view) {
|
||||
AudioManager audioManager = getAudioManager();
|
||||
switch (view.getId()) {
|
||||
case R.id.volume_down:
|
||||
if (audioManager != null) {
|
||||
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, 0);
|
||||
}
|
||||
break;
|
||||
case R.id.volume_up:
|
||||
if (audioManager != null) {
|
||||
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
volumeSeekbar.setProgressTintList(ColorStateList.valueOf(color));
|
||||
}
|
||||
|
||||
public void tintWhiteColor() {
|
||||
setProgressBarColor(Color.WHITE);
|
||||
}
|
||||
|
||||
public void setProgressBarColor(int newColor) {
|
||||
TintHelper.setTintAuto(volumeSeekbar, newColor, false);
|
||||
volumeDown.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
|
||||
volumeUp.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
public void setTintable(int color) {
|
||||
setProgressBarColor(color);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
|
||||
import code.name.monkey.retromusic.ui.fragments.mainactivity.LibraryFragment;
|
||||
|
||||
public class AbsLibraryPagerFragment extends AbsMusicServiceFragment {
|
||||
|
||||
|
||||
public LibraryFragment getLibraryFragment() {
|
||||
return (LibraryFragment) getParentFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
|
||||
public abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment<A extends RecyclerView.Adapter, LM extends RecyclerView.LayoutManager> extends
|
||||
AbsLibraryPagerRecyclerViewFragment<A, LM> {
|
||||
|
||||
private int gridSize;
|
||||
private String sortOrder;
|
||||
|
||||
private boolean usePaletteInitialized;
|
||||
private boolean usePalette;
|
||||
private int currentLayoutRes;
|
||||
|
||||
public final int getGridSize() {
|
||||
if (gridSize == 0) {
|
||||
if (isLandscape()) {
|
||||
gridSize = loadGridSizeLand();
|
||||
} else {
|
||||
gridSize = loadGridSize();
|
||||
}
|
||||
}
|
||||
return gridSize;
|
||||
}
|
||||
|
||||
protected abstract void setGridSize(int gridSize);
|
||||
|
||||
public final String getSortOrder() {
|
||||
if (sortOrder == null) {
|
||||
sortOrder = loadSortOrder();
|
||||
}
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
protected abstract void setSortOrder(String sortOrder);
|
||||
|
||||
public void setAndSaveSortOrder(final String sortOrder) {
|
||||
this.sortOrder = sortOrder;
|
||||
saveSortOrder(sortOrder);
|
||||
setSortOrder(sortOrder);
|
||||
}
|
||||
|
||||
public int getMaxGridSize() {
|
||||
if (isLandscape()) {
|
||||
return getResources().getInteger(R.integer.max_columns_land);
|
||||
} else {
|
||||
return getResources().getInteger(R.integer.max_columns);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether the palette should be used at all or not
|
||||
*/
|
||||
public final boolean usePalette() {
|
||||
if (!usePaletteInitialized) {
|
||||
usePalette = loadUsePalette();
|
||||
usePaletteInitialized = true;
|
||||
}
|
||||
return usePalette;
|
||||
}
|
||||
|
||||
public void setAndSaveGridSize(final int gridSize) {
|
||||
int oldLayoutRes = getItemLayoutRes();
|
||||
this.gridSize = gridSize;
|
||||
if (isLandscape()) {
|
||||
saveGridSizeLand(gridSize);
|
||||
} else {
|
||||
saveGridSize(gridSize);
|
||||
}
|
||||
// only recreate the adapter and layout manager if the layout currentLayoutRes has changed
|
||||
if (oldLayoutRes != getItemLayoutRes()) {
|
||||
invalidateLayoutManager();
|
||||
invalidateAdapter();
|
||||
} else {
|
||||
setGridSize(gridSize);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAndSaveUsePalette(final boolean usePalette) {
|
||||
this.usePalette = usePalette;
|
||||
saveUsePalette(usePalette);
|
||||
setUsePalette(usePalette);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether the palette option should be available for the current item layout or not
|
||||
*/
|
||||
public boolean canUsePalette() {
|
||||
return getItemLayoutRes() == R.layout.item_color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to customize which item layout currentLayoutRes should be used. You might also want to
|
||||
* override {@link #canUsePalette()} then.
|
||||
*
|
||||
* @see #getGridSize()
|
||||
*/
|
||||
@LayoutRes
|
||||
protected int getItemLayoutRes() {
|
||||
if (getGridSize() > getMaxGridSizeForList()) {
|
||||
return R.layout.item_grid;
|
||||
}
|
||||
return R.layout.item_list;
|
||||
}
|
||||
|
||||
protected final void notifyLayoutResChanged(@LayoutRes int res) {
|
||||
this.currentLayoutRes = res;
|
||||
RecyclerView recyclerView = getRecyclerView();
|
||||
if (recyclerView != null) {
|
||||
applyRecyclerViewPaddingForLayoutRes(recyclerView, currentLayoutRes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
applyRecyclerViewPaddingForLayoutRes(getRecyclerView(), currentLayoutRes);
|
||||
}
|
||||
|
||||
protected void applyRecyclerViewPaddingForLayoutRes(@NonNull RecyclerView recyclerView,
|
||||
@LayoutRes int res) {
|
||||
int padding;
|
||||
if (res == R.layout.item_grid) {
|
||||
padding = (int) (getResources().getDisplayMetrics().density * 2);
|
||||
} else {
|
||||
padding = 0;
|
||||
}
|
||||
recyclerView.setPadding(padding, padding, padding, padding);
|
||||
}
|
||||
|
||||
protected abstract String loadSortOrder();
|
||||
|
||||
protected abstract void saveSortOrder(String sortOrder);
|
||||
|
||||
protected abstract int loadGridSize();
|
||||
|
||||
protected abstract void saveGridSize(int gridColumns);
|
||||
|
||||
protected abstract int loadGridSizeLand();
|
||||
|
||||
protected abstract void saveGridSizeLand(int gridColumns);
|
||||
|
||||
protected abstract void saveUsePalette(boolean usePalette);
|
||||
|
||||
protected abstract boolean loadUsePalette();
|
||||
|
||||
protected abstract void setUsePalette(boolean usePalette);
|
||||
|
||||
protected int getMaxGridSizeForList() {
|
||||
if (isLandscape()) {
|
||||
return getActivity().getResources().getInteger(R.integer.default_list_columns_land);
|
||||
}
|
||||
return getActivity().getResources().getInteger(R.integer.default_list_columns);
|
||||
}
|
||||
|
||||
protected final boolean isLandscape() {
|
||||
return RetroUtil.isLandscape(getResources());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.AppBarLayout.OnOffsetChangedListener;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
||||
|
||||
public abstract class AbsLibraryPagerRecyclerViewFragment<A extends RecyclerView.Adapter, LM extends RecyclerView.LayoutManager> extends
|
||||
AbsLibraryPagerFragment implements OnOffsetChangedListener {
|
||||
|
||||
public static final String TAG = AbsLibraryPagerRecyclerViewFragment.class.getSimpleName();
|
||||
@BindView(R.id.container)
|
||||
ViewGroup container;
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
@BindView(android.R.id.empty)
|
||||
TextView empty;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private A adapter;
|
||||
private LM layoutManager;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(getLayoutRes(), container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
getLibraryFragment().addOnAppBarOffsetChangedListener(this);
|
||||
initLayoutManager();
|
||||
initAdapter();
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
if (recyclerView instanceof FastScrollRecyclerView) {
|
||||
//noinspection ConstantConditions
|
||||
ViewUtil.setUpFastScrollRecyclerViewColor(getActivity(),
|
||||
((FastScrollRecyclerView) recyclerView), ThemeStore.accentColor(getActivity()));
|
||||
}
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
super.onQueueChanged();
|
||||
checkForPadding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
checkForPadding();
|
||||
}
|
||||
|
||||
private void checkForPadding() {
|
||||
int height = (MusicPlayerRemote.getPlayingQueue().isEmpty() ? getResources().getDimensionPixelSize(R.dimen.mini_player_height) : 0);
|
||||
recyclerView.setPadding(0, 0, 0, height);
|
||||
}
|
||||
|
||||
protected void invalidateLayoutManager() {
|
||||
initLayoutManager();
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
}
|
||||
|
||||
protected void invalidateAdapter() {
|
||||
initAdapter();
|
||||
checkIsEmpty();
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private void initAdapter() {
|
||||
adapter = createAdapter();
|
||||
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
super.onChanged();
|
||||
checkIsEmpty();
|
||||
checkForPadding();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initLayoutManager() {
|
||||
layoutManager = createLayoutManager();
|
||||
}
|
||||
|
||||
protected A getAdapter() {
|
||||
return adapter;
|
||||
}
|
||||
|
||||
protected LM getLayoutManager() {
|
||||
return layoutManager;
|
||||
}
|
||||
|
||||
protected RecyclerView getRecyclerView() {
|
||||
return recyclerView;
|
||||
}
|
||||
|
||||
public ViewGroup getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
|
||||
container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
|
||||
container.getPaddingRight(), getLibraryFragment().getTotalAppBarScrollingRange() + i);
|
||||
}
|
||||
|
||||
private void checkIsEmpty() {
|
||||
empty.setText(getEmptyMessage());
|
||||
empty.setVisibility(adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@StringRes
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.empty;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
protected int getLayoutRes() {
|
||||
return R.layout.fragment_main_activity_recycler_view;
|
||||
}
|
||||
|
||||
protected abstract LM createLayoutManager();
|
||||
|
||||
@NonNull
|
||||
protected abstract A createAdapter();
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
getLibraryFragment().removeOnAppBarOffsetChangedListener(this);
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.base;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.ui.activities.MainActivity;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
|
||||
public abstract class AbsMainActivityFragment extends AbsMusicServiceFragment {
|
||||
|
||||
public MainActivity getMainActivity() {
|
||||
return (MainActivity) getActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
getMainActivity().setNavigationbarColorAuto();
|
||||
getMainActivity().setLightNavigationBar(true);
|
||||
getMainActivity().setTaskDescriptionColorAuto();
|
||||
getMainActivity().hideStatusBar();
|
||||
}
|
||||
|
||||
|
||||
// WORKAROUND
|
||||
public void setStatusbarColor(View view, int color) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
final View statusBar = view.findViewById(R.id.status_bar);
|
||||
if (statusBar != null) {
|
||||
RetroUtil.statusBarHeight(statusBar);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
statusBar.setBackgroundColor(ColorUtil.darkenColor(color));
|
||||
getMainActivity().setLightStatusbarAuto(color);
|
||||
} else {
|
||||
statusBar.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setStatusbarColorAuto(View view) {
|
||||
// we don't want to use statusbar color because we are doing the color darkening on our own to support KitKat
|
||||
setStatusbarColor(view, ThemeStore.primaryColor(getContext()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.View;
|
||||
|
||||
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener;
|
||||
|
||||
import code.name.monkey.retromusic.ui.activities.base.AbsMusicServiceActivity;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 18/08/17.
|
||||
*/
|
||||
|
||||
public class AbsMusicServiceFragment extends Fragment implements MusicServiceEventListener {
|
||||
|
||||
private AbsMusicServiceActivity activity;
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
try {
|
||||
activity = (AbsMusicServiceActivity) context;
|
||||
} catch (ClassCastException e) {
|
||||
throw new RuntimeException(context.getClass().getSimpleName() + " must be an instance of " + AbsMusicServiceActivity.class.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
activity = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
activity.addMusicServiceEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
activity.removeMusicServiceEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.base;
|
||||
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 24/09/17.
|
||||
*/
|
||||
|
||||
public abstract class AbsPlayerControlsFragment extends AbsMusicServiceFragment
|
||||
implements MusicProgressViewUpdateHelper.Callback {
|
||||
|
||||
protected abstract void show();
|
||||
|
||||
protected abstract void hide();
|
||||
|
||||
protected abstract void updateShuffleState();
|
||||
|
||||
protected abstract void updateRepeatState();
|
||||
|
||||
protected abstract void setUpProgressSlider();
|
||||
|
||||
public abstract void setDark(int color);
|
||||
}
|
|
@ -0,0 +1,282 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.base;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog;
|
||||
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog;
|
||||
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog;
|
||||
import code.name.monkey.retromusic.dialogs.SleepTimerDialog;
|
||||
import code.name.monkey.retromusic.dialogs.SongDetailDialog;
|
||||
import code.name.monkey.retromusic.dialogs.SongShareDialog;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.interfaces.PaletteColorHolder;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.activities.tageditor.AbsTagEditorActivity;
|
||||
import code.name.monkey.retromusic.ui.activities.tageditor.SongTagEditorActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
public abstract class AbsPlayerFragment extends AbsMusicServiceFragment implements
|
||||
Toolbar.OnMenuItemClickListener, PaletteColorHolder {
|
||||
|
||||
public static final String TAG = AbsPlayerFragment.class.getSimpleName();
|
||||
private boolean isToolbarShown = true;
|
||||
private Callbacks callbacks;
|
||||
private AsyncTask updateIsFavoriteTask;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
try {
|
||||
callbacks = (Callbacks) context;
|
||||
} catch (ClassCastException e) {
|
||||
throw new RuntimeException(
|
||||
context.getClass().getSimpleName() + " must implement " + Callbacks.class
|
||||
.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
callbacks = null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
final Song song = MusicPlayerRemote.getCurrentSong();
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_toggle_favorite:
|
||||
toggleFavorite(song);
|
||||
return true;
|
||||
case R.id.action_share:
|
||||
if (getFragmentManager() != null) {
|
||||
SongShareDialog.create(song).show(getFragmentManager(), "SHARE_SONG");
|
||||
}
|
||||
return true;
|
||||
case R.id.action_delete_from_device:
|
||||
DeleteSongsDialog.create(song)
|
||||
.show(getActivity().getSupportFragmentManager(), "DELETE_SONGS");
|
||||
return true;
|
||||
case R.id.action_add_to_playlist:
|
||||
if (getFragmentManager() != null) {
|
||||
AddToPlaylistDialog.create(song).show(getFragmentManager(), "ADD_PLAYLIST");
|
||||
}
|
||||
return true;
|
||||
case R.id.action_clear_playing_queue:
|
||||
MusicPlayerRemote.clearQueue();
|
||||
return true;
|
||||
case R.id.action_save_playing_queue:
|
||||
CreatePlaylistDialog.create(MusicPlayerRemote.getPlayingQueue())
|
||||
.show(getActivity().getSupportFragmentManager(), "ADD_TO_PLAYLIST");
|
||||
return true;
|
||||
case R.id.action_tag_editor:
|
||||
Intent intent = new Intent(getActivity(), SongTagEditorActivity.class);
|
||||
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, song.id);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.action_details:
|
||||
if (getFragmentManager() != null) {
|
||||
SongDetailDialog.create(song).show(getFragmentManager(), "SONG_DETAIL");
|
||||
}
|
||||
return true;
|
||||
case R.id.action_go_to_album:
|
||||
NavigationUtil.goToAlbum(getActivity(), song.albumId);
|
||||
return true;
|
||||
case R.id.action_go_to_artist:
|
||||
NavigationUtil.goToArtist(getActivity(), song.artistId);
|
||||
return true;
|
||||
case R.id.now_playing:
|
||||
NavigationUtil.goToPlayingQueue(getActivity());
|
||||
return true;
|
||||
case R.id.action_show_lyrics:
|
||||
NavigationUtil.goToLyrics(getActivity());
|
||||
return true;
|
||||
case R.id.action_equalizer:
|
||||
NavigationUtil.openEqualizer(getActivity());
|
||||
return true;
|
||||
case R.id.action_sleep_timer:
|
||||
new SleepTimerDialog().show(getFragmentManager(), TAG);
|
||||
return true;
|
||||
case R.id.action_set_as_ringtone:
|
||||
MusicUtil.setRingtone(getActivity(), song.id);
|
||||
return true;
|
||||
case R.id.action_go_to_genre:
|
||||
/*MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
||||
Uri trackUri = ContentUris
|
||||
.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, song.id);
|
||||
retriever.setDataSource(getActivity(), trackUri);
|
||||
String genre = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE);
|
||||
if (genre == null) {
|
||||
genre = "Not Specified";
|
||||
}*/
|
||||
Toast.makeText(getContext(), "Soon", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void toggleFavorite(Song song) {
|
||||
MusicUtil.toggleFavorite(getActivity(), song);
|
||||
}
|
||||
|
||||
protected boolean isToolbarShown() {
|
||||
return isToolbarShown;
|
||||
}
|
||||
|
||||
protected void setToolbarShown(boolean toolbarShown) {
|
||||
isToolbarShown = toolbarShown;
|
||||
}
|
||||
|
||||
protected void showToolbar(@Nullable final View toolbar) {
|
||||
if (toolbar == null) {
|
||||
return;
|
||||
}
|
||||
setToolbarShown(true);
|
||||
toolbar.setVisibility(View.VISIBLE);
|
||||
toolbar.animate().alpha(1f).setDuration(PlayerAlbumCoverFragment.VISIBILITY_ANIM_DURATION);
|
||||
}
|
||||
|
||||
protected void hideToolbar(@Nullable final View toolbar) {
|
||||
if (toolbar == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setToolbarShown(false);
|
||||
|
||||
toolbar.animate().alpha(0f).setDuration(PlayerAlbumCoverFragment.VISIBILITY_ANIM_DURATION)
|
||||
.withEndAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
toolbar.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void toggleToolbar(@Nullable final View toolbar) {
|
||||
if (isToolbarShown()) {
|
||||
hideToolbar(toolbar);
|
||||
} else {
|
||||
showToolbar(toolbar);
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkToggleToolbar(@Nullable final View toolbar) {
|
||||
if (toolbar != null && !isToolbarShown() && toolbar.getVisibility() != View.GONE) {
|
||||
hideToolbar(toolbar);
|
||||
} else if (toolbar != null && isToolbarShown() && toolbar.getVisibility() != View.VISIBLE) {
|
||||
showToolbar(toolbar);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void onShow();
|
||||
|
||||
public abstract void onHide();
|
||||
|
||||
public abstract boolean onBackPressed();
|
||||
|
||||
public abstract Toolbar getToolbar();
|
||||
|
||||
public abstract int toolbarIconColor();
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
//updateLyrics();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
//updateLyrics();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
|
||||
if (updateIsFavoriteTask != null && !updateIsFavoriteTask.isCancelled()) {
|
||||
updateIsFavoriteTask.cancel(true);
|
||||
}
|
||||
super.onDestroyView();
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public void updateIsFavorite() {
|
||||
if (updateIsFavoriteTask != null) {
|
||||
updateIsFavoriteTask.cancel(false);
|
||||
}
|
||||
updateIsFavoriteTask = new AsyncTask<Song, Void, Boolean>() {
|
||||
@Override
|
||||
protected Boolean doInBackground(Song... params) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
return MusicUtil.isFavorite(getActivity(), params[0]);
|
||||
} else {
|
||||
cancel(false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean isFavorite) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
int res = isFavorite ? R.drawable.ic_favorite_white_24dp
|
||||
: R.drawable.ic_favorite_border_white_24dp;
|
||||
Drawable drawable = RetroUtil.getTintedVectorDrawable(activity, res, toolbarIconColor());
|
||||
getToolbar().getMenu().findItem(R.id.action_toggle_favorite)
|
||||
.setIcon(drawable)
|
||||
.setTitle(isFavorite ? getString(R.string.action_remove_from_favorites)
|
||||
: getString(R.string.action_add_to_favorites));
|
||||
}
|
||||
}
|
||||
}.execute(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
public Callbacks getCallbacks() {
|
||||
return callbacks;
|
||||
}
|
||||
|
||||
protected void toggleStatusBar(ViewGroup viewGroup) {
|
||||
if (!PreferenceUtil.getInstance(getContext()).getFullScreenMode()) {
|
||||
RetroUtil.statusBarHeight(viewGroup);
|
||||
}
|
||||
}
|
||||
|
||||
protected void toggleStatusBar(View viewGroup) {
|
||||
if (!PreferenceUtil.getInstance(getContext()).getFullScreenMode()) {
|
||||
RetroUtil.statusBarHeight(viewGroup);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
view.setBackgroundColor(ThemeStore.primaryColor(getActivity()));
|
||||
}
|
||||
|
||||
public interface Callbacks {
|
||||
|
||||
void onPaletteColorChanged();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,275 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.intro;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore.Images.Media;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog.Builder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.util.Compressor;
|
||||
import code.name.monkey.retromusic.util.ImageUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.CircularImageView;
|
||||
import code.name.monkey.retromusic.views.IconImageView;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
import static code.name.monkey.retromusic.Constants.USER_BANNER;
|
||||
import static code.name.monkey.retromusic.Constants.USER_PROFILE;
|
||||
|
||||
public class NameFragment extends Fragment {
|
||||
|
||||
private static final int PICK_IMAGE_REQUEST = 9002;
|
||||
private static final int PICK_BANNER_REQUEST = 9003;
|
||||
private static final int PROFILE_ICON_SIZE = 400;
|
||||
@BindView(R.id.name)
|
||||
EditText name;
|
||||
@BindView(R.id.user_image)
|
||||
CircularImageView userImage;
|
||||
@BindView(R.id.image)
|
||||
ImageView image;
|
||||
@BindView(R.id.banner_select)
|
||||
IconImageView imageView;
|
||||
private Unbinder unbinder;
|
||||
private CompositeDisposable disposable;
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = LayoutInflater.from(getActivity())
|
||||
.inflate(R.layout.fragment_name, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
name.setText(PreferenceUtil.getInstance(getActivity()).getUserName());
|
||||
if (!PreferenceUtil.getInstance(getActivity()).getProfileImage().isEmpty()) {
|
||||
loadImageFromStorage(PreferenceUtil.getInstance(getActivity()).getProfileImage());
|
||||
}
|
||||
if (!PreferenceUtil.getInstance(getActivity()).getBannerImage().isEmpty()) {
|
||||
loadBannerFromStorage(PreferenceUtil.getInstance(getActivity()).getBannerImage());
|
||||
imageView.setImageResource(R.drawable.ic_close_white_24dp);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
disposable = new CompositeDisposable();
|
||||
}
|
||||
|
||||
@OnClick({R.id.next, R.id.banner_select})
|
||||
void next(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.banner_select:
|
||||
showBannerOptions();
|
||||
break;
|
||||
case R.id.next:
|
||||
String nameString = name.getText().toString().trim();
|
||||
if (TextUtils.isEmpty(nameString)) {
|
||||
Toast.makeText(getActivity(), "Umm name is empty", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
//noinspection ConstantConditions
|
||||
PreferenceUtil.getInstance(getActivity()).setUserName(nameString);
|
||||
getActivity().setResult(RESULT_OK);
|
||||
//((UserInfoActivity) getActivity()).setFragment(new ChooseThemeFragment(), true);
|
||||
getActivity().finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void showBannerOptions() {
|
||||
//noinspection ConstantConditions
|
||||
new Builder(getContext())
|
||||
.title(R.string.select_banner_photo)
|
||||
.items(Arrays.asList(getString(R.string.new_banner_photo),
|
||||
getString(R.string.remove_banner_photo)))
|
||||
.itemsCallback((dialog, itemView, position, text) -> {
|
||||
switch (position) {
|
||||
case 0:
|
||||
selectBannerImage();
|
||||
break;
|
||||
case 1:
|
||||
PreferenceUtil.getInstance(getContext()).setBannerImagePath("");
|
||||
break;
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
private void selectBannerImage() {
|
||||
//noinspection ConstantConditions
|
||||
if (PreferenceUtil.getInstance(getActivity()).getBannerImage().isEmpty()) {
|
||||
Intent pickImageIntent = new Intent(Intent.ACTION_PICK,
|
||||
Media.EXTERNAL_CONTENT_URI);
|
||||
pickImageIntent.setType("image/*");
|
||||
pickImageIntent.putExtra("crop", "true");
|
||||
pickImageIntent.putExtra("outputX", 1290);
|
||||
pickImageIntent.putExtra("outputY", 720);
|
||||
pickImageIntent.putExtra("aspectX", 16);
|
||||
pickImageIntent.putExtra("aspectY", 9);
|
||||
pickImageIntent.putExtra("scale", true);
|
||||
//intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
startActivityForResult(Intent.createChooser(pickImageIntent,
|
||||
"Select Picture"), PICK_BANNER_REQUEST);
|
||||
} else {
|
||||
PreferenceUtil.getInstance(getContext()).setBannerImagePath("");
|
||||
image.setImageResource(android.R.color.transparent);
|
||||
imageView.setImageResource(R.drawable.ic_edit_white_24dp);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.image)
|
||||
public void onViewClicked() {
|
||||
//noinspection ConstantConditions
|
||||
new Builder(getContext())
|
||||
.title("Set a profile photo")
|
||||
.items(Arrays.asList(getString(R.string.new_profile_photo),
|
||||
getString(R.string.remove_profile_photo)))
|
||||
.itemsCallback((dialog, itemView, position, text) -> {
|
||||
switch (position) {
|
||||
case 0:
|
||||
pickNewPhoto();
|
||||
break;
|
||||
case 1:
|
||||
PreferenceUtil.getInstance(getContext()).saveProfileImage("");
|
||||
break;
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
private void pickNewPhoto() {
|
||||
Intent pickImageIntent = new Intent(Intent.ACTION_PICK,
|
||||
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
|
||||
pickImageIntent.setType("image/*");
|
||||
pickImageIntent.putExtra("crop", "true");
|
||||
pickImageIntent.putExtra("outputX", 512);
|
||||
pickImageIntent.putExtra("outputY", 512);
|
||||
pickImageIntent.putExtra("aspectX", 1);
|
||||
pickImageIntent.putExtra("aspectY", 1);
|
||||
pickImageIntent.putExtra("scale", true);
|
||||
startActivityForResult(Intent.createChooser(pickImageIntent, "Select Picture"),
|
||||
PICK_IMAGE_REQUEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null &&
|
||||
data.getData() != null) {
|
||||
Uri uri = data.getData();
|
||||
try {
|
||||
Bitmap bitmap = ImageUtil.getResizedBitmap(Media.getBitmap(getActivity()
|
||||
.getContentResolver(), uri), PROFILE_ICON_SIZE);
|
||||
String profileImagePath = saveToInternalStorage(bitmap, USER_PROFILE);
|
||||
PreferenceUtil.getInstance(getActivity()).saveProfileImage(profileImagePath);
|
||||
loadImageFromStorage(profileImagePath);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (requestCode == PICK_BANNER_REQUEST && resultCode == RESULT_OK && data != null &&
|
||||
data.getData() != null) {
|
||||
Uri uri = data.getData();
|
||||
try {
|
||||
Bitmap bitmap = Media.getBitmap(getActivity().getContentResolver(), uri);
|
||||
String profileImagePath = saveToInternalStorage(bitmap, USER_BANNER);
|
||||
PreferenceUtil.getInstance(getActivity()).setBannerImagePath(profileImagePath);
|
||||
loadBannerFromStorage(profileImagePath);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadBannerFromStorage(String profileImagePath) {
|
||||
disposable.add(new Compressor(getActivity())
|
||||
.setQuality(100)
|
||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmapAsFlowable(new File(profileImagePath, USER_BANNER))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(bitmap -> {
|
||||
image.setImageBitmap(bitmap);
|
||||
}));
|
||||
}
|
||||
|
||||
private void loadImageFromStorage(String path) {
|
||||
disposable.add(new Compressor(getActivity())
|
||||
.setMaxHeight(300)
|
||||
.setMaxWidth(300)
|
||||
.setQuality(75)
|
||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmapAsFlowable(new File(path, USER_PROFILE))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(bitmap -> {
|
||||
userImage.setImageBitmap(bitmap);
|
||||
}));
|
||||
}
|
||||
|
||||
private String saveToInternalStorage(Bitmap bitmapImage, String userBanner) {
|
||||
ContextWrapper cw = new ContextWrapper(getActivity());
|
||||
// path to /data/data/yourapp/app_data/imageDir
|
||||
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
|
||||
// Create imageDir
|
||||
File mypath = new File(directory, userBanner);
|
||||
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(mypath);
|
||||
// Use the compress method on the BitMap object to write image to the OutputStream
|
||||
bitmapImage.compress(Bitmap.CompressFormat.WEBP, 100, fos);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (fos != null) {
|
||||
fos.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return directory.getAbsolutePath();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.mainactivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.mvp.contract.AlbumContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.AlbumPresenter;
|
||||
import code.name.monkey.retromusic.ui.adapter.album.AlbumAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
public class AlbumsFragment extends
|
||||
AbsLibraryPagerRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager> implements
|
||||
AlbumContract.AlbumView {
|
||||
|
||||
public static final String TAG = AlbumsFragment.class.getSimpleName();
|
||||
|
||||
private AlbumPresenter presenter;
|
||||
|
||||
public static AlbumsFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
AlbumsFragment fragment = new AlbumsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GridLayoutManager createLayoutManager() {
|
||||
return new GridLayoutManager(getActivity(), getGridSize());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected AlbumAdapter createAdapter() {
|
||||
int itemLayoutRes = getItemLayoutRes();
|
||||
notifyLayoutResChanged(itemLayoutRes);
|
||||
if (itemLayoutRes != R.layout.item_list) {
|
||||
itemLayoutRes = PreferenceUtil.getInstance(getContext()).getAlbumGridStyle(getContext());
|
||||
}
|
||||
ArrayList<Album> dataSet =
|
||||
getAdapter() == null ? new ArrayList<>() : getAdapter().getDataSet();
|
||||
return new AlbumAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes,
|
||||
loadUsePalette(), getLibraryFragment());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_albums;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUsePalette() {
|
||||
return PreferenceUtil.getInstance(getActivity()).albumColoredFooters();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUsePalette(boolean usePalette) {
|
||||
getAdapter().usePalette(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setGridSize(int gridSize) {
|
||||
getLayoutManager().setSpanCount(gridSize);
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSortOrder(String sortOrder) {
|
||||
presenter.loadAlbums();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String loadSortOrder() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getAlbumSortOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSortOrder(String sortOrder) {
|
||||
PreferenceUtil.getInstance(getActivity()).setAlbumSortOrder(sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadGridSize() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getAlbumGridSize(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSize(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setAlbumGridSize(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadGridSizeLand() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getAlbumGridSizeLand(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSizeLand(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setAlbumGridSizeLand(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveUsePalette(boolean usePalette) {
|
||||
PreferenceUtil.getInstance(getActivity()).setAlbumColoredFooters(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
presenter.loadAlbums();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
presenter = new AlbumPresenter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().getToolbar().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library
|
||||
: R.string.albums);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().getToolbar().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.albums);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
presenter.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
presenter.unsubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Album> albums) {
|
||||
getAdapter().swapDataSet(albums);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.mainactivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.mvp.contract.ArtistContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.ArtistPresenter;
|
||||
import code.name.monkey.retromusic.ui.adapter.artist.ArtistAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
public class ArtistsFragment extends
|
||||
AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager> implements
|
||||
ArtistContract.ArtistView {
|
||||
|
||||
public static final String TAG = ArtistsFragment.class.getSimpleName();
|
||||
private ArtistPresenter presenter;
|
||||
|
||||
public static ArtistsFragment newInstance() {
|
||||
|
||||
Bundle args = new Bundle();
|
||||
|
||||
ArtistsFragment fragment = new ArtistsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
presenter = new ArtistPresenter(this);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected GridLayoutManager createLayoutManager() {
|
||||
return new GridLayoutManager(getActivity(), getGridSize());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected ArtistAdapter createAdapter() {
|
||||
int itemLayoutRes = getItemLayoutRes();
|
||||
notifyLayoutResChanged(itemLayoutRes);
|
||||
if (itemLayoutRes != R.layout.item_list) {
|
||||
itemLayoutRes = PreferenceUtil.getInstance(getContext()).getArtistGridStyle(getContext());
|
||||
}
|
||||
ArrayList<Artist> dataSet =
|
||||
getAdapter() == null ? new ArrayList<>() : getAdapter().getDataSet();
|
||||
return new ArtistAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes,
|
||||
loadUsePalette(), getLibraryFragment());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_artists;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
presenter.loadArtists();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadGridSize() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getArtistGridSize(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSize(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistGridSize(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadGridSizeLand() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getArtistGridSizeLand(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSizeLand(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistGridSizeLand(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveUsePalette(boolean usePalette) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistColoredFooters(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUsePalette() {
|
||||
return PreferenceUtil.getInstance(getActivity()).artistColoredFooters();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUsePalette(boolean usePalette) {
|
||||
getAdapter().usePalette(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setGridSize(int gridSize) {
|
||||
getLayoutManager().setSpanCount(gridSize);
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String loadSortOrder() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getArtistSortOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSortOrder(String sortOrder) {
|
||||
PreferenceUtil.getInstance(getActivity()).setArtistSortOrder(sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSortOrder(String sortOrder) {
|
||||
presenter.loadArtists();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().getToolbar().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library
|
||||
: R.string.artists);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().getToolbar().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.artists);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
presenter.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
presenter.unsubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Artist> artists) {
|
||||
getAdapter().swapDataSet(artists);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.mainactivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
import code.name.monkey.retromusic.mvp.contract.GenreContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.GenrePresenter;
|
||||
import code.name.monkey.retromusic.ui.adapter.GenreAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GenreFragment extends
|
||||
AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearLayoutManager> implements
|
||||
GenreContract.GenreView {
|
||||
|
||||
private GenrePresenter mPresenter;
|
||||
|
||||
public static GenreFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
GenreFragment fragment = new GenreFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
mPresenter = new GenrePresenter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().getToolbar().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library
|
||||
: R.string.genres);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().getToolbar().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.genres);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
mPresenter.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mPresenter.unsubscribe();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected LinearLayoutManager createLayoutManager() {
|
||||
return new LinearLayoutManager(getActivity());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected GenreAdapter createAdapter() {
|
||||
ArrayList<Genre> dataSet =
|
||||
getAdapter() == null ? new ArrayList<Genre>() : getAdapter().getDataSet();
|
||||
return new GenreAdapter(getLibraryFragment().getMainActivity(), dataSet, R.layout.item_list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Genre> songs) {
|
||||
getAdapter().swapDataSet(songs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<Genre>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
menu.removeItem(R.id.action_sort_order);
|
||||
menu.removeItem(R.id.action_grid_size);
|
||||
menu.removeItem(R.id.action_new_playlist);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_genres;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,458 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.mainactivity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.afollestad.materialcab.MaterialCab;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog;
|
||||
import code.name.monkey.retromusic.dialogs.SleepTimerDialog;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.SortOrder;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.ui.activities.SearchActivity;
|
||||
import code.name.monkey.retromusic.ui.activities.SettingsActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMainActivityFragment;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import code.name.monkey.retromusic.views.SansFontCollapsingToolbarLayout;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class LibraryFragment extends AbsMainActivityFragment implements CabHolder,
|
||||
MainActivityFragmentCallbacks {
|
||||
|
||||
private static final String TAG = "LibraryFragment";
|
||||
private static final String CURRENT_TAB_ID = "current_tab_id";
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.appbar)
|
||||
AppBarLayout appbar;
|
||||
@BindView(R.id.collapsing_toolbar)
|
||||
SansFontCollapsingToolbarLayout collapsingToolbar;
|
||||
|
||||
private Unbinder unBinder;
|
||||
private MaterialCab cab;
|
||||
private FragmentManager fragmentManager;
|
||||
|
||||
public static Fragment newInstance(int tab) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(CURRENT_TAB_ID, tab);
|
||||
LibraryFragment fragment = new LibraryFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public SansFontCollapsingToolbarLayout getToolbar() {
|
||||
return collapsingToolbar;
|
||||
}
|
||||
|
||||
public void addOnAppBarOffsetChangedListener(
|
||||
AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) {
|
||||
appbar.addOnOffsetChangedListener(onOffsetChangedListener);
|
||||
}
|
||||
|
||||
public void removeOnAppBarOffsetChangedListener(
|
||||
AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) {
|
||||
appbar.removeOnOffsetChangedListener(onOffsetChangedListener);
|
||||
}
|
||||
|
||||
public int getTotalAppBarScrollingRange() {
|
||||
return appbar.getTotalScrollRange();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_library, container, false);
|
||||
unBinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
setStatusbarColorAuto(view);
|
||||
|
||||
getMainActivity().setBottomBarVisibility(View.VISIBLE);
|
||||
setupToolbar();
|
||||
if (getArguments() == null) {
|
||||
selectedFragment(SongsFragment.newInstance());
|
||||
return;
|
||||
}
|
||||
switch (getArguments().getInt(CURRENT_TAB_ID)) {
|
||||
default:
|
||||
case R.id.action_song:
|
||||
selectedFragment(SongsFragment.newInstance());
|
||||
break;
|
||||
case R.id.action_album:
|
||||
selectedFragment(AlbumsFragment.newInstance());
|
||||
break;
|
||||
case R.id.action_artist:
|
||||
selectedFragment(ArtistsFragment.newInstance());
|
||||
break;
|
||||
case R.id.action_playlist:
|
||||
selectedFragment(PlaylistsFragment.newInstance());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupToolbar() {
|
||||
//noinspection ConstantConditions
|
||||
int primaryColor = ThemeStore.primaryColor(getContext());
|
||||
appbar.setBackgroundColor(primaryColor);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
toolbar.setTitle(R.string.library);
|
||||
appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) ->
|
||||
getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext())));
|
||||
Objects.requireNonNull(getActivity()).setTitle(R.string.app_name);
|
||||
getMainActivity().setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
public Fragment getCurrentFragment() {
|
||||
if (fragmentManager == null) {
|
||||
return SongsFragment.newInstance();
|
||||
}
|
||||
return fragmentManager.findFragmentByTag(LibraryFragment.TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unBinder.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleBackPress() {
|
||||
if (cab != null && cab.isActive()) {
|
||||
cab.finish();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void selectedFragment(Fragment fragment) {
|
||||
fragmentManager = getChildFragmentManager();
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
|
||||
fragmentTransaction
|
||||
.replace(R.id.fragment_container, fragment, TAG)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MaterialCab openCab(int menuRes, MaterialCab.Callback callback) {
|
||||
if (cab != null && cab.isActive()) {
|
||||
cab.finish();
|
||||
}
|
||||
//noinspection ConstantConditions
|
||||
cab = new MaterialCab(getMainActivity(), R.id.cab_stub)
|
||||
.setMenu(menuRes)
|
||||
.setCloseDrawableRes(R.drawable.ic_close_white_24dp)
|
||||
.setBackgroundColor(
|
||||
RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(getActivity())))
|
||||
.start(callback);
|
||||
return cab;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.menu_main, menu);
|
||||
|
||||
Fragment currentFragment = getCurrentFragment();
|
||||
if (currentFragment instanceof AbsLibraryPagerRecyclerViewCustomGridSizeFragment
|
||||
&& currentFragment.isAdded()) {
|
||||
AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment = (AbsLibraryPagerRecyclerViewCustomGridSizeFragment) currentFragment;
|
||||
|
||||
MenuItem gridSizeItem = menu.findItem(R.id.action_grid_size);
|
||||
if (RetroUtil.isLandscape(getResources())) {
|
||||
gridSizeItem.setTitle(R.string.action_grid_size_land);
|
||||
}
|
||||
setUpGridSizeMenu(fragment, gridSizeItem.getSubMenu());
|
||||
|
||||
setUpSortOrderMenu(fragment, menu.findItem(R.id.action_sort_order).getSubMenu());
|
||||
|
||||
} else {
|
||||
menu.add(0, R.id.action_new_playlist, 0, R.string.new_playlist_title);
|
||||
menu.removeItem(R.id.action_grid_size);
|
||||
}
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(getActivity(), toolbar, menu,
|
||||
ATHToolbarActivity.getToolbarBackgroundColor(toolbar));
|
||||
}
|
||||
|
||||
private void setUpSortOrderMenu(
|
||||
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment,
|
||||
@NonNull SubMenu sortOrderMenu) {
|
||||
String currentSortOrder = fragment.getSortOrder();
|
||||
sortOrderMenu.clear();
|
||||
|
||||
if (fragment instanceof AlbumsFragment) {
|
||||
sortOrderMenu.add(0, R.id.action_album_sort_order_asc, 0, R.string.sort_order_a_z)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_A_Z));
|
||||
sortOrderMenu.add(0, R.id.action_album_sort_order_desc, 1, R.string.sort_order_z_a)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_Z_A));
|
||||
sortOrderMenu.add(0, R.id.action_album_sort_order_artist, 2, R.string.sort_order_artist)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_ARTIST));
|
||||
sortOrderMenu.add(0, R.id.action_album_sort_order_year, 3, R.string.sort_order_year)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_YEAR));
|
||||
} else if (fragment instanceof ArtistsFragment) {
|
||||
sortOrderMenu.add(0, R.id.action_artist_sort_order_asc, 0, R.string.sort_order_a_z)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_A_Z));
|
||||
sortOrderMenu.add(0, R.id.action_artist_sort_order_desc, 1, R.string.sort_order_z_a)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.ArtistSortOrder.ARTIST_Z_A));
|
||||
} else if (fragment instanceof SongsFragment) {
|
||||
sortOrderMenu.add(0, R.id.action_song_sort_order_asc, 0, R.string.sort_order_a_z)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_A_Z));
|
||||
sortOrderMenu.add(0, R.id.action_song_sort_order_desc, 1, R.string.sort_order_z_a)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_Z_A));
|
||||
sortOrderMenu.add(0, R.id.action_song_sort_order_artist, 2, R.string.sort_order_artist)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ARTIST));
|
||||
sortOrderMenu.add(0, R.id.action_song_sort_order_album, 3, R.string.sort_order_album)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_ALBUM));
|
||||
sortOrderMenu.add(0, R.id.action_song_sort_order_year, 4, R.string.sort_order_year)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_YEAR));
|
||||
sortOrderMenu.add(0, R.id.action_song_sort_order_date, 4, R.string.sort_order_date)
|
||||
.setChecked(currentSortOrder.equals(SortOrder.SongSortOrder.SONG_DATE));
|
||||
}
|
||||
|
||||
sortOrderMenu.setGroupCheckable(0, true, true);
|
||||
}
|
||||
|
||||
private boolean handleSortOrderMenuItem(
|
||||
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, @NonNull MenuItem item) {
|
||||
String sortOrder = null;
|
||||
if (fragment instanceof AlbumsFragment) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_album_sort_order_asc:
|
||||
sortOrder = SortOrder.AlbumSortOrder.ALBUM_A_Z;
|
||||
break;
|
||||
case R.id.action_album_sort_order_desc:
|
||||
sortOrder = SortOrder.AlbumSortOrder.ALBUM_Z_A;
|
||||
break;
|
||||
case R.id.action_album_sort_order_artist:
|
||||
sortOrder = SortOrder.AlbumSortOrder.ALBUM_ARTIST;
|
||||
break;
|
||||
case R.id.action_album_sort_order_year:
|
||||
sortOrder = SortOrder.AlbumSortOrder.ALBUM_YEAR;
|
||||
break;
|
||||
}
|
||||
} else if (fragment instanceof ArtistsFragment) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_artist_sort_order_asc:
|
||||
sortOrder = SortOrder.ArtistSortOrder.ARTIST_A_Z;
|
||||
break;
|
||||
case R.id.action_artist_sort_order_desc:
|
||||
sortOrder = SortOrder.ArtistSortOrder.ARTIST_Z_A;
|
||||
break;
|
||||
}
|
||||
} else if (fragment instanceof SongsFragment) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_song_sort_order_asc:
|
||||
sortOrder = SortOrder.SongSortOrder.SONG_A_Z;
|
||||
break;
|
||||
case R.id.action_song_sort_order_desc:
|
||||
sortOrder = SortOrder.SongSortOrder.SONG_Z_A;
|
||||
break;
|
||||
case R.id.action_song_sort_order_artist:
|
||||
sortOrder = SortOrder.SongSortOrder.SONG_ARTIST;
|
||||
break;
|
||||
case R.id.action_song_sort_order_album:
|
||||
sortOrder = SortOrder.SongSortOrder.SONG_ALBUM;
|
||||
break;
|
||||
case R.id.action_song_sort_order_year:
|
||||
sortOrder = SortOrder.SongSortOrder.SONG_YEAR;
|
||||
break;
|
||||
case R.id.action_song_sort_order_date:
|
||||
sortOrder = SortOrder.SongSortOrder.SONG_DATE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sortOrder != null) {
|
||||
item.setChecked(true);
|
||||
fragment.setAndSaveSortOrder(sortOrder);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(activity, toolbar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
//if (pager == null) return false;
|
||||
Fragment currentFragment = getCurrentFragment();
|
||||
if (currentFragment instanceof AbsLibraryPagerRecyclerViewCustomGridSizeFragment) {
|
||||
AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment = (AbsLibraryPagerRecyclerViewCustomGridSizeFragment) currentFragment;
|
||||
if (handleGridSizeMenuItem(fragment, item)) {
|
||||
return true;
|
||||
}
|
||||
if (handleSortOrderMenuItem(fragment, item)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.action_new_playlist:
|
||||
CreatePlaylistDialog.create().show(getChildFragmentManager(), "CREATE_PLAYLIST");
|
||||
return true;
|
||||
case R.id.action_shuffle_all:
|
||||
//noinspection ConstantConditions
|
||||
SongLoader.getAllSongs(getContext()).subscribeOn(Schedulers.computation())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(songs -> MusicPlayerRemote.openAndShuffleQueue(songs, true));
|
||||
return true;
|
||||
case R.id.action_search:
|
||||
startActivity(new Intent(getActivity(), SearchActivity.class));
|
||||
return true;
|
||||
case R.id.action_equalizer:
|
||||
//noinspection ConstantConditions
|
||||
NavigationUtil.openEqualizer(getActivity());
|
||||
return true;
|
||||
case R.id.action_sleep_timer:
|
||||
if (getFragmentManager() != null) {
|
||||
new SleepTimerDialog().show(getFragmentManager(), TAG);
|
||||
}
|
||||
return true;
|
||||
case R.id.action_settings:
|
||||
startActivity(new Intent(getContext(), SettingsActivity.class));
|
||||
break;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void setUpGridSizeMenu(
|
||||
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment,
|
||||
@NonNull SubMenu gridSizeMenu) {
|
||||
switch (fragment.getGridSize()) {
|
||||
case 1:
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_1).setChecked(true);
|
||||
break;
|
||||
case 2:
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_2).setChecked(true);
|
||||
break;
|
||||
case 3:
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_3).setChecked(true);
|
||||
break;
|
||||
case 4:
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_4).setChecked(true);
|
||||
break;
|
||||
case 5:
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_5).setChecked(true);
|
||||
break;
|
||||
case 6:
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_6).setChecked(true);
|
||||
break;
|
||||
case 7:
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_7).setChecked(true);
|
||||
break;
|
||||
case 8:
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_8).setChecked(true);
|
||||
break;
|
||||
}
|
||||
int maxGridSize = fragment.getMaxGridSize();
|
||||
if (maxGridSize < 8) {
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_8).setVisible(false);
|
||||
}
|
||||
if (maxGridSize < 7) {
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_7).setVisible(false);
|
||||
}
|
||||
if (maxGridSize < 6) {
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_6).setVisible(false);
|
||||
}
|
||||
if (maxGridSize < 5) {
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_5).setVisible(false);
|
||||
}
|
||||
if (maxGridSize < 4) {
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_4).setVisible(false);
|
||||
}
|
||||
if (maxGridSize < 3) {
|
||||
gridSizeMenu.findItem(R.id.action_grid_size_3).setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean handleGridSizeMenuItem(
|
||||
@NonNull AbsLibraryPagerRecyclerViewCustomGridSizeFragment fragment, @NonNull MenuItem item) {
|
||||
int gridSize = 0;
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_grid_size_1:
|
||||
gridSize = 1;
|
||||
break;
|
||||
case R.id.action_grid_size_2:
|
||||
gridSize = 2;
|
||||
break;
|
||||
case R.id.action_grid_size_3:
|
||||
gridSize = 3;
|
||||
break;
|
||||
case R.id.action_grid_size_4:
|
||||
gridSize = 4;
|
||||
break;
|
||||
case R.id.action_grid_size_5:
|
||||
gridSize = 5;
|
||||
break;
|
||||
case R.id.action_grid_size_6:
|
||||
gridSize = 6;
|
||||
break;
|
||||
case R.id.action_grid_size_7:
|
||||
gridSize = 7;
|
||||
break;
|
||||
case R.id.action_grid_size_8:
|
||||
gridSize = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
if (gridSize > 0) {
|
||||
item.setChecked(true);
|
||||
fragment.setAndSaveGridSize(gridSize);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.mainactivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.mvp.contract.PlaylistContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.PlaylistPresenter;
|
||||
import code.name.monkey.retromusic.ui.adapter.playlist.PlaylistAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
|
||||
public class PlaylistsFragment extends AbsLibraryPagerRecyclerViewFragment<PlaylistAdapter, LinearLayoutManager> implements
|
||||
PlaylistContract.PlaylistView {
|
||||
|
||||
private PlaylistPresenter presenter;
|
||||
|
||||
public static PlaylistsFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlaylistsFragment fragment = new PlaylistsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
presenter = new PlaylistPresenter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LinearLayoutManager createLayoutManager() {
|
||||
return new LinearLayoutManager(getActivity());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected PlaylistAdapter createAdapter() {
|
||||
return new PlaylistAdapter(getLibraryFragment().getMainActivity(), new ArrayList<>(),
|
||||
R.layout.item_list, getLibraryFragment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().getToolbar().setTitle(PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.playlists);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().getToolbar().setTitle(PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.playlists);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
presenter.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
presenter.unsubscribe();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
super.onMediaStoreChanged();
|
||||
presenter.loadPlaylists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Playlist> playlists) {
|
||||
getAdapter().swapDataSet(playlists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
menu.removeItem(R.id.action_shuffle_all);
|
||||
menu.removeItem(R.id.action_sort_order);
|
||||
menu.removeItem(R.id.action_grid_size);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_playlists;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.mainactivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.contract.SongContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.SongPresenter;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.ShuffleButtonSongAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.SongAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public class SongsFragment extends
|
||||
AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager> implements
|
||||
SongContract.SongView {
|
||||
|
||||
private static final String TAG = "Songs";
|
||||
private SongPresenter presenter;
|
||||
|
||||
public SongsFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
public static SongsFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
SongsFragment fragment = new SongsFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
presenter = new SongPresenter(this);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected GridLayoutManager createLayoutManager() {
|
||||
return new GridLayoutManager(getActivity(), getGridSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.no_songs;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected SongAdapter createAdapter() {
|
||||
int itemLayoutRes = getItemLayoutRes();
|
||||
notifyLayoutResChanged(itemLayoutRes);
|
||||
boolean usePalette = loadUsePalette();
|
||||
ArrayList<Song> dataSet =
|
||||
getAdapter() == null ? new ArrayList<Song>() : getAdapter().getDataSet();
|
||||
|
||||
if (getGridSize() <= getMaxGridSizeForList()) {
|
||||
return new ShuffleButtonSongAdapter(getLibraryFragment().getMainActivity(), dataSet,
|
||||
itemLayoutRes, usePalette, getLibraryFragment());
|
||||
}
|
||||
return new SongAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes,
|
||||
usePalette, getLibraryFragment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
presenter.loadSongs();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadGridSize() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getSongGridSize(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSize(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongGridSize(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadGridSizeLand() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getSongGridSizeLand(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveGridSizeLand(int gridSize) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongGridSizeLand(gridSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveUsePalette(boolean usePalette) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongColoredFooters(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadUsePalette() {
|
||||
return PreferenceUtil.getInstance(getActivity()).songColoredFooters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsePalette(boolean usePalette) {
|
||||
getAdapter().usePalette(usePalette);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setGridSize(int gridSize) {
|
||||
getLayoutManager().setSpanCount(gridSize);
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getLibraryFragment().getToolbar().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library : R.string.songs);
|
||||
if (getAdapter().getDataSet().isEmpty()) {
|
||||
presenter.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMenuVisibility(boolean menuVisible) {
|
||||
super.setMenuVisibility(menuVisible);
|
||||
if (menuVisible) {
|
||||
getLibraryFragment().getToolbar().setTitle(
|
||||
PreferenceUtil.getInstance(getContext()).tabTitles() ? R.string.library
|
||||
: R.string.songs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
presenter.unsubscribe();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Song> songs) {
|
||||
getAdapter().swapDataSet(songs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
getAdapter().swapDataSet(new ArrayList<Song>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String loadSortOrder() {
|
||||
return PreferenceUtil.getInstance(getActivity()).getSongSortOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSortOrder(String sortOrder) {
|
||||
PreferenceUtil.getInstance(getActivity()).setSongSortOrder(sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSortOrder(String sortOrder) {
|
||||
presenter.loadSongs();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,697 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.mainactivity.folders;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.CoordinatorLayout;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialcab.MaterialCab;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper;
|
||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper;
|
||||
import code.name.monkey.retromusic.interfaces.CabHolder;
|
||||
import code.name.monkey.retromusic.interfaces.LoaderIds;
|
||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
|
||||
import code.name.monkey.retromusic.misc.DialogAsyncTask;
|
||||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener;
|
||||
import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.adapter.SongFileAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMainActivityFragment;
|
||||
import code.name.monkey.retromusic.util.FileUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
import code.name.monkey.retromusic.views.BreadCrumbLayout;
|
||||
|
||||
public class FoldersFragment extends AbsMainActivityFragment implements
|
||||
MainActivityFragmentCallbacks,
|
||||
CabHolder, BreadCrumbLayout.SelectionCallback, SongFileAdapter.Callbacks,
|
||||
AppBarLayout.OnOffsetChangedListener, LoaderManager.LoaderCallbacks<List<File>> {
|
||||
|
||||
public static final String TAG = FoldersFragment.class.getSimpleName();
|
||||
public static final FileFilter AUDIO_FILE_FILTER = file -> !file.isHidden() && (file.isDirectory() ||
|
||||
FileUtil.fileIsMimeType(file, "audio/*", MimeTypeMap.getSingleton()) ||
|
||||
FileUtil.fileIsMimeType(file, "application/opus", MimeTypeMap.getSingleton()) ||
|
||||
FileUtil.fileIsMimeType(file, "application/ogg", MimeTypeMap.getSingleton()));
|
||||
|
||||
protected static final String PATH = "path";
|
||||
protected static final String CRUMBS = "crumbs";
|
||||
private static final int LOADER_ID = LoaderIds.FOLDERS_FRAGMENT;
|
||||
@BindView(R.id.coordinator_layout)
|
||||
CoordinatorLayout coordinatorLayout;
|
||||
@BindView(R.id.container)
|
||||
View container;
|
||||
@BindView(android.R.id.empty)
|
||||
View empty;
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.bread_crumbs)
|
||||
BreadCrumbLayout breadCrumbs;
|
||||
@BindView(R.id.appbar)
|
||||
AppBarLayout appbar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
@BindView(R.id.recycler_view)
|
||||
FastScrollRecyclerView recyclerView;
|
||||
Comparator<File> fileComparator = (lhs, rhs) -> {
|
||||
if (lhs.isDirectory() && !rhs.isDirectory()) {
|
||||
return -1;
|
||||
} else if (!lhs.isDirectory() && rhs.isDirectory()) {
|
||||
return 1;
|
||||
} else {
|
||||
return lhs.getName().compareToIgnoreCase
|
||||
(rhs.getName());
|
||||
}
|
||||
};
|
||||
|
||||
private Unbinder unbinder;
|
||||
private SongFileAdapter adapter;
|
||||
private MaterialCab cab;
|
||||
|
||||
public FoldersFragment() {
|
||||
}
|
||||
|
||||
public static FoldersFragment newInstance(Context context) {
|
||||
return newInstance(PreferenceUtil.getInstance(context).getStartDirectory());
|
||||
}
|
||||
|
||||
public static FoldersFragment newInstance(File directory) {
|
||||
FoldersFragment frag = new FoldersFragment();
|
||||
Bundle b = new Bundle();
|
||||
b.putSerializable(PATH, directory);
|
||||
frag.setArguments(b);
|
||||
return frag;
|
||||
}
|
||||
|
||||
|
||||
public static File getDefaultStartDirectory() {
|
||||
File musicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
|
||||
File startFolder;
|
||||
if (musicDir.exists() && musicDir.isDirectory()) {
|
||||
startFolder = musicDir;
|
||||
} else {
|
||||
File externalStorage = Environment.getExternalStorageDirectory();
|
||||
if (externalStorage.exists() && externalStorage.isDirectory()) {
|
||||
startFolder = externalStorage;
|
||||
} else {
|
||||
startFolder = new File("/"); // root
|
||||
}
|
||||
}
|
||||
return startFolder;
|
||||
}
|
||||
|
||||
private static File tryGetCanonicalFile(File file) {
|
||||
try {
|
||||
return file.getCanonicalFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCrumb(BreadCrumbLayout.Crumb crumb, boolean addToHistory) {
|
||||
if (crumb == null) {
|
||||
return;
|
||||
}
|
||||
saveScrollPosition();
|
||||
breadCrumbs.setActiveOrAdd(crumb, false);
|
||||
if (addToHistory) {
|
||||
breadCrumbs.addHistory(crumb);
|
||||
}
|
||||
getLoaderManager().restartLoader(LOADER_ID, null, this);
|
||||
}
|
||||
|
||||
private void saveScrollPosition() {
|
||||
BreadCrumbLayout.Crumb crumb = getActiveCrumb();
|
||||
if (crumb != null) {
|
||||
crumb.setScrollPosition(
|
||||
((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BreadCrumbLayout.Crumb getActiveCrumb() {
|
||||
return breadCrumbs != null && breadCrumbs.size() > 0 ? breadCrumbs
|
||||
.getCrumb(breadCrumbs.getActiveIndex()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putParcelable(CRUMBS, breadCrumbs.getStateWrapper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
if (savedInstanceState == null) {
|
||||
//noinspection ConstantConditions
|
||||
setCrumb(new BreadCrumbLayout.Crumb(
|
||||
FileUtil.safeGetCanonicalFile((File) getArguments().getSerializable(PATH))), true);
|
||||
} else {
|
||||
breadCrumbs.restoreFromStateWrapper(savedInstanceState.getParcelable(CRUMBS));
|
||||
getLoaderManager().initLoader(LOADER_ID, null, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_folder, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
setStatusbarColorAuto(view);
|
||||
getMainActivity().getSlidingUpPanelLayout().setShadowHeight(0);
|
||||
|
||||
getMainActivity().setBottomBarVisibility(View.GONE);
|
||||
|
||||
setUpAppbarColor();
|
||||
setUpToolbar();
|
||||
setUpBreadCrumbs();
|
||||
setUpRecyclerView();
|
||||
setUpAdapter();
|
||||
ViewUtil.setStatusBarHeight(getContext(), statusBar);
|
||||
}
|
||||
|
||||
private void setUpAppbarColor() {
|
||||
//noinspection ConstantConditions
|
||||
int primaryColor = ThemeStore.primaryColor(getActivity());
|
||||
appbar.setBackgroundColor(primaryColor);
|
||||
toolbar.setBackgroundColor(primaryColor);
|
||||
//breadCrumbs.setBackgroundColor(primaryColor);
|
||||
breadCrumbs.setActivatedContentColor(ToolbarContentTintHelper.toolbarTitleColor(getActivity(), primaryColor));
|
||||
breadCrumbs.setDeactivatedContentColor(ToolbarContentTintHelper.toolbarSubtitleColor(getActivity(), primaryColor));
|
||||
appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext())));
|
||||
}
|
||||
|
||||
private void setUpToolbar() {
|
||||
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
|
||||
//noinspection ConstantConditions
|
||||
getActivity().setTitle(R.string.folders);
|
||||
getMainActivity().setSupportActionBar(toolbar);
|
||||
}
|
||||
|
||||
private void setUpBreadCrumbs() {
|
||||
breadCrumbs.setCallback(this);
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
//noinspection ConstantConditions
|
||||
ViewUtil.setUpFastScrollRecyclerViewColor(getActivity(), recyclerView, ThemeStore.accentColor(getActivity()));
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||
appbar.addOnOffsetChangedListener(this);
|
||||
}
|
||||
|
||||
private void setUpAdapter() {
|
||||
adapter = new SongFileAdapter(getMainActivity(), new LinkedList<File>(), R.layout.item_list, this, this);
|
||||
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
|
||||
@Override
|
||||
public void onChanged() {
|
||||
super.onChanged();
|
||||
checkIsEmpty();
|
||||
}
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
checkIsEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
saveScrollPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
appbar.removeOnOffsetChangedListener(this);
|
||||
unbinder.unbind();
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleBackPress() {
|
||||
if (cab != null && cab.isActive()) {
|
||||
cab.finish();
|
||||
return true;
|
||||
}
|
||||
if (breadCrumbs != null && breadCrumbs.popHistory()) {
|
||||
setCrumb(breadCrumbs.lastHistory(), false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MaterialCab openCab(int menuRes, MaterialCab.Callback callback) {
|
||||
if (cab != null && cab.isActive()) cab.finish();
|
||||
cab = new MaterialCab(getMainActivity(), R.id.cab_stub)
|
||||
.setMenu(menuRes)
|
||||
.setCloseDrawableRes(R.drawable.ic_close_white_24dp)
|
||||
.setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor
|
||||
(getActivity())))
|
||||
.start(callback);
|
||||
return cab;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.menu_folders, menu);
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(getActivity(), toolbar, menu, ATHToolbarActivity.getToolbarBackgroundColor(toolbar));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(getActivity(), toolbar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCrumbSelection(BreadCrumbLayout.Crumb crumb, int index) {
|
||||
setCrumb(crumb, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
//noinspection ConstantConditions
|
||||
getActivity().onBackPressed();
|
||||
break;
|
||||
case R.id.action_go_to_start_directory:
|
||||
setCrumb(new BreadCrumbLayout.Crumb(tryGetCanonicalFile(PreferenceUtil.getInstance(getActivity()).getStartDirectory())), true);
|
||||
return true;
|
||||
case R.id.action_scan:
|
||||
BreadCrumbLayout.Crumb crumb = getActiveCrumb();
|
||||
if (crumb != null) {
|
||||
//noinspection Convert2MethodRef
|
||||
new ListPathsAsyncTask(getActivity(), paths -> scanPaths(paths)).execute(new ListPathsAsyncTask.LoadingInfo(crumb.getFile(), AUDIO_FILE_FILTER));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileSelected(File file) {
|
||||
file = tryGetCanonicalFile(file); // important as we compare the path value later
|
||||
if (file.isDirectory()) {
|
||||
setCrumb(new BreadCrumbLayout.Crumb(file), true);
|
||||
} else {
|
||||
FileFilter fileFilter = pathname -> !pathname.isDirectory() && AUDIO_FILE_FILTER.accept(pathname);
|
||||
new ListSongsAsyncTask(getActivity(), file, (songs, extra) -> {
|
||||
File file1 = (File) extra;
|
||||
int startIndex = -1;
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
if (file1.getPath().equals(songs.get(i).data)) { // path is already canonical here
|
||||
startIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (startIndex > -1) {
|
||||
MusicPlayerRemote.openQueue(songs, startIndex, true);
|
||||
} else {
|
||||
final File finalFile = file1;
|
||||
Snackbar.make(coordinatorLayout, Html.fromHtml(String.format(getString(R.string.not_listed_in_media_store), file1.getName())), Snackbar.LENGTH_LONG)
|
||||
.setAction(R.string.action_scan, v -> new ListPathsAsyncTask(getActivity(), paths -> scanPaths(paths)).execute(new ListPathsAsyncTask.LoadingInfo(finalFile, AUDIO_FILE_FILTER)))
|
||||
.setActionTextColor(ThemeStore.accentColor(getActivity()))
|
||||
.show();
|
||||
}
|
||||
}).execute(new ListSongsAsyncTask.LoadingInfo(toList(file.getParentFile()), fileFilter, getFileComparator()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMultipleItemAction(MenuItem item, ArrayList<File> files) {
|
||||
final int itemId = item.getItemId();
|
||||
new ListSongsAsyncTask(getActivity(), null, (songs, extra) -> SongsMenuHelper.handleMenuClick(getActivity(), songs, itemId)).execute(new ListSongsAsyncTask.LoadingInfo(files, AUDIO_FILE_FILTER, getFileComparator()));
|
||||
}
|
||||
|
||||
private ArrayList<File> toList(File file) {
|
||||
ArrayList<File> files = new ArrayList<>(1);
|
||||
files.add(file);
|
||||
return files;
|
||||
}
|
||||
|
||||
private Comparator<File> getFileComparator() {
|
||||
return fileComparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileMenuClicked(final File file, View view) {
|
||||
PopupMenu popupMenu = new PopupMenu(getActivity(), view);
|
||||
if (file.isDirectory()) {
|
||||
popupMenu.inflate(R.menu.menu_item_directory);
|
||||
popupMenu.setOnMenuItemClickListener(item -> {
|
||||
final int itemId = item.getItemId();
|
||||
switch (itemId) {
|
||||
case R.id.action_play_next:
|
||||
case R.id.action_add_to_current_playing:
|
||||
case R.id.action_add_to_playlist:
|
||||
case R.id.action_delete_from_device:
|
||||
new ListSongsAsyncTask(getActivity(), null, (songs, extra) -> SongsMenuHelper.handleMenuClick(getActivity(), songs, itemId)).execute(new ListSongsAsyncTask.LoadingInfo(toList(file), AUDIO_FILE_FILTER, getFileComparator()));
|
||||
return true;
|
||||
case R.id.action_set_as_start_directory:
|
||||
PreferenceUtil.getInstance(getActivity()).setStartDirectory(file);
|
||||
Toast.makeText(getActivity(), String.format(getString(R.string.new_start_directory), file.getPath()), Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
case R.id.action_scan:
|
||||
new ListPathsAsyncTask(getActivity(), paths -> scanPaths(paths)).execute(new ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
} else {
|
||||
popupMenu.inflate(R.menu.menu_item_file);
|
||||
popupMenu.setOnMenuItemClickListener(item -> {
|
||||
final int itemId = item.getItemId();
|
||||
switch (itemId) {
|
||||
case R.id.action_play_next:
|
||||
case R.id.action_add_to_current_playing:
|
||||
case R.id.action_add_to_playlist:
|
||||
case R.id.action_go_to_album:
|
||||
case R.id.action_go_to_artist:
|
||||
case R.id.action_share:
|
||||
case R.id.action_tag_editor:
|
||||
case R.id.action_details:
|
||||
case R.id.action_set_as_ringtone:
|
||||
case R.id.action_delete_from_device:
|
||||
new ListSongsAsyncTask(getActivity(), null, (songs, extra) -> SongMenuHelper.handleMenuClick(getActivity(), songs.get(0), itemId)).execute(new ListSongsAsyncTask.LoadingInfo(toList(file), AUDIO_FILE_FILTER, getFileComparator()));
|
||||
return true;
|
||||
case R.id.action_scan:
|
||||
new ListPathsAsyncTask(getActivity(), paths -> scanPaths(paths)).execute(new ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
popupMenu.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
|
||||
container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), container.getPaddingRight(), appbar.getTotalScrollRange() + verticalOffset);
|
||||
}
|
||||
|
||||
private void checkIsEmpty() {
|
||||
if (empty != null) {
|
||||
empty.setVisibility(adapter == null || adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void scanPaths(@Nullable String[] toBeScanned) {
|
||||
if (getActivity() == null) return;
|
||||
if (toBeScanned == null || toBeScanned.length < 1) {
|
||||
Toast.makeText(getActivity(), R.string.nothing_to_scan, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
MediaScannerConnection.scanFile(getActivity().getApplicationContext(), toBeScanned, null, new UpdateToastMediaScannerCompletionListener(getActivity(), toBeScanned));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAdapter(@NonNull List<File> files) {
|
||||
adapter.swapDataSet(files);
|
||||
BreadCrumbLayout.Crumb crumb = getActiveCrumb();
|
||||
if (crumb != null && recyclerView != null) {
|
||||
((LinearLayoutManager) recyclerView.getLayoutManager())
|
||||
.scrollToPositionWithOffset(crumb.getScrollPosition(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Loader<List<File>> onCreateLoader(int id, Bundle args) {
|
||||
return new AsyncFileLoader(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(@NonNull Loader<List<File>> loader, List<File> data) {
|
||||
updateAdapter(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(@NonNull Loader<List<File>> loader) {
|
||||
updateAdapter(new LinkedList<File>());
|
||||
}
|
||||
|
||||
private static class AsyncFileLoader extends WrappedAsyncTaskLoader<List<File>> {
|
||||
private WeakReference<FoldersFragment> fragmentWeakReference;
|
||||
|
||||
public AsyncFileLoader(FoldersFragment foldersFragment) {
|
||||
super(foldersFragment.getActivity());
|
||||
fragmentWeakReference = new WeakReference<>(foldersFragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<File> loadInBackground() {
|
||||
FoldersFragment foldersFragment = fragmentWeakReference.get();
|
||||
File directory = null;
|
||||
if (foldersFragment != null) {
|
||||
BreadCrumbLayout.Crumb crumb = foldersFragment.getActiveCrumb();
|
||||
if (crumb != null) {
|
||||
directory = crumb.getFile();
|
||||
}
|
||||
}
|
||||
if (directory != null) {
|
||||
List<File> files = FileUtil.listFiles(directory, AUDIO_FILE_FILTER);
|
||||
Collections.sort(files, foldersFragment.getFileComparator());
|
||||
return files;
|
||||
} else {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ListSongsAsyncTask extends ListingFilesDialogAsyncTask<ListSongsAsyncTask.LoadingInfo, Void, ArrayList<Song>> {
|
||||
private final Object extra;
|
||||
private WeakReference<Context> contextWeakReference;
|
||||
private WeakReference<OnSongsListedCallback> callbackWeakReference;
|
||||
|
||||
public ListSongsAsyncTask(Context context, Object extra, OnSongsListedCallback callback) {
|
||||
super(context);
|
||||
this.extra = extra;
|
||||
contextWeakReference = new WeakReference<>(context);
|
||||
callbackWeakReference = new WeakReference<>(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
checkCallbackReference();
|
||||
checkContextReference();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrayList<Song> doInBackground(LoadingInfo... params) {
|
||||
try {
|
||||
LoadingInfo info = params[0];
|
||||
List<File> files = FileUtil.listFilesDeep(info.files, info.fileFilter);
|
||||
|
||||
if (isCancelled() || checkContextReference() == null || checkCallbackReference() == null)
|
||||
return null;
|
||||
|
||||
Collections.sort(files, info.fileComparator);
|
||||
|
||||
Context context = checkContextReference();
|
||||
if (isCancelled() || context == null || checkCallbackReference() == null)
|
||||
return null;
|
||||
|
||||
return FileUtil.matchFilesWithMediaStore(context, files).blockingFirst();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
cancel(false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(ArrayList<Song> songs) {
|
||||
super.onPostExecute(songs);
|
||||
OnSongsListedCallback callback = checkCallbackReference();
|
||||
if (songs != null && callback != null)
|
||||
callback.onSongsListed(songs, extra);
|
||||
}
|
||||
|
||||
private Context checkContextReference() {
|
||||
Context context = contextWeakReference.get();
|
||||
if (context == null) {
|
||||
cancel(false);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
private OnSongsListedCallback checkCallbackReference() {
|
||||
OnSongsListedCallback callback = callbackWeakReference.get();
|
||||
if (callback == null) {
|
||||
cancel(false);
|
||||
}
|
||||
return callback;
|
||||
}
|
||||
|
||||
public interface OnSongsListedCallback {
|
||||
void onSongsListed(@NonNull ArrayList<Song> songs, Object extra);
|
||||
}
|
||||
|
||||
public static class LoadingInfo {
|
||||
public final Comparator<File> fileComparator;
|
||||
public final FileFilter fileFilter;
|
||||
public final List<File> files;
|
||||
|
||||
public LoadingInfo(@NonNull List<File> files, @NonNull FileFilter fileFilter, @NonNull Comparator<File> fileComparator) {
|
||||
this.fileComparator = fileComparator;
|
||||
this.fileFilter = fileFilter;
|
||||
this.files = files;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ListPathsAsyncTask extends ListingFilesDialogAsyncTask<ListPathsAsyncTask.LoadingInfo, String, String[]> {
|
||||
private WeakReference<OnPathsListedCallback> onPathsListedCallbackWeakReference;
|
||||
|
||||
public ListPathsAsyncTask(Context context, OnPathsListedCallback callback) {
|
||||
super(context);
|
||||
onPathsListedCallbackWeakReference = new WeakReference<>(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
checkCallbackReference();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] doInBackground(LoadingInfo... params) {
|
||||
try {
|
||||
if (isCancelled() || checkCallbackReference() == null) return null;
|
||||
|
||||
LoadingInfo info = params[0];
|
||||
|
||||
final String[] paths;
|
||||
|
||||
if (info.file.isDirectory()) {
|
||||
List<File> files = FileUtil.listFilesDeep(info.file, info.fileFilter);
|
||||
|
||||
if (isCancelled() || checkCallbackReference() == null) return null;
|
||||
|
||||
paths = new String[files.size()];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
File f = files.get(i);
|
||||
paths[i] = FileUtil.safeGetCanonicalPath(f);
|
||||
|
||||
if (isCancelled() || checkCallbackReference() == null) return null;
|
||||
}
|
||||
} else {
|
||||
paths = new String[1];
|
||||
paths[0] = info.file.getPath();
|
||||
}
|
||||
|
||||
return paths;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
cancel(false);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String[] paths) {
|
||||
super.onPostExecute(paths);
|
||||
OnPathsListedCallback callback = checkCallbackReference();
|
||||
if (callback != null && paths != null) {
|
||||
callback.onPathsListed(paths);
|
||||
}
|
||||
}
|
||||
|
||||
private OnPathsListedCallback checkCallbackReference() {
|
||||
OnPathsListedCallback callback = onPathsListedCallbackWeakReference.get();
|
||||
if (callback == null) {
|
||||
cancel(false);
|
||||
}
|
||||
return callback;
|
||||
}
|
||||
|
||||
public interface OnPathsListedCallback {
|
||||
void onPathsListed(@NonNull String[] paths);
|
||||
}
|
||||
|
||||
public static class LoadingInfo {
|
||||
public final File file;
|
||||
public final FileFilter fileFilter;
|
||||
|
||||
public LoadingInfo(File file, FileFilter fileFilter) {
|
||||
this.file = file;
|
||||
this.fileFilter = fileFilter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class ListingFilesDialogAsyncTask<Params, Progress, Result> extends DialogAsyncTask<Params, Progress, Result> {
|
||||
public ListingFilesDialogAsyncTask(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ListingFilesDialogAsyncTask(Context context, int showDelay) {
|
||||
super(context, showDelay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog createDialog(@NonNull Context context) {
|
||||
return new MaterialDialog.Builder(context)
|
||||
.title(R.string.listing_files)
|
||||
.progress(true, 0)
|
||||
.progressIndeterminateStyle(true)
|
||||
.cancelListener(dialog -> cancel(false))
|
||||
.dismissListener(dialog -> cancel(false))
|
||||
.negativeText(android.R.string.cancel)
|
||||
.onNegative((dialog, which) -> cancel(false))
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,413 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.mainactivity.home;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.AppBarLayout;
|
||||
import android.support.design.widget.CollapsingToolbarLayout;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.GridLayoutManager;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Display;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Random;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.dialogs.HomeOptionDialog;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks;
|
||||
import code.name.monkey.retromusic.loaders.SongLoader;
|
||||
import code.name.monkey.retromusic.misc.AppBarStateChangeListener;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.HistoryPlaylist;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist;
|
||||
import code.name.monkey.retromusic.mvp.contract.HomeContract;
|
||||
import code.name.monkey.retromusic.mvp.presenter.HomePresenter;
|
||||
import code.name.monkey.retromusic.ui.adapter.GenreAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.album.AlbumFullWithAdapter;
|
||||
import code.name.monkey.retromusic.ui.adapter.artist.ArtistAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMainActivityFragment;
|
||||
import code.name.monkey.retromusic.util.Compressor;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
import code.name.monkey.retromusic.views.CircularImageView;
|
||||
import code.name.monkey.retromusic.views.MetalRecyclerViewPager;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.USER_BANNER;
|
||||
import static code.name.monkey.retromusic.Constants.USER_PROFILE;
|
||||
|
||||
public class HomeFragment extends AbsMainActivityFragment implements MainActivityFragmentCallbacks,
|
||||
HomeContract.HomeView {
|
||||
private static final String TAG = "HomeFragment";
|
||||
Unbinder unbinder;
|
||||
@BindView(R.id.home_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.appbar)
|
||||
AppBarLayout appbar;
|
||||
@BindView(R.id.image)
|
||||
ImageView imageView;
|
||||
@BindView(R.id.user_image)
|
||||
CircularImageView userImage;
|
||||
@BindView(R.id.collapsing_toolbar)
|
||||
CollapsingToolbarLayout toolbarLayout;
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recentArtistRV;
|
||||
@BindView(R.id.recent_album)
|
||||
RecyclerView recentAlbumRV;
|
||||
@BindView(R.id.top_artist)
|
||||
RecyclerView topArtistRV;
|
||||
@BindView(R.id.top_album)
|
||||
MetalRecyclerViewPager topAlbumRV;
|
||||
@BindView(R.id.recent_artist_container)
|
||||
View recentArtistContainer;
|
||||
@BindView(R.id.recent_albums_container)
|
||||
View recentAlbumsContainer;
|
||||
@BindView(R.id.top_artist_container)
|
||||
View topArtistContainer;
|
||||
@BindView(R.id.top_albums_container)
|
||||
View topAlbumContainer;
|
||||
@BindView(R.id.genres)
|
||||
RecyclerView genresRecyclerView;
|
||||
@BindView(R.id.genre_container)
|
||||
LinearLayout genreContainer;
|
||||
@BindView(R.id.container)
|
||||
View container;
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.search)
|
||||
ImageView search;
|
||||
|
||||
|
||||
private HomePresenter homePresenter;
|
||||
private CompositeDisposable disposable;
|
||||
|
||||
public static HomeFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
HomeFragment fragment = new HomeFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
private void getTimeOfTheDay() {
|
||||
Calendar c = Calendar.getInstance();
|
||||
int timeOfDay = c.get(Calendar.HOUR_OF_DAY);
|
||||
|
||||
String[] images = new String[]{};
|
||||
if (timeOfDay >= 0 && timeOfDay < 6) {
|
||||
images = getResources().getStringArray(R.array.night);
|
||||
} else if (timeOfDay >= 6 && timeOfDay < 12) {
|
||||
images = getResources().getStringArray(R.array.morning);
|
||||
} else if (timeOfDay >= 12 && timeOfDay < 16) {
|
||||
images = getResources().getStringArray(R.array.after_noon);
|
||||
} else if (timeOfDay >= 16 && timeOfDay < 20) {
|
||||
images = getResources().getStringArray(R.array.evening);
|
||||
} else if (timeOfDay >= 20 && timeOfDay < 24) {
|
||||
images = getResources().getStringArray(R.array.night);
|
||||
}
|
||||
String day = images[new Random().nextInt(images.length)];
|
||||
loadTimeImage(day);
|
||||
}
|
||||
|
||||
private void loadTimeImage(String day) {
|
||||
//noinspection ConstantConditions
|
||||
if (PreferenceUtil.getInstance(getActivity()).getBannerImage().isEmpty()) {
|
||||
if (imageView != null) {
|
||||
Glide.with(getActivity()).load(day)
|
||||
.asBitmap()
|
||||
.placeholder(R.drawable.material_design_default)
|
||||
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
|
||||
.into(imageView);
|
||||
}
|
||||
} else {
|
||||
loadBannerFromStorage();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadBannerFromStorage() {
|
||||
//noinspection ConstantConditions
|
||||
disposable.add(new Compressor(getContext())
|
||||
.setQuality(100)
|
||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmapAsFlowable(
|
||||
new File(PreferenceUtil.getInstance(getContext()).getBannerImage(), USER_BANNER))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(imageView::setImageBitmap));
|
||||
}
|
||||
|
||||
private void loadImageFromStorage(ImageView imageView) {
|
||||
//noinspection ConstantConditions
|
||||
disposable.add(new Compressor(getContext())
|
||||
.setMaxHeight(300)
|
||||
.setMaxWidth(300)
|
||||
.setQuality(75)
|
||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmapAsFlowable(
|
||||
new File(PreferenceUtil.getInstance(getContext()).getProfileImage(), USER_PROFILE))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(imageView::setImageBitmap,
|
||||
throwable -> imageView.setImageDrawable(ContextCompat
|
||||
.getDrawable(getContext(), R.drawable.ic_person_flat))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
disposable = new CompositeDisposable();
|
||||
//noinspection ConstantConditions
|
||||
homePresenter = new HomePresenter(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_home, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
getMainActivity().getSlidingUpPanelLayout().setShadowHeight(8);
|
||||
getMainActivity().setBottomBarVisibility(View.VISIBLE);
|
||||
|
||||
setupToolbar();
|
||||
loadImageFromStorage(userImage);
|
||||
|
||||
homePresenter.subscribe();
|
||||
checkPadding();
|
||||
getTimeOfTheDay();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void setupToolbar() {
|
||||
if (!PreferenceUtil.getInstance(getContext()).getFullScreenMode()) {
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar
|
||||
.getLayoutParams();
|
||||
params.topMargin = RetroUtil.getStatusBarHeight(getContext());
|
||||
toolbar.setLayoutParams(params);
|
||||
}
|
||||
|
||||
appbar.addOnOffsetChangedListener(new AppBarStateChangeListener() {
|
||||
@Override
|
||||
public void onStateChanged(AppBarLayout appBarLayout, State state) {
|
||||
int color;
|
||||
switch (state) {
|
||||
case COLLAPSED:
|
||||
getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext()));
|
||||
color = ThemeStore.textColorPrimary(getContext());
|
||||
break;
|
||||
default:
|
||||
case EXPANDED:
|
||||
case IDLE:
|
||||
getMainActivity().setLightStatusbar(false);
|
||||
color = ContextCompat.getColor(getContext(), R.color.md_white_1000);
|
||||
break;
|
||||
}
|
||||
TintHelper.setTintAuto(search, color, false);
|
||||
title.setTextColor(color);
|
||||
}
|
||||
});
|
||||
|
||||
int primaryColor = ThemeStore.primaryColor(getContext());
|
||||
|
||||
TintHelper.setTintAuto(container, primaryColor, true);
|
||||
toolbarLayout.setStatusBarScrimColor(primaryColor);
|
||||
toolbarLayout.setContentScrimColor(primaryColor);
|
||||
|
||||
toolbar.setTitle(R.string.home);
|
||||
getMainActivity().setSupportActionBar(toolbar);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleBackPress() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
disposable.clear();
|
||||
homePresenter.unsubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loading() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showEmptyView() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completed() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showData(ArrayList<Object> homes) {
|
||||
//homeAdapter.swapDataSet(homes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
super.onMediaStoreChanged();
|
||||
homePresenter.subscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
checkPadding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
super.onQueueChanged();
|
||||
checkPadding();
|
||||
}
|
||||
|
||||
private void checkPadding() {
|
||||
int height = getResources().getDimensionPixelSize(R.dimen.mini_player_height);
|
||||
container.setPadding(0, 0, 0, MusicPlayerRemote.getPlayingQueue().isEmpty() ? height * 2 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recentArtist(ArrayList<Artist> artists) {
|
||||
recentArtistContainer.setVisibility(View.VISIBLE);
|
||||
recentArtistRV.setLayoutManager(new GridLayoutManager(getMainActivity(),
|
||||
1, GridLayoutManager.HORIZONTAL, false));
|
||||
ArtistAdapter artistAdapter = new ArtistAdapter(getMainActivity(), artists,
|
||||
R.layout.item_artist, false, null);
|
||||
recentArtistRV.setAdapter(artistAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recentAlbum(ArrayList<Album> albums) {
|
||||
recentAlbumsContainer.setVisibility(View.VISIBLE);
|
||||
AlbumFullWithAdapter artistAdapter = new AlbumFullWithAdapter(getMainActivity(),
|
||||
getDisplayMetrics());
|
||||
artistAdapter.swapData(albums);
|
||||
recentAlbumRV.setAdapter(artistAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void topArtists(ArrayList<Artist> artists) {
|
||||
topArtistContainer.setVisibility(View.VISIBLE);
|
||||
topArtistRV.setLayoutManager(new GridLayoutManager(getMainActivity(),
|
||||
1, GridLayoutManager.HORIZONTAL, false));
|
||||
ArtistAdapter artistAdapter = new ArtistAdapter(getMainActivity(), artists,
|
||||
R.layout.item_artist, false, null);
|
||||
topArtistRV.setAdapter(artistAdapter);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void topAlbums(ArrayList<Album> albums) {
|
||||
topAlbumContainer.setVisibility(View.VISIBLE);
|
||||
AlbumFullWithAdapter artistAdapter = new AlbumFullWithAdapter(getMainActivity(),
|
||||
getDisplayMetrics());
|
||||
artistAdapter.swapData(albums);
|
||||
topAlbumRV.setAdapter(artistAdapter);
|
||||
}
|
||||
|
||||
private DisplayMetrics getDisplayMetrics() {
|
||||
Display display = getMainActivity().getWindowManager().getDefaultDisplay();
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
display.getMetrics(metrics);
|
||||
|
||||
return metrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suggestions(ArrayList<Playlist> playlists) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void geners(ArrayList<Genre> genres) {
|
||||
genreContainer.setVisibility(View.VISIBLE);
|
||||
genresRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
//noinspection ConstantConditions
|
||||
GenreAdapter genreAdapter = new GenreAdapter(getActivity(), genres, R.layout.item_list);
|
||||
genresRecyclerView.setAdapter(genreAdapter);
|
||||
}
|
||||
|
||||
|
||||
@OnClick({R.id.last_added, R.id.top_played, R.id.action_shuffle, R.id.history,
|
||||
R.id.user_image, R.id.search})
|
||||
void startUserInfo(View view) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
switch (view.getId()) {
|
||||
case R.id.action_shuffle:
|
||||
MusicPlayerRemote
|
||||
.openAndShuffleQueue(SongLoader.getAllSongs(activity).blockingFirst(), true);
|
||||
break;
|
||||
case R.id.last_added:
|
||||
NavigationUtil.goToPlaylistNew(activity, new LastAddedPlaylist(activity));
|
||||
break;
|
||||
case R.id.top_played:
|
||||
NavigationUtil.goToPlaylistNew(activity, new MyTopTracksPlaylist(activity));
|
||||
break;
|
||||
case R.id.history:
|
||||
NavigationUtil.goToPlaylistNew(activity, new HistoryPlaylist(activity));
|
||||
break;
|
||||
case R.id.search:
|
||||
NavigationUtil.goToSearch(activity);
|
||||
break;
|
||||
case R.id.user_image:
|
||||
new HomeOptionDialog().show(getFragmentManager(), TAG);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
homePresenter.loadRecentArtists();
|
||||
homePresenter.loadRecentAlbums();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.transform.CustPagerTransformer;
|
||||
import code.name.monkey.retromusic.transform.NormalPageTransformer;
|
||||
import code.name.monkey.retromusic.transform.ParallaxPagerTransformer;
|
||||
import code.name.monkey.retromusic.ui.adapter.album.AlbumCoverPagerAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.NowPlayingScreen;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMusicServiceFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
|
||||
public class PlayerAlbumCoverFragment extends AbsMusicServiceFragment implements
|
||||
ViewPager.OnPageChangeListener {
|
||||
|
||||
public static final String TAG = PlayerAlbumCoverFragment.class.getSimpleName();
|
||||
public static final long VISIBILITY_ANIM_DURATION = 300;
|
||||
@BindView(R.id.player_album_cover_viewpager)
|
||||
ViewPager viewPager;
|
||||
private Unbinder unbinder;
|
||||
private Callbacks callbacks;
|
||||
private int currentPosition;
|
||||
private AlbumCoverPagerAdapter.AlbumCoverFragment.ColorReceiver colorReceiver =
|
||||
new AlbumCoverPagerAdapter.AlbumCoverFragment.ColorReceiver() {
|
||||
@Override
|
||||
public void onColorReady(int color, int requestCode) {
|
||||
if (currentPosition == requestCode) {
|
||||
notifyColorChange(color);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void removeSlideEffect() {
|
||||
ParallaxPagerTransformer transformer = new ParallaxPagerTransformer(R.id.player_image);
|
||||
transformer.setSpeed(0.3f);
|
||||
viewPager.setPageTransformer(true, transformer);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_player_album_cover, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
viewPager.addOnPageChangeListener(this);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
if (PreferenceUtil.getInstance(getContext()).carouselEffect() && !(
|
||||
(PreferenceUtil.getInstance(getContext()).getNowPlayingScreen() == NowPlayingScreen.FULL) ||
|
||||
(PreferenceUtil.getInstance(getContext()).getNowPlayingScreen()
|
||||
== NowPlayingScreen.FLAT))) {
|
||||
viewPager.setClipToPadding(false);
|
||||
viewPager.setPadding(96, 0, 96, 0);
|
||||
viewPager.setPageMargin(18);
|
||||
|
||||
viewPager.setPageTransformer(false, new CustPagerTransformer(getContext()));
|
||||
} else {
|
||||
viewPager.setPageTransformer(true, new NormalPageTransformer());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
viewPager.removeOnPageChangeListener(this);
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayingQueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
viewPager.setCurrentItem(MusicPlayerRemote.getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
updatePlayingQueue();
|
||||
}
|
||||
|
||||
private void updatePlayingQueue() {
|
||||
viewPager.setAdapter(
|
||||
new AlbumCoverPagerAdapter(getFragmentManager(), MusicPlayerRemote.getPlayingQueue()));
|
||||
//noinspection ConstantConditions
|
||||
viewPager.getAdapter().notifyDataSetChanged();
|
||||
viewPager.setCurrentItem(MusicPlayerRemote.getPosition());
|
||||
onPageSelected(MusicPlayerRemote.getPosition());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
currentPosition = position;
|
||||
if (viewPager.getAdapter() != null) {
|
||||
((AlbumCoverPagerAdapter) viewPager.getAdapter()).receiveColor(colorReceiver, position);
|
||||
}
|
||||
if (position != MusicPlayerRemote.getPosition()) {
|
||||
MusicPlayerRemote.playSongAt(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void notifyColorChange(int color) {
|
||||
if (callbacks != null) {
|
||||
callbacks.onColorChanged(color);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCallbacks(Callbacks listener) {
|
||||
callbacks = listener;
|
||||
}
|
||||
|
||||
public void removeEffect() {
|
||||
viewPager.setPageTransformer(false, null);
|
||||
}
|
||||
|
||||
|
||||
public interface Callbacks {
|
||||
|
||||
void onColorChanged(int color);
|
||||
|
||||
void onFavoriteToggled();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.adaptive;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment.Callbacks;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment;
|
||||
|
||||
public class AdaptiveFragment extends AbsPlayerFragment implements Callbacks {
|
||||
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
private int lastColor;
|
||||
private AdaptivePlaybackControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
|
||||
public static PlayerFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlayerFragment fragment = new PlayerFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
playbackControlsFragment.setDark(color);
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar,
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor), getActivity());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_adaptive_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment =
|
||||
(AdaptivePlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment =
|
||||
(PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
playerAlbumCoverFragment.removeSlideEffect();
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
int primaryColor = ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, primaryColor, getActivity());
|
||||
toolbar.setTitleTextColor(primaryColor);
|
||||
toolbar.setSubtitleTextColor(ThemeStore.textColorSecondary(getContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
toolbar.setTitle(song.title);
|
||||
toolbar.setSubtitle(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,313 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.adaptive;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatSeekBar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
|
||||
public class AdaptivePlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseButton;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
AppCompatSeekBar progressSlider;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView songTotalTime;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View volumeContainer;
|
||||
|
||||
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable playPauseDrawable;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater
|
||||
.inflate(R.layout.fragment_adaptive_player_playback_controls, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
setUpMusicControllers();
|
||||
|
||||
hideVolumeIfAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
|
||||
if (ColorUtil.isColorLight(ATHUtil.resolveColor(getContext(), android.R.attr.windowBackground))) {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(getActivity(), true);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(getActivity(), true);
|
||||
} else {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(getActivity(), false);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
}
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
updatePlayPauseColor();
|
||||
|
||||
TintHelper.setTintAuto(playPauseButton, MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(dark)), false);
|
||||
TintHelper.setTintAuto(playPauseButton, dark, true);
|
||||
TintHelper.setTintAuto(progressSlider, dark, false);
|
||||
}
|
||||
|
||||
private void updatePlayPauseColor() {
|
||||
//playPauseButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpPlayPauseButton() {
|
||||
playPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
playPauseButton.setImageDrawable(playPauseDrawable);
|
||||
updatePlayPauseColor();
|
||||
playPauseButton.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playPauseButton.post(() -> {
|
||||
if (playPauseButton != null) {
|
||||
playPauseButton.setPivotX(playPauseButton.getWidth() / 2);
|
||||
playPauseButton.setPivotY(playPauseButton.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseButton();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
//Ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
//Ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
|
||||
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(),
|
||||
MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void showBouceAnimation() {
|
||||
playPauseButton.clearAnimation();
|
||||
|
||||
playPauseButton.setScaleX(0.9f);
|
||||
playPauseButton.setScaleY(0.9f);
|
||||
playPauseButton.setVisibility(View.VISIBLE);
|
||||
playPauseButton.setPivotX(playPauseButton.getWidth() / 2);
|
||||
playPauseButton.setPivotY(playPauseButton.getHeight() / 2);
|
||||
|
||||
playPauseButton.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> playPauseButton.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_play_pause_button)
|
||||
void showAnimation() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
MusicPlayerRemote.pauseSong();
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying();
|
||||
}
|
||||
showBouceAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
}
|
||||
|
||||
public void hideVolumeIfAvailable() {
|
||||
volumeContainer.setVisibility(
|
||||
PreferenceUtil.getInstance(getContext()).getVolumeToggle() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,301 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.blur;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.AppCompatSeekBar;
|
||||
import android.support.v7.widget.AppCompatTextView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.VolumeFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
|
||||
|
||||
public class BlurPlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseFab;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
AppCompatSeekBar progressSlider;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView songTotalTime;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.title)
|
||||
AppCompatTextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View mVolumeContainer;
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_blur_playback_controls, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
setUpMusicControllers();
|
||||
|
||||
mVolumeContainer.setVisibility(PreferenceUtil.getInstance(getContext()).getVolumeToggle() ? View.VISIBLE : View.GONE);
|
||||
|
||||
VolumeFragment mVolumeFragment = (VolumeFragment) getChildFragmentManager().findFragmentById(R.id.volume_fragment);
|
||||
mVolumeFragment.tintWhiteColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
lastPlaybackControlsColor = Color.WHITE;
|
||||
lastDisabledPlaybackControlsColor = ContextCompat.getColor(getContext(), R.color.md_grey_500);
|
||||
|
||||
setProgressBarColor(Color.WHITE);
|
||||
|
||||
songCurrentProgress.setTextColor(lastPlaybackControlsColor);
|
||||
songTotalTime.setTextColor(lastPlaybackControlsColor);
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
}
|
||||
|
||||
public void setProgressBarColor(int newColor) {
|
||||
TintHelper.setTintAuto(progressSlider, newColor, false);
|
||||
}
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
final int fabColor = Color.WHITE;
|
||||
TintHelper.setTintAuto(playPauseFab, fabColor, true);
|
||||
|
||||
playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
|
||||
playPauseFab.setImageDrawable(playerFabPlayPauseDrawable); // Note: set the drawable AFTER TintHelper.setTintAuto() was called
|
||||
playPauseFab.setColorFilter(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(fabColor)), PorterDuff.Mode.SRC_IN);
|
||||
playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playPauseFab.post(() -> {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playerFabPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playerFabPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
playPauseFab.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setScaleX(0f);
|
||||
playPauseFab.setScaleY(0f);
|
||||
playPauseFab.setRotation(0f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(), MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
}
|
||||
|
||||
public void hideVolumeIfAvailable() {
|
||||
mVolumeContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,315 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.blur;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.PlayingQueueAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment;
|
||||
import jp.wasabeef.glide.transformations.BlurTransformation;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class BlurPlayerFragment extends AbsPlayerFragment implements PlayerAlbumCoverFragment.Callbacks {
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.toolbar_container)
|
||||
View toolbarContainer;
|
||||
@BindView(R.id.gradient_background)
|
||||
ImageView colorBackground;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
@Nullable
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
@Nullable
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
private int lastColor;
|
||||
private BlurPlaybackControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
|
||||
private RecyclerView.Adapter wrappedAdapter;
|
||||
private RecyclerViewDragDropManager recyclerViewDragDropManager;
|
||||
private PlayingQueueAdapter playingQueueAdapter;
|
||||
private LinearLayoutManager layoutManager;
|
||||
|
||||
public static PlayerFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlayerFragment fragment = new PlayerFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
playbackControlsFragment.setDark(color);
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
|
||||
if (title != null && playingQueueAdapter != null) {
|
||||
if (ColorUtil.isColorLight(color)) {
|
||||
title.setTextColor(Color.BLACK);
|
||||
playingQueueAdapter.usePalette(false);
|
||||
} else {
|
||||
title.setTextColor(Color.WHITE);
|
||||
playingQueueAdapter.usePalette(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if (recyclerViewDragDropManager != null) {
|
||||
recyclerViewDragDropManager.release();
|
||||
recyclerViewDragDropManager = null;
|
||||
}
|
||||
|
||||
if (recyclerView != null) {
|
||||
recyclerView.setItemAnimator(null);
|
||||
recyclerView.setAdapter(null);
|
||||
recyclerView = null;
|
||||
}
|
||||
|
||||
if (wrappedAdapter != null) {
|
||||
WrapperAdapterUtils.releaseAll(wrappedAdapter);
|
||||
wrappedAdapter = null;
|
||||
}
|
||||
playingQueueAdapter = null;
|
||||
layoutManager = null;
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_blur, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment = (BlurPlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment =
|
||||
(PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
}
|
||||
|
||||
private void updateBlur() {
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int blurAmount = PreferenceManager.getDefaultSharedPreferences(getContext()).getInt("blur_amount", 25);
|
||||
|
||||
colorBackground.clearColorFilter();
|
||||
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.getCurrentSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.override(320, 480)
|
||||
.transform(new BlurTransformation(getActivity(), blurAmount))
|
||||
.into(new RetroMusicColoredTarget(colorBackground) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
if (color == getDefaultFooterColor()) {
|
||||
colorBackground.setColorFilter(color);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
updateQueuePosition();
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
if (recyclerView != null) {
|
||||
recyclerViewDragDropManager = new RecyclerViewDragDropManager();
|
||||
final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
|
||||
|
||||
playingQueueAdapter = new PlayingQueueAdapter(
|
||||
(AppCompatActivity) getActivity(),
|
||||
MusicPlayerRemote.getPlayingQueue(),
|
||||
MusicPlayerRemote.getPosition(),
|
||||
R.layout.item_song,
|
||||
false,
|
||||
null);
|
||||
wrappedAdapter = recyclerViewDragDropManager.createWrappedAdapter(playingQueueAdapter);
|
||||
|
||||
layoutManager = new LinearLayoutManager(getContext());
|
||||
|
||||
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(wrappedAdapter);
|
||||
recyclerView.setItemAnimator(animator);
|
||||
recyclerViewDragDropManager.attachRecyclerView(recyclerView);
|
||||
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void updateCurrentSong() {
|
||||
}
|
||||
|
||||
private void updateQueuePosition() {
|
||||
if (playingQueueAdapter != null) {
|
||||
playingQueueAdapter.setCurrent(MusicPlayerRemote.getPosition());
|
||||
// if (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
resetToCurrentPosition();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateQueue() {
|
||||
if (playingQueueAdapter != null) {
|
||||
playingQueueAdapter.swapDataSet(MusicPlayerRemote.getPlayingQueue(), MusicPlayerRemote.getPosition());
|
||||
resetToCurrentPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetToCurrentPosition() {
|
||||
if (recyclerView != null) {
|
||||
recyclerView.stopScroll();
|
||||
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (recyclerViewDragDropManager != null) {
|
||||
recyclerViewDragDropManager.cancelDrag();
|
||||
}
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,283 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.card;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
|
||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.adapter.song.PlayingQueueAdapter;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment;
|
||||
|
||||
public class CardFragment extends AbsPlayerFragment implements PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
@Nullable
|
||||
@BindView(R.id.recycler_view)
|
||||
RecyclerView recyclerView;
|
||||
@Nullable
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
private RecyclerView.Adapter wrappedAdapter;
|
||||
private RecyclerViewDragDropManager recyclerViewDragDropManager;
|
||||
private PlayingQueueAdapter playingQueueAdapter;
|
||||
private LinearLayoutManager layoutManager;
|
||||
private int lastColor;
|
||||
private CardPlaybackControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
|
||||
public static PlayerFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlayerFragment fragment = new PlayerFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
playbackControlsFragment.setDark(color);
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
|
||||
if (title != null && playingQueueAdapter != null) {
|
||||
if (ColorUtil.isColorLight(color)) {
|
||||
title.setTextColor(Color.BLACK);
|
||||
playingQueueAdapter.usePalette(false);
|
||||
} else {
|
||||
title.setTextColor(Color.WHITE);
|
||||
playingQueueAdapter.usePalette(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if (recyclerViewDragDropManager != null) {
|
||||
recyclerViewDragDropManager.release();
|
||||
recyclerViewDragDropManager = null;
|
||||
}
|
||||
|
||||
if (recyclerView != null) {
|
||||
recyclerView.setItemAnimator(null);
|
||||
recyclerView.setAdapter(null);
|
||||
recyclerView = null;
|
||||
}
|
||||
|
||||
if (wrappedAdapter != null) {
|
||||
WrapperAdapterUtils.releaseAll(wrappedAdapter);
|
||||
wrappedAdapter = null;
|
||||
}
|
||||
playingQueueAdapter = null;
|
||||
layoutManager = null;
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_card_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment =
|
||||
(CardPlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment = (PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
playerAlbumCoverFragment.removeSlideEffect();
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
//updateLyrics();
|
||||
setUpRecyclerView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
//updateLyrics();
|
||||
updateQueuePosition();
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
if (recyclerView != null) {
|
||||
recyclerViewDragDropManager = new RecyclerViewDragDropManager();
|
||||
final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
|
||||
|
||||
playingQueueAdapter = new PlayingQueueAdapter(
|
||||
(AppCompatActivity) getActivity(),
|
||||
MusicPlayerRemote.getPlayingQueue(),
|
||||
MusicPlayerRemote.getPosition(),
|
||||
R.layout.item_song,
|
||||
false,
|
||||
null);
|
||||
wrappedAdapter = recyclerViewDragDropManager.createWrappedAdapter(playingQueueAdapter);
|
||||
|
||||
layoutManager = new LinearLayoutManager(getContext());
|
||||
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
recyclerView.setAdapter(wrappedAdapter);
|
||||
recyclerView.setItemAnimator(animator);
|
||||
recyclerViewDragDropManager.attachRecyclerView(recyclerView);
|
||||
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQueueChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoreChanged() {
|
||||
updateQueue();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void updateCurrentSong() {
|
||||
}
|
||||
|
||||
private void updateQueuePosition() {
|
||||
if (playingQueueAdapter != null) {
|
||||
playingQueueAdapter.setCurrent(MusicPlayerRemote.getPosition());
|
||||
}
|
||||
// if (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
resetToCurrentPosition();
|
||||
//}
|
||||
}
|
||||
|
||||
private void updateQueue() {
|
||||
if (playingQueueAdapter != null) {
|
||||
playingQueueAdapter.swapDataSet(MusicPlayerRemote.getPlayingQueue(),
|
||||
MusicPlayerRemote.getPosition());
|
||||
resetToCurrentPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetToCurrentPosition() {
|
||||
if (recyclerView != null) {
|
||||
recyclerView.stopScroll();
|
||||
layoutManager.scrollToPositionWithOffset(MusicPlayerRemote.getPosition() + 1, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (recyclerViewDragDropManager != null) {
|
||||
recyclerViewDragDropManager.cancelDrag();
|
||||
}
|
||||
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,358 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.card;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatSeekBar;
|
||||
import android.support.v7.widget.AppCompatTextView;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
|
||||
public class CardPlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseButton;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
AppCompatSeekBar progressSlider;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView songTotalTime;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.title)
|
||||
AppCompatTextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View volumeContainer;
|
||||
@BindView(R.id.menu)
|
||||
View menuView;
|
||||
@BindView(R.id.image_text_container)
|
||||
CardView colorContainer;
|
||||
|
||||
@BindView(R.id.image)
|
||||
ImageView playImageView;
|
||||
@BindView(R.id.playback_controls)
|
||||
View playbackControls;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable playPauseDrawable;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_card_player_playback_controls, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
setUpMusicControllers();
|
||||
|
||||
hideVolumeIfAvailable();
|
||||
|
||||
setupControls();
|
||||
}
|
||||
|
||||
private void setupControls() {
|
||||
playImageView.setImageResource(R.drawable.ic_play_circle_filled_white_24dp);
|
||||
//noinspection ConstantConditions
|
||||
int iconPadding = getActivity().getResources().getDimensionPixelSize(R.dimen.list_item_image_icon_padding);
|
||||
playImageView.setPadding(iconPadding, iconPadding, iconPadding, iconPadding);
|
||||
|
||||
menuView.setVisibility(View.GONE);
|
||||
|
||||
int primaryColor = ThemeStore.primaryColor(getContext());
|
||||
playbackControls.setBackgroundColor(primaryColor);
|
||||
colorContainer.setCardBackgroundColor(primaryColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(song.artistName);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
playImageView.setColorFilter(dark, PorterDuff.Mode.SRC_IN);
|
||||
if (ColorUtil.isColorLight(ATHUtil.resolveColor(getContext(), android.R.attr.windowBackground))) {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(getActivity(), true);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(getActivity(), true);
|
||||
} else {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(getActivity(), false);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
}
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
updatePlayPauseColor();
|
||||
updateProgressTextColor();
|
||||
|
||||
TintHelper.setTintAuto(playPauseButton, MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(dark)), false);
|
||||
TintHelper.setTintAuto(playPauseButton, dark, true);
|
||||
}
|
||||
|
||||
private void updatePlayPauseColor() {
|
||||
//playPauseButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpPlayPauseButton() {
|
||||
playPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
playPauseButton.setImageDrawable(playPauseDrawable);
|
||||
updatePlayPauseColor();
|
||||
playPauseButton.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playPauseButton.post(() -> {
|
||||
if (playPauseButton != null) {
|
||||
playPauseButton.setPivotX(playPauseButton.getWidth() / 2);
|
||||
playPauseButton.setPivotY(playPauseButton.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseButton();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProgressTextColor() {
|
||||
int color = MaterialValueHelper.getPrimaryTextColor(getContext(), false);
|
||||
songTotalTime.setTextColor(color);
|
||||
songCurrentProgress.setTextColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
//Ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
//Ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(), MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void showBouceAnimation() {
|
||||
playPauseButton.clearAnimation();
|
||||
|
||||
playPauseButton.setScaleX(0.9f);
|
||||
playPauseButton.setScaleY(0.9f);
|
||||
playPauseButton.setVisibility(View.VISIBLE);
|
||||
playPauseButton.setPivotX(playPauseButton.getWidth() / 2);
|
||||
playPauseButton.setPivotY(playPauseButton.getHeight() / 2);
|
||||
|
||||
playPauseButton.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> playPauseButton.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_play_pause_button)
|
||||
void showAnimation() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
MusicPlayerRemote.pauseSong();
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying();
|
||||
}
|
||||
showBouceAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
}
|
||||
|
||||
public void hideVolumeIfAvailable() {
|
||||
volumeContainer.setVisibility(PreferenceUtil.getInstance(getContext()).getVolumeToggle() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.cardblur;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment;
|
||||
import jp.wasabeef.glide.transformations.BlurTransformation;
|
||||
|
||||
public class CardBlurFragment extends AbsPlayerFragment implements PlayerAlbumCoverFragment.Callbacks {
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
@BindView(R.id.gradient_background)
|
||||
ImageView colorBackground;
|
||||
|
||||
private int lastColor;
|
||||
private CardBlurPlaybackControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
|
||||
public static PlayerFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlayerFragment fragment = new PlayerFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
playbackControlsFragment.setDark(color);
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_card_blur_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment = (CardBlurPlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment =
|
||||
(PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
playerAlbumCoverFragment.removeEffect();
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
/* for (int i = 0; i < toolbar.getMenu().size(); i++) {
|
||||
MenuItem menuItem = toolbar.getMenu().getItem(i);
|
||||
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||
}*/
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
updateBlur();
|
||||
}
|
||||
|
||||
private void updateBlur() {
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
int blurAmount = PreferenceManager.getDefaultSharedPreferences(getContext()).getInt("blur_amount", 25);
|
||||
|
||||
colorBackground.clearColorFilter();
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.getCurrentSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity)
|
||||
.build()
|
||||
.transform(new BlurTransformation(getActivity(), blurAmount))
|
||||
.into(new RetroMusicColoredTarget(colorBackground) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
if (color == getDefaultFooterColor()) {
|
||||
colorBackground.setColorFilter(color);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,335 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.cardblur;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatSeekBar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.VolumeFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
|
||||
public class CardBlurPlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseFab;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
AppCompatSeekBar progressSlider;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView songTotalTime;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View volumeContainer;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_card_blur_player_playback_controls, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
setUpMusicControllers();
|
||||
hideVolumeIfAvailable();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateSong();
|
||||
updateShuffleState();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
|
||||
title.setTextColor(Color.WHITE);
|
||||
text.setTextColor(Color.WHITE);
|
||||
|
||||
lastPlaybackControlsColor = Color.WHITE;
|
||||
lastDisabledPlaybackControlsColor = ColorUtil.withAlpha(Color.WHITE, 0.3f);
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
updateProgressTextColor();
|
||||
}
|
||||
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
final int fabColor = Color.WHITE;
|
||||
TintHelper.setTintAuto(playPauseFab, fabColor, true);
|
||||
|
||||
playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
|
||||
playPauseFab.setImageDrawable(playerFabPlayPauseDrawable); // Note: set the drawable AFTER TintHelper.setTintAuto() was called
|
||||
playPauseFab.setColorFilter(MaterialValueHelper.getPrimaryTextColor(getContext(),
|
||||
ColorUtil.isColorLight(fabColor)), PorterDuff.Mode.SRC_IN);
|
||||
playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playPauseFab.post(() -> {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playerFabPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playerFabPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
setupVolumeControls();
|
||||
}
|
||||
|
||||
private void setupVolumeControls() {
|
||||
VolumeFragment volumeFragment = (VolumeFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.volume_fragment);
|
||||
volumeFragment.tintWhiteColor();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProgressTextColor() {
|
||||
int color = MaterialValueHelper.getPrimaryTextColor(getContext(), false);
|
||||
songTotalTime.setTextColor(color);
|
||||
songCurrentProgress.setTextColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
//Ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
//Ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(), MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
progressSlider.setBackgroundTintList(ColorStateList.valueOf(Color.WHITE));
|
||||
}
|
||||
|
||||
public void showBouceAnimation() {
|
||||
playPauseFab.clearAnimation();
|
||||
|
||||
playPauseFab.setScaleX(0.9f);
|
||||
playPauseFab.setScaleY(0.9f);
|
||||
playPauseFab.setVisibility(View.VISIBLE);
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
|
||||
playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_play_pause_button)
|
||||
void showAnimation() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
MusicPlayerRemote.pauseSong();
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying();
|
||||
}
|
||||
showBouceAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
}
|
||||
|
||||
public void hideVolumeIfAvailable() {
|
||||
volumeContainer.setVisibility(PreferenceUtil.getInstance(getContext()).getVolumeToggle() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,305 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.color;
|
||||
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.graphics.Palette;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.animation.GlideAnimation;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
|
||||
import code.name.monkey.retromusic.glide.SongGlideRequest;
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.model.lyrics.Lyrics;
|
||||
import code.name.monkey.retromusic.ui.activities.LyricsActivity;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
||||
public class ColorFragment extends AbsPlayerFragment {
|
||||
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.gradient_background)
|
||||
View colorBackground;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
@BindView(R.id.image)
|
||||
ImageView imageView;
|
||||
@BindView(R.id.lyrics)
|
||||
TextView lyricsView;
|
||||
@BindView(R.id.lyrics_container)
|
||||
View lyricsViewContainer;
|
||||
@BindView(R.id.album_cover_container)
|
||||
View imageViewContainer;
|
||||
|
||||
private int lastColor;
|
||||
private int backgroundColor;
|
||||
private ColorPlaybackControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
private ValueAnimator valueAnimator;
|
||||
private AsyncTask updateLyricsAsyncTask;
|
||||
private Lyrics lyrics;
|
||||
|
||||
public static ColorFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
ColorFragment fragment = new ColorFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
if (valueAnimator != null) {
|
||||
valueAnimator.cancel();
|
||||
valueAnimator = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_color_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment = (ColorPlaybackControlsFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar,
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor), getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
updateLyricsLocal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
updateSong();
|
||||
updateLyricsLocal();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Activity activity = getActivity();
|
||||
|
||||
SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.getCurrentSong())
|
||||
.checkIgnoreMediaStore(activity)
|
||||
.generatePalette(activity).build().dontAnimate()
|
||||
.into(new RetroMusicColoredTarget(imageView) {
|
||||
@Override
|
||||
public void onColorReady(int color) {
|
||||
//setColors(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(Exception e, Drawable errorDrawable) {
|
||||
super.onLoadFailed(e, errorDrawable);
|
||||
|
||||
int backgroundColor = getDefaultFooterColor();
|
||||
int textColor = ColorUtil.isColorLight(getDefaultFooterColor()) ?
|
||||
MaterialValueHelper.getPrimaryTextColor(getContext(), true) :
|
||||
MaterialValueHelper.getPrimaryTextColor(getContext(), false);
|
||||
|
||||
setColors(backgroundColor, textColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(BitmapPaletteWrapper resource,
|
||||
GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
|
||||
super.onResourceReady(resource, glideAnimation);
|
||||
/* MediaNotificationProcessor processor = new MediaNotificationProcessor(getContext(),
|
||||
getContext());
|
||||
Palette.Builder builder = MediaNotificationProcessor
|
||||
.generatePalette(resource.getBitmap());
|
||||
|
||||
int backgroundColor = processor.getBackgroundColor(builder);
|
||||
int textColor = processor.getTextColor(builder);*/
|
||||
|
||||
Palette palette = resource.getPalette();
|
||||
Palette.Swatch swatch = RetroColorUtil.getSwatch(palette);
|
||||
|
||||
int textColor = RetroColorUtil.getTextColor(palette);
|
||||
int backgroundColor = swatch.getRgb();
|
||||
|
||||
setColors(backgroundColor, textColor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setColors(int backgroundColor, int textColor) {
|
||||
playbackControlsFragment.setDark(textColor, backgroundColor);
|
||||
|
||||
colorBackground.setBackgroundColor(backgroundColor);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, textColor, getActivity());
|
||||
|
||||
lastColor = textColor;
|
||||
|
||||
this.backgroundColor = backgroundColor;
|
||||
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
}
|
||||
|
||||
private void colorize(int i) {
|
||||
if (valueAnimator != null) {
|
||||
valueAnimator.cancel();
|
||||
}
|
||||
|
||||
valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), Color.TRANSPARENT, i);
|
||||
valueAnimator.addUpdateListener(animation -> {
|
||||
if (colorBackground != null) {
|
||||
colorBackground.setBackgroundColor((Integer) animation.getAnimatedValue());
|
||||
}
|
||||
});
|
||||
valueAnimator.setDuration(ViewUtil.RETRO_MUSIC_ANIM_TIME).start();
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private void updateLyricsLocal() {
|
||||
if (updateLyricsAsyncTask != null) {
|
||||
updateLyricsAsyncTask.cancel(false);
|
||||
}
|
||||
final Song song = MusicPlayerRemote.getCurrentSong();
|
||||
updateLyricsAsyncTask = new AsyncTask<Void, Void, Lyrics>() {
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
lyrics = null;
|
||||
toolbar.getMenu().removeItem(R.id.action_show_lyrics);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Lyrics doInBackground(Void... params) {
|
||||
String data = MusicUtil.getLyrics(song);
|
||||
if (TextUtils.isEmpty(data)) {
|
||||
return null;
|
||||
}
|
||||
return Lyrics.parse(song, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Lyrics l) {
|
||||
lyrics = l;
|
||||
if (lyrics == null) {
|
||||
lyricsView.setText(R.string.no_lyrics_found);
|
||||
} else {
|
||||
lyricsView.setText(lyrics.getText());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled(Lyrics s) {
|
||||
onPostExecute(null);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@OnClick(R.id.expand)
|
||||
void expand() {
|
||||
startActivity(new Intent(getContext(), LyricsActivity.class));
|
||||
}
|
||||
|
||||
@OnClick({R.id.lyrics, R.id.image})
|
||||
void toggleLyrics(View view) {
|
||||
if (lyricsViewContainer.getVisibility() == View.GONE) {
|
||||
lyricsViewContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
lyricsViewContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,348 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.color;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatSeekBar;
|
||||
import android.support.v7.widget.AppCompatTextView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.VolumeFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
|
||||
public class ColorPlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseFab;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
AppCompatSeekBar progressSlider;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView songTotalTime;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.title)
|
||||
AppCompatTextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View volumeContainer;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
private VolumeFragment volumeFragment;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_color_player_playback_controls, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
setUpMusicControllers();
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getVolumeToggle()) {
|
||||
volumeContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
volumeContainer.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
volumeFragment = (VolumeFragment) getChildFragmentManager().findFragmentById(R.id.volume_fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(song.artistName);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
|
||||
public void setDark(int textColor, int background) {
|
||||
setDark(textColor);
|
||||
TintHelper.setTintAuto(playPauseFab, background, false);
|
||||
TintHelper.setTintAuto(playPauseFab, textColor, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int color) {
|
||||
lastPlaybackControlsColor = color;
|
||||
lastDisabledPlaybackControlsColor = ColorUtil.withAlpha(color, 0.5f);
|
||||
|
||||
title.setTextColor(lastPlaybackControlsColor);
|
||||
text.setTextColor(lastDisabledPlaybackControlsColor);
|
||||
|
||||
TintHelper.setTintAuto(progressSlider, lastPlaybackControlsColor, false);
|
||||
|
||||
volumeFragment.setTintable(lastPlaybackControlsColor);
|
||||
|
||||
songCurrentProgress.setTextColor(lastDisabledPlaybackControlsColor);
|
||||
songTotalTime.setTextColor(lastDisabledPlaybackControlsColor);
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
}
|
||||
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
|
||||
playPauseFab.setImageDrawable(playerFabPlayPauseDrawable); // Note: set the drawable AFTER TintHelper.setTintAuto() was called
|
||||
playPauseFab.setColorFilter(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(Color.BLACK)), PorterDuff.Mode.SRC_IN);
|
||||
//playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playPauseFab.post(() -> {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playerFabPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playerFabPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
playPauseFab.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setScaleX(0f);
|
||||
playPauseFab.setScaleY(0f);
|
||||
playPauseFab.setRotation(0f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(), MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void showBouceAnimation() {
|
||||
playPauseFab.clearAnimation();
|
||||
|
||||
playPauseFab.setScaleX(0.9f);
|
||||
playPauseFab.setScaleY(0.9f);
|
||||
playPauseFab.setVisibility(View.VISIBLE);
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
|
||||
playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_play_pause_button)
|
||||
void showAnimation() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
MusicPlayerRemote.pauseSong();
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying();
|
||||
}
|
||||
showBouceAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
}
|
||||
|
||||
public void hideVolumeIfAvailable() {
|
||||
volumeContainer.setVisibility(PreferenceUtil.getInstance(getContext()).getVolumeToggle() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,300 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.flat;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ClipDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback;
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsMusicServiceFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
|
||||
public class FlatPlaybackControlsFragment extends AbsMusicServiceFragment implements Callback {
|
||||
|
||||
@BindView(R.id.text)
|
||||
TextView mText;
|
||||
@BindView(R.id.title)
|
||||
TextView mTitle;
|
||||
@BindView(R.id.playback_controls)
|
||||
ViewGroup viewGroup;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView mSongTotalTime;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView mPlayerSongCurrentProgress;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton mPlayerRepeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton mPlayerShuffleButton;
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageView mPlayerPlayPauseFab;
|
||||
Unbinder unbinder;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
SeekBar progressSlider;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View mVolumeContainer;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_flat_player_playback_controls, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setUpMusicControllers();
|
||||
|
||||
mVolumeContainer.setVisibility(PreferenceUtil.getInstance(getContext()).getVolumeToggle() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
mPlayerSongCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
mSongTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
}
|
||||
|
||||
|
||||
public void show() {
|
||||
mPlayerPlayPauseFab.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
|
||||
public void hide() {
|
||||
if (mPlayerPlayPauseFab != null) {
|
||||
mPlayerPlayPauseFab.setScaleX(0f);
|
||||
mPlayerPlayPauseFab.setScaleY(0f);
|
||||
mPlayerPlayPauseFab.setRotation(0f);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDark(int dark) {
|
||||
int color = ATHUtil.resolveColor(getActivity(), android.R.attr.colorBackground);
|
||||
boolean isDark = ColorUtil.isColorLight(color);
|
||||
if (isDark) {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(getActivity(), true);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(getActivity(), true);
|
||||
} else {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(getActivity(), false);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
}
|
||||
int accentColor = ThemeStore.accentColor(getContext());
|
||||
boolean b = PreferenceUtil.getInstance(getContext()).getAdaptiveColor();
|
||||
updateTextColors(b ? dark : accentColor);
|
||||
setProgressBarColor(b ? dark : accentColor);
|
||||
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
private void setProgressBarColor(int dark) {
|
||||
TintHelper.setTintAuto(progressSlider, dark, false);
|
||||
//LayerDrawable ld = (LayerDrawable) progressSlider.getProgressDrawable();
|
||||
//ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress);
|
||||
//clipDrawable.setColorFilter(dark, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void updateTextColors(int color) {
|
||||
boolean isDark = ColorUtil.isColorLight(color);
|
||||
int darkColor = ColorUtil.darkenColor(color);
|
||||
int colorPrimary = MaterialValueHelper.getPrimaryTextColor(getContext(), isDark);
|
||||
int colorSecondary = MaterialValueHelper.getSecondaryTextColor(getContext(), ColorUtil.isColorLight(darkColor));
|
||||
|
||||
TintHelper.setTintAuto(mPlayerPlayPauseFab, colorPrimary, false);
|
||||
TintHelper.setTintAuto(mPlayerPlayPauseFab, color, true);
|
||||
|
||||
mTitle.setBackgroundColor(color);
|
||||
mTitle.setTextColor(colorPrimary);
|
||||
mText.setBackgroundColor(darkColor);
|
||||
mText.setTextColor(colorSecondary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playerFabPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playerFabPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
|
||||
mPlayerPlayPauseFab.setImageDrawable(
|
||||
playerFabPlayPauseDrawable); // Note: set the drawable AFTER TintHelper.setTintAuto() was called
|
||||
//playPauseFab.setColorFilter(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(fabColor)), PorterDuff.Mode.SRC_IN);
|
||||
mPlayerPlayPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
mPlayerPlayPauseFab.post(() -> {
|
||||
if (mPlayerPlayPauseFab != null) {
|
||||
mPlayerPlayPauseFab.setPivotX(mPlayerPlayPauseFab.getWidth() / 2);
|
||||
mPlayerPlayPauseFab.setPivotY(mPlayerPlayPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
//TransitionManager.beginDelayedTransition(viewGroup, new ChangeText().setChangeBehavior(ChangeText.CHANGE_BEHAVIOR_OUT_IN));
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
mTitle.setText(song.title);
|
||||
mText.setText(song.artistName);
|
||||
|
||||
}
|
||||
|
||||
private void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(),
|
||||
MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
mPlayerRepeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
private void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
mPlayerRepeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
mPlayerRepeatButton
|
||||
.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
mPlayerRepeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
mPlayerRepeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
mPlayerRepeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
mPlayerRepeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
mPlayerShuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
private void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
mPlayerShuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
mPlayerShuffleButton
|
||||
.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.flat;
|
||||
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
import code.name.monkey.retromusic.views.DrawableGradient;
|
||||
|
||||
public class FlatPlayerFragment extends AbsPlayerFragment implements
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.gradient_background)
|
||||
View colorBackground;
|
||||
@BindView(R.id.toolbar_container)
|
||||
FrameLayout toolbarContainer;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private ValueAnimator valueAnimator;
|
||||
private FlatPlaybackControlsFragment flatPlaybackControlsFragment;
|
||||
private int lastColor;
|
||||
|
||||
private void setUpSubFragments() {
|
||||
flatPlaybackControlsFragment = (FlatPlaybackControlsFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment = (PlayerAlbumCoverFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, ATHUtil.resolveColor(getContext(),
|
||||
R.attr.iconColor), getActivity());
|
||||
}
|
||||
|
||||
private void colorize(int i) {
|
||||
if (valueAnimator != null) {
|
||||
valueAnimator.cancel();
|
||||
}
|
||||
|
||||
valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), android.R.color.transparent, i);
|
||||
valueAnimator.addUpdateListener(animation -> {
|
||||
GradientDrawable drawable = new DrawableGradient(GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
new int[]{(int) animation.getAnimatedValue(), android.R.color.transparent}, 0);
|
||||
if (colorBackground != null) {
|
||||
colorBackground.setBackground(drawable);
|
||||
}
|
||||
});
|
||||
valueAnimator.setDuration(ViewUtil.RETRO_MUSIC_ANIM_TIME).start();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_flat_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpPlayerToolbar();
|
||||
setUpSubFragments();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
flatPlaybackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
flatPlaybackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
boolean isLight = ColorUtil.isColorLight(lastColor);
|
||||
return PreferenceUtil.getInstance(getContext()).getAdaptiveColor() ?
|
||||
MaterialValueHelper.getPrimaryTextColor(getContext(), isLight) :
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
lastColor = color;
|
||||
flatPlaybackControlsFragment.setDark(color);
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
|
||||
boolean isLight = ColorUtil.isColorLight(color);
|
||||
|
||||
//TransitionManager.beginDelayedTransition(mToolbar);
|
||||
int iconColor = PreferenceUtil.getInstance(getContext()).getAdaptiveColor() ?
|
||||
MaterialValueHelper.getPrimaryTextColor(getContext(), isLight) :
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, iconColor, getActivity());
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
colorize(color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,301 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.full;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ClipDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.VolumeFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/09/17.
|
||||
*/
|
||||
|
||||
public class FullPlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView mPlayerSongCurrentProgress;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView songTotalTime;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
SeekBar progressSlider;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton playerPrevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton playerNextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton playerRepeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton playerShuffleButton;
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playerPlayPauseFab;
|
||||
Unbinder unbinder;
|
||||
@BindView(R.id.title)
|
||||
TextView mTitle;
|
||||
@BindView(R.id.text)
|
||||
TextView mText;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View mVolumeContainer;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_full_player_controls, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
setUpMusicControllers();
|
||||
|
||||
mVolumeContainer.setVisibility(PreferenceUtil.getInstance(getContext()).getVolumeToggle() ? View.VISIBLE : View.GONE);
|
||||
VolumeFragment volumeFragment = (VolumeFragment) getChildFragmentManager().findFragmentById(R.id.volume_fragment);
|
||||
volumeFragment.tintWhiteColor();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
mPlayerSongCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
}
|
||||
|
||||
|
||||
public void show() {
|
||||
playerPlayPauseFab.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
|
||||
public void hide() {
|
||||
if (playerPlayPauseFab != null) {
|
||||
playerPlayPauseFab.setScaleX(0f);
|
||||
playerPlayPauseFab.setScaleY(0f);
|
||||
playerPlayPauseFab.setRotation(0f);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDark(int dark) {
|
||||
lastPlaybackControlsColor = Color.WHITE;
|
||||
lastDisabledPlaybackControlsColor = ContextCompat.getColor(getContext(), R.color.md_grey_500);
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
setProgressBarColor(dark);
|
||||
} else {
|
||||
int accentColor = ThemeStore.accentColor(getContext());
|
||||
setProgressBarColor(accentColor);
|
||||
}
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
updateProgressTextColor();
|
||||
}
|
||||
|
||||
private void setProgressBarColor(int dark) {
|
||||
LayerDrawable ld = (LayerDrawable) progressSlider.getProgressDrawable();
|
||||
ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress);
|
||||
clipDrawable.setColorFilter(dark, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
mTitle.setText(song.title);
|
||||
mText.setText(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playerPlayPauseFab.setImageResource(R.drawable.ic_pause_white_24dp);
|
||||
} else {
|
||||
playerPlayPauseFab.setImageResource(R.drawable.ic_play_arrow_white_24dp);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
|
||||
playerPlayPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playerPlayPauseFab.post(() -> {
|
||||
if (playerPlayPauseFab != null) {
|
||||
playerPlayPauseFab.setPivotX(playerPlayPauseFab.getWidth() / 2);
|
||||
playerPlayPauseFab.setPivotY(playerPlayPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
playerNextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
playerPrevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updateProgressTextColor() {
|
||||
int color = MaterialValueHelper.getSecondaryTextColor(getContext(), false);
|
||||
//songTotalTime.setTextColor(color);
|
||||
//songCurrentProgress.setTextColor(color);
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
playerNextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
playerPrevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(), MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
playerRepeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
playerRepeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
playerRepeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
playerRepeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
playerRepeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
playerRepeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
playerRepeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
playerShuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
playerShuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
playerShuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.full;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
|
||||
public class FullPlayerFragment extends AbsPlayerFragment implements PlayerAlbumCoverFragment.Callbacks {
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
Unbinder unbinder;
|
||||
|
||||
private int lastColor;
|
||||
private FullPlaybackControlsFragment fullPlaybackControlsFragment;
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationIcon(R.drawable.ic_close_white_24dp);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_full, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
fullPlaybackControlsFragment = (FullPlaybackControlsFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment = (PlayerAlbumCoverFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
playerAlbumCoverFragment.removeSlideEffect();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
lastColor = color;
|
||||
fullPlaybackControlsFragment.setDark(color);
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, Color.WHITE, getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.hmm;
|
||||
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class HmmPlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
private Unbinder unbinder;
|
||||
private int mLastPlaybackControlsColor;
|
||||
private int mLastDisabledPlaybackControlsColor;
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_hmm_controls_fragment, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setUpMusicControllers();
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(mLastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(mLastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(mLastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(mLastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(mLastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
if (ColorUtil.isColorLight(dark)) {
|
||||
mLastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(getActivity(), true);
|
||||
mLastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(getActivity(), true);
|
||||
} else {
|
||||
mLastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(getActivity(), false);
|
||||
mLastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
}
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.hmm;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.materialdialogs.internal.MDTintHelper;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.fragments.MiniPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class HmmPlayerFragment extends AbsPlayerFragment implements
|
||||
MusicProgressViewUpdateHelper.Callback, PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView totalTime;
|
||||
@BindView(R.id.progress_bar)
|
||||
ProgressBar progressBar;
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
private Unbinder unBinder;
|
||||
private int lastColor;
|
||||
private HmmPlaybackControlsFragment hmmPlaybackControlsFragment;
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(String.format("%s \nby -%s", song.albumName, song.artistName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unBinder.unbind();
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_hmm_player, container, false);
|
||||
unBinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
progressBar.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
progressBar.setOnTouchListener(new MiniPlayerFragment.FlingPlayBackController(getActivity()));
|
||||
|
||||
setUpPlayerToolbar();
|
||||
setUpSubFragments();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
hmmPlaybackControlsFragment = (HmmPlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment = (PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
hmmPlaybackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
hmmPlaybackControlsFragment.hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return MaterialValueHelper
|
||||
.getSecondaryTextColor(getContext(), ColorUtil.isColorLight(lastColor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressBar.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressBar, "progress", progress);
|
||||
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
animatorSet.playSequentially(animator);
|
||||
|
||||
animatorSet.setDuration(1500);
|
||||
animatorSet.setInterpolator(new LinearInterpolator());
|
||||
animatorSet.start();
|
||||
|
||||
totalTime.setText(String.format("%s/%s", MusicUtil.getReadableDurationString(total),
|
||||
MusicUtil.getReadableDurationString(progress)));
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
lastColor = PreferenceUtil.getInstance(getContext()).getAdaptiveColor() ? color :
|
||||
ThemeStore.accentColor(getContext());
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
hmmPlaybackControlsFragment.setDark(lastColor);
|
||||
setProgressBarColor(lastColor);
|
||||
|
||||
int iconColor = MaterialValueHelper
|
||||
.getSecondaryTextColor(getContext(), ColorUtil.isColorLight(lastColor));
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar, iconColor, getActivity());
|
||||
}
|
||||
|
||||
private void setProgressBarColor(int color) {
|
||||
MDTintHelper.setTint(progressBar, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,294 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.lockscreen;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatImageButton;
|
||||
import android.support.v7.widget.AppCompatSeekBar;
|
||||
import android.support.v7.widget.AppCompatTextView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.fragments.VolumeFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
public class LockScreenPlayerControlsFragment extends AbsPlayerControlsFragment {
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
AppCompatImageButton playPauseFab;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
AppCompatSeekBar progressSlider;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView songTotalTime;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.title)
|
||||
AppCompatTextView title;
|
||||
@BindView(R.id.text)
|
||||
AppCompatTextView text;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
private int lastPlaybackControlsColor;
|
||||
|
||||
public LockScreenPlayerControlsFragment() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_lock_screen_playback_controls, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setUpMusicControllers();
|
||||
|
||||
VolumeFragment volumeFragment = (VolumeFragment) getChildFragmentManager().findFragmentById(R.id.volume_fragment);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
|
||||
title.setText(song.title);
|
||||
text.setText(String.format("%s - %s", song.artistName, song.albumName));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
setProgressBarColor(progressSlider, dark);
|
||||
|
||||
if (ColorUtil.isColorLight(ATHUtil.resolveColor(getContext(), android.R.attr.windowBackground))) {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(getActivity(), true);
|
||||
} else {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(getActivity(), false);
|
||||
|
||||
}
|
||||
|
||||
updatePrevNextColor();
|
||||
|
||||
boolean isDark = ColorUtil.isColorLight(dark);
|
||||
text.setTextColor(dark);
|
||||
TintHelper.setTintAuto(playPauseFab, MaterialValueHelper.getPrimaryTextColor(getContext(), isDark), false);
|
||||
TintHelper.setTintAuto(playPauseFab, dark, true);
|
||||
}
|
||||
|
||||
public void setProgressBarColor(SeekBar progressBar, int newColor) {
|
||||
TintHelper.setTintAuto(progressBar, newColor, false);
|
||||
//LayerDrawable ld = (LayerDrawable) progressBar.getProgressDrawable();
|
||||
//ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress);
|
||||
//clipDrawable.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
playPauseFab.post(() -> {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
playPauseFab.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setScaleX(0f);
|
||||
playPauseFab.setScaleY(0f);
|
||||
playPauseFab.setRotation(0f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
//TODO(Nothing to Implement)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
//TODO(Nothing to Implement)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(),
|
||||
MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void showBouceAnimation() {
|
||||
playPauseFab.clearAnimation();
|
||||
|
||||
playPauseFab.setScaleX(0.9f);
|
||||
playPauseFab.setScaleY(0.9f);
|
||||
playPauseFab.setVisibility(View.VISIBLE);
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
|
||||
playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playPauseFab.setImageResource(R.drawable.ic_pause_white_24dp);
|
||||
} else {
|
||||
playPauseFab.setImageResource(R.drawable.ic_play_arrow_white_24dp);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_play_pause_button)
|
||||
void showAnimation() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
MusicPlayerRemote.pauseSong();
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying();
|
||||
}
|
||||
showBouceAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,273 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.material;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatSeekBar;
|
||||
import android.support.v7.widget.AppCompatTextView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
public class MaterialControlsFragment extends AbsPlayerControlsFragment {
|
||||
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseFab;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
AppCompatSeekBar progressSlider;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView songTotalTime;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.title)
|
||||
AppCompatTextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View mVolumeContainer;
|
||||
private Unbinder unbinder;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_material_playback_controls, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
setUpMusicControllers();
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getVolumeToggle()) {
|
||||
mVolumeContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mVolumeContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState();
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
int color = ATHUtil.resolveColor(getActivity(), android.R.attr.colorBackground);
|
||||
if (ColorUtil.isColorLight(color)) {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(getActivity(), true);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(getActivity(), true);
|
||||
} else {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(getActivity(), false);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
}
|
||||
|
||||
updatePlayPauseColor();
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
}
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playPauseFab.setImageResource(R.drawable.ic_pause_white_big);
|
||||
} else {
|
||||
playPauseFab.setImageResource(R.drawable.ic_play_arrow_white_big);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void updatePlayPauseColor() {
|
||||
playPauseFab.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(),
|
||||
MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.material;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
public class MaterialFragment extends AbsPlayerFragment implements PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
private int lastColor;
|
||||
private MaterialControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
|
||||
public static PlayerFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlayerFragment fragment = new PlayerFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
playbackControlsFragment.setDark(color);
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar,
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor), getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_material, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment = (MaterialControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment =
|
||||
(PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar,
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor), getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.normal;
|
||||
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
import code.name.monkey.retromusic.views.DrawableGradient;
|
||||
|
||||
|
||||
public class PlayerFragment extends AbsPlayerFragment implements PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.gradient_background)
|
||||
View colorBackground;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
private int lastColor;
|
||||
private PlayerPlaybackControlsFragment playbackControlsFragment;
|
||||
private Unbinder unbinder;
|
||||
private ValueAnimator valueAnimator;
|
||||
|
||||
public static PlayerFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
PlayerFragment fragment = new PlayerFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
|
||||
private void colorize(int i) {
|
||||
if (valueAnimator != null) {
|
||||
valueAnimator.cancel();
|
||||
}
|
||||
|
||||
valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), android.R.color.transparent, i);
|
||||
valueAnimator.addUpdateListener(animation -> {
|
||||
GradientDrawable drawable = new DrawableGradient(GradientDrawable.Orientation.TOP_BOTTOM,
|
||||
new int[]{(int) animation.getAnimatedValue(), android.R.color.transparent}, 0);
|
||||
if (colorBackground != null) {
|
||||
colorBackground.setBackground(drawable);
|
||||
}
|
||||
});
|
||||
valueAnimator.setDuration(ViewUtil.RETRO_MUSIC_ANIM_TIME).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ColorInt
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
playbackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
playbackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
playbackControlsFragment.setDark(color);
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar,
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor), getActivity());
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
colorize(color);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
playbackControlsFragment = (PlayerPlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment =
|
||||
(PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar,
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor), getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateIsFavorite();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,345 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.normal;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ClipDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.AppCompatSeekBar;
|
||||
import android.support.v7.widget.AppCompatTextView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
|
||||
public class PlayerPlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseFab;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
AppCompatSeekBar progressSlider;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView songTotalTime;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.title)
|
||||
AppCompatTextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View mVolumeContainer;
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_player_playback_controls, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
setUpMusicControllers();
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getVolumeToggle()) {
|
||||
mVolumeContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mVolumeContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
int color = ATHUtil.resolveColor(getActivity(), android.R.attr.colorBackground);
|
||||
if (ColorUtil.isColorLight(color)) {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(getActivity(), true);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(getActivity(), true);
|
||||
} else {
|
||||
lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(getActivity(), false);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
}
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
setFabColor(dark);
|
||||
} else {
|
||||
setFabColor(ThemeStore.accentColor(getContext()));
|
||||
}
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
}
|
||||
|
||||
private void setFabColor(int i) {
|
||||
TintHelper.setTintAuto(playPauseFab, MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(i)), false);
|
||||
TintHelper.setTintAuto(playPauseFab, i, true);
|
||||
setProgressBarColor(i);
|
||||
}
|
||||
|
||||
public void setProgressBarColor(int newColor) {
|
||||
LayerDrawable ld = (LayerDrawable) progressSlider.getProgressDrawable();
|
||||
ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress);
|
||||
clipDrawable.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
|
||||
playPauseFab.setImageDrawable(
|
||||
playerFabPlayPauseDrawable); // Note: set the drawable AFTER TintHelper.setTintAuto() was called
|
||||
//playPauseFab.setColorFilter(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(fabColor)), PorterDuff.Mode.SRC_IN);
|
||||
//playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playPauseFab.post(() -> {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playerFabPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playerFabPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
playPauseFab.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setScaleX(0f);
|
||||
playPauseFab.setScaleY(0f);
|
||||
playPauseFab.setRotation(0f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(),
|
||||
MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void showBouceAnimation() {
|
||||
playPauseFab.clearAnimation();
|
||||
|
||||
playPauseFab.setScaleX(0.9f);
|
||||
playPauseFab.setScaleY(0.9f);
|
||||
playPauseFab.setVisibility(View.VISIBLE);
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
|
||||
playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_play_pause_button)
|
||||
void showAnimation() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
MusicPlayerRemote.pauseSong();
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying();
|
||||
}
|
||||
showBouceAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,324 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.plain;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ClipDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class PlainPlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseFab;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_progress_slider)
|
||||
SeekBar progressSlider;
|
||||
@BindView(R.id.player_song_total_time)
|
||||
TextView songTotalTime;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View volumeContainer;
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_plain_controls_fragment, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setUpMusicControllers();
|
||||
if (PreferenceUtil.getInstance(getContext()).getVolumeToggle()) {
|
||||
volumeContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
volumeContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
playPauseFab.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setScaleX(0f);
|
||||
playPauseFab.setScaleY(0f);
|
||||
playPauseFab.setRotation(0f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
MusicPlayerRemote.seekTo(progress);
|
||||
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(), MusicPlayerRemote.getSongDurationMillis());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void showBouceAnimation() {
|
||||
playPauseFab.clearAnimation();
|
||||
|
||||
playPauseFab.setScaleX(0.9f);
|
||||
playPauseFab.setScaleY(0.9f);
|
||||
playPauseFab.setVisibility(View.VISIBLE);
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
|
||||
playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_play_pause_button)
|
||||
void showAnimation() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
MusicPlayerRemote.pauseSong();
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying();
|
||||
}
|
||||
showBouceAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
progressSlider.setMax(total);
|
||||
|
||||
ObjectAnimator animator = ObjectAnimator.ofInt(progressSlider, "progress", progress);
|
||||
animator.setDuration(1500);
|
||||
animator.setInterpolator(new LinearInterpolator());
|
||||
animator.start();
|
||||
|
||||
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
int color = ATHUtil.resolveColor(getActivity(), android.R.attr.colorBackground);
|
||||
if (ColorUtil.isColorLight(color)) {
|
||||
lastPlaybackControlsColor =
|
||||
MaterialValueHelper.getSecondaryTextColor(getActivity(), true);
|
||||
lastDisabledPlaybackControlsColor =
|
||||
MaterialValueHelper.getSecondaryDisabledTextColor(getActivity(), true);
|
||||
} else {
|
||||
lastPlaybackControlsColor =
|
||||
MaterialValueHelper.getPrimaryTextColor(getActivity(), false);
|
||||
lastDisabledPlaybackControlsColor =
|
||||
MaterialValueHelper.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
}
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
TintHelper.setTintAuto(playPauseFab, MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(dark)), false);
|
||||
TintHelper.setTintAuto(playPauseFab, dark, true);
|
||||
setProgressBarColor(progressSlider, dark);
|
||||
}
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
}
|
||||
|
||||
public void setProgressBarColor(SeekBar progressBar, int newColor) {
|
||||
LayerDrawable ld = (LayerDrawable) progressBar.getProgressDrawable();
|
||||
ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress);
|
||||
clipDrawable.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
|
||||
playPauseFab.setImageDrawable(playerFabPlayPauseDrawable); // Note: set the drawable AFTER TintHelper.setTintAuto() was called
|
||||
//playPauseFab.setColorFilter(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(fabColor)), PorterDuff.Mode.SRC_IN);
|
||||
//playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playPauseFab.post(() -> {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playerFabPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playerFabPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.plain;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class PlainPlayerFragment extends AbsPlayerFragment implements
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.toolbar_container)
|
||||
FrameLayout toolbarContainer;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
|
||||
private Unbinder unbinder;
|
||||
private PlainPlaybackControlsFragment plainPlaybackControlsFragment;
|
||||
private int mLastColor;
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
super.onServiceConnected();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_plain_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar,
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor),
|
||||
getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
title.setSelected(true);
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
plainPlaybackControlsFragment = (PlainPlaybackControlsFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.playback_controls_fragment);
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment = (PlayerAlbumCoverFragment) getChildFragmentManager()
|
||||
.findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPaletteColor() {
|
||||
return mLastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
plainPlaybackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
plainPlaybackControlsFragment.hide();
|
||||
onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
plainPlaybackControlsFragment.setDark(color);
|
||||
mLastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar,
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor), getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.simple;
|
||||
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ClipDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper;
|
||||
import code.name.monkey.appthemehelper.util.TintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.PlayPauseDrawable;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class SimplePlaybackControlsFragment extends AbsPlayerControlsFragment {
|
||||
@BindView(R.id.player_play_pause_button)
|
||||
ImageButton playPauseFab;
|
||||
@BindView(R.id.player_prev_button)
|
||||
ImageButton prevButton;
|
||||
@BindView(R.id.player_next_button)
|
||||
ImageButton nextButton;
|
||||
@BindView(R.id.player_repeat_button)
|
||||
ImageButton repeatButton;
|
||||
@BindView(R.id.player_shuffle_button)
|
||||
ImageButton shuffleButton;
|
||||
@BindView(R.id.player_song_current_progress)
|
||||
TextView songCurrentProgress;
|
||||
@BindView(R.id.volume_fragment_container)
|
||||
View volumeContainer;
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.text)
|
||||
TextView text;
|
||||
private Unbinder unbinder;
|
||||
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
||||
private int lastPlaybackControlsColor;
|
||||
private int lastDisabledPlaybackControlsColor;
|
||||
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||
|
||||
|
||||
@Override
|
||||
public void onPlayStateChanged() {
|
||||
updatePlayPauseDrawableState(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRepeatModeChanged() {
|
||||
updateRepeatState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShuffleModeChanged() {
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updatePlayPauseDrawableState(false);
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updateSong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_simple_controls_fragment, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
progressViewUpdateHelper.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
progressViewUpdateHelper.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setUpMusicControllers();
|
||||
volumeContainer.setVisibility(PreferenceUtil.getInstance(getContext()).getVolumeToggle() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPlayPauseFab();
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
updatePrevNextColor();
|
||||
nextButton.setOnClickListener(v -> MusicPlayerRemote.playNextSong());
|
||||
prevButton.setOnClickListener(v -> MusicPlayerRemote.back());
|
||||
}
|
||||
|
||||
private void updatePrevNextColor() {
|
||||
nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
prevButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
shuffleButton.setOnClickListener(v -> MusicPlayerRemote.toggleShuffleMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateShuffleState() {
|
||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
repeatButton.setOnClickListener(v -> MusicPlayerRemote.cycleRepeatMode());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateRepeatState() {
|
||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_THIS:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp);
|
||||
repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSong() {
|
||||
Song song = MusicPlayerRemote.getCurrentSong();
|
||||
title.setText(song.title);
|
||||
text.setText(song.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged();
|
||||
updateSong();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpProgressSlider() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void show() {
|
||||
playPauseFab.animate()
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.rotation(360f)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void hide() {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setScaleX(0f);
|
||||
playPauseFab.setScaleY(0f);
|
||||
playPauseFab.setRotation(0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void showBouceAnimation() {
|
||||
playPauseFab.clearAnimation();
|
||||
|
||||
playPauseFab.setScaleX(0.9f);
|
||||
playPauseFab.setScaleY(0.9f);
|
||||
playPauseFab.setVisibility(View.VISIBLE);
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
|
||||
playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new DecelerateInterpolator())
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.withEndAction(() -> playPauseFab.animate()
|
||||
.setDuration(200)
|
||||
.setInterpolator(new AccelerateInterpolator())
|
||||
.scaleX(1f)
|
||||
.scaleY(1f)
|
||||
.alpha(1f)
|
||||
.start())
|
||||
.start();
|
||||
}
|
||||
|
||||
@OnClick(R.id.player_play_pause_button)
|
||||
void showAnimation() {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
MusicPlayerRemote.pauseSong();
|
||||
} else {
|
||||
MusicPlayerRemote.resumePlaying();
|
||||
}
|
||||
showBouceAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateProgressViews(int progress, int total) {
|
||||
songCurrentProgress.setText(String.format("%s / %s", MusicUtil.getReadableDurationString(progress),
|
||||
MusicUtil.getReadableDurationString(total)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDark(int dark) {
|
||||
int color = ATHUtil.resolveColor(getActivity(), android.R.attr.colorBackground);
|
||||
if (ColorUtil.isColorLight(color)) {
|
||||
lastPlaybackControlsColor = MaterialValueHelper
|
||||
.getSecondaryTextColor(getActivity(), true);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper
|
||||
.getSecondaryDisabledTextColor(getActivity(), true);
|
||||
} else {
|
||||
lastPlaybackControlsColor = MaterialValueHelper
|
||||
.getPrimaryTextColor(getActivity(), false);
|
||||
lastDisabledPlaybackControlsColor = MaterialValueHelper
|
||||
.getPrimaryDisabledTextColor(getActivity(), false);
|
||||
}
|
||||
|
||||
if (PreferenceUtil.getInstance(getContext()).getAdaptiveColor()) {
|
||||
TintHelper.setTintAuto(playPauseFab, MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(dark)), false);
|
||||
TintHelper.setTintAuto(playPauseFab, dark, true);
|
||||
text.setTextColor(dark);
|
||||
} else {
|
||||
text.setTextColor(ThemeStore.accentColor(getContext()));
|
||||
}
|
||||
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
updatePrevNextColor();
|
||||
}
|
||||
|
||||
public void setProgressBarColor(SeekBar progressBar, int newColor) {
|
||||
LayerDrawable ld = (LayerDrawable) progressBar.getProgressDrawable();
|
||||
ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress);
|
||||
clipDrawable.setColorFilter(newColor, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
private void setUpPlayPauseFab() {
|
||||
playerFabPlayPauseDrawable = new PlayPauseDrawable(getActivity());
|
||||
|
||||
playPauseFab.setImageDrawable(playerFabPlayPauseDrawable); // Note: set the drawable AFTER TintHelper.setTintAuto() was called
|
||||
//playPauseFab.setColorFilter(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(fabColor)), PorterDuff.Mode.SRC_IN);
|
||||
//playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||
playPauseFab.post(() -> {
|
||||
if (playPauseFab != null) {
|
||||
playPauseFab.setPivotX(playPauseFab.getWidth() / 2);
|
||||
playPauseFab.setPivotY(playPauseFab.getHeight() / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||
if (MusicPlayerRemote.isPlaying()) {
|
||||
playerFabPlayPauseDrawable.setPause(animate);
|
||||
} else {
|
||||
playerFabPlayPauseDrawable.setPlay(animate);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.player.simple;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment;
|
||||
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class SimplePlayerFragment extends AbsPlayerFragment implements
|
||||
PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
@BindView(R.id.player_toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.status_bar)
|
||||
View statusBar;
|
||||
private Unbinder unbinder;
|
||||
private SimplePlaybackControlsFragment simplePlaybackControlsFragment;
|
||||
private int lastColor;
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_simple_player, container, false);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
toggleStatusBar(statusBar);
|
||||
setUpSubFragments();
|
||||
setUpPlayerToolbar();
|
||||
}
|
||||
|
||||
private void setUpSubFragments() {
|
||||
PlayerAlbumCoverFragment playerAlbumCoverFragment = (PlayerAlbumCoverFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.player_album_cover_fragment);
|
||||
playerAlbumCoverFragment.setCallbacks(this);
|
||||
simplePlaybackControlsFragment = (SimplePlaybackControlsFragment)
|
||||
getChildFragmentManager().findFragmentById(R.id.playback_controls_fragment);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPaletteColor() {
|
||||
return lastColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow() {
|
||||
simplePlaybackControlsFragment.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
simplePlaybackControlsFragment.hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Toolbar getToolbar() {
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int toolbarIconColor() {
|
||||
return ATHUtil.resolveColor(getContext(), R.attr.iconColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onColorChanged(int color) {
|
||||
lastColor = color;
|
||||
getCallbacks().onPaletteColorChanged();
|
||||
simplePlaybackControlsFragment.setDark(color);
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar,
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor), getActivity());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFavoriteToggled() {
|
||||
toggleFavorite(MusicPlayerRemote.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toggleFavorite(Song song) {
|
||||
super.toggleFavorite(song);
|
||||
if (song.id == MusicPlayerRemote.getCurrentSong().id) {
|
||||
updateIsFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpPlayerToolbar() {
|
||||
toolbar.inflateMenu(R.menu.menu_player);
|
||||
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
ToolbarContentTintHelper.colorizeToolbar(toolbar,
|
||||
ATHUtil.resolveColor(getContext(), R.attr.iconColor),
|
||||
getActivity());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.settings;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceFragmentCompat;
|
||||
import code.name.monkey.retromusic.preferences.BlacklistPreference;
|
||||
import code.name.monkey.retromusic.preferences.BlacklistPreferenceDialog;
|
||||
import code.name.monkey.retromusic.preferences.NowPlayingScreenPreference;
|
||||
import code.name.monkey.retromusic.preferences.NowPlayingScreenPreferenceDialog;
|
||||
import code.name.monkey.retromusic.ui.activities.SettingsActivity;
|
||||
import code.name.monkey.retromusic.util.DensityUtil;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public abstract class AbsSettingsFragment extends ATEPreferenceFragmentCompat {
|
||||
protected void showProToastAndNavigate(String message) {
|
||||
Toast.makeText(getContext(), message + " is Pro version feature.", Toast.LENGTH_SHORT).show();
|
||||
//noinspection ConstantConditions
|
||||
NavigationUtil.goToProVersion(getActivity());
|
||||
}
|
||||
|
||||
protected void setSummary(@NonNull Preference preference) {
|
||||
setSummary(preference, PreferenceManager
|
||||
.getDefaultSharedPreferences(preference.getContext())
|
||||
.getString(preference.getKey(), ""));
|
||||
}
|
||||
|
||||
protected void setSummary(Preference preference, @NonNull Object value) {
|
||||
String stringValue = value.toString();
|
||||
if (preference instanceof ListPreference) {
|
||||
ListPreference listPreference = (ListPreference) preference;
|
||||
int index = listPreference.findIndexOfValue(stringValue);
|
||||
preference.setSummary(index >= 0 ? listPreference.getEntries()[index] : null);
|
||||
} else {
|
||||
preference.setSummary(stringValue);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void invalidateSettings();
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setDividerHeight(0);
|
||||
setDivider(new ColorDrawable(Color.TRANSPARENT));
|
||||
|
||||
getListView().setPadding(DensityUtil.dip2px(getContext(), 0), 0, 0, 0);
|
||||
getListView().addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||
super.onScrolled(recyclerView, dx, dy);
|
||||
if (getActivity() != null) {
|
||||
((SettingsActivity) getActivity())
|
||||
.addAppbarLayoutElevation(recyclerView.canScrollVertically(RecyclerView.NO_POSITION) ? 8f : 0f);
|
||||
}
|
||||
}
|
||||
});
|
||||
//noinspection ConstantConditions
|
||||
getListView().setBackgroundColor(ThemeStore.primaryColor(getContext()));
|
||||
getListView().setOverScrollMode(View.OVER_SCROLL_NEVER);
|
||||
invalidateSettings();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DialogFragment onCreatePreferenceDialog(Preference preference) {
|
||||
if (preference instanceof NowPlayingScreenPreference) {
|
||||
return NowPlayingScreenPreferenceDialog.newInstance();
|
||||
} else if (preference instanceof BlacklistPreference) {
|
||||
return BlacklistPreferenceDialog.newInstance();
|
||||
}
|
||||
return super.onCreatePreferenceDialog(preference);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.settings;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.media.audiofx.AudioEffect;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class AudioSettings extends AbsSettingsFragment {
|
||||
@Override
|
||||
public void invalidateSettings() {
|
||||
Preference findPreference = findPreference("equalizer");
|
||||
if (!hasEqualizer() && !PreferenceUtil.getInstance(getContext()).getSelectedEqualizer().equals("retro")) {
|
||||
findPreference.setEnabled(false);
|
||||
findPreference.setSummary(getResources().getString(R.string.no_equalizer));
|
||||
} else {
|
||||
findPreference.setEnabled(true);
|
||||
}
|
||||
findPreference.setOnPreferenceClickListener(preference -> {
|
||||
//noinspection ConstantConditions
|
||||
NavigationUtil.openEqualizer(getActivity());
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
private boolean hasEqualizer() {
|
||||
final Intent effects = new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL);
|
||||
//noinspection ConstantConditions
|
||||
PackageManager pm = getActivity().getPackageManager();
|
||||
ResolveInfo ri = pm.resolveActivity(effects, 0);
|
||||
return ri != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.pref_audio);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.settings;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class ImageSettingFragment extends AbsSettingsFragment {
|
||||
@Override
|
||||
public void invalidateSettings() {
|
||||
final Preference autoDownloadImagesPolicy = findPreference("auto_download_images_policy");
|
||||
setSummary(autoDownloadImagesPolicy);
|
||||
autoDownloadImagesPolicy.setOnPreferenceChangeListener((preference, o) -> {
|
||||
setSummary(autoDownloadImagesPolicy, o);
|
||||
return true;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.pref_images);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.settings;
|
||||
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.BindViews;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.ui.activities.SettingsActivity;
|
||||
import code.name.monkey.retromusic.views.IconImageView;
|
||||
|
||||
public class MainSettingsFragment extends Fragment {
|
||||
|
||||
Unbinder unbinder;
|
||||
@BindViews({R.id.general_settings_icon, R.id.audio_settings_icon,
|
||||
R.id.now_playing_settings_icon, R.id.image_settings_icon,
|
||||
R.id.notification_settings_icon, R.id.other_settings_icon})
|
||||
List<IconImageView> icons;
|
||||
ButterKnife.Action<View> apply = (view, index) -> {
|
||||
//noinspection ConstantConditions
|
||||
((IconImageView) view).setColorFilter(ThemeStore.accentColor(getContext()), PorterDuff.Mode.SRC_IN);
|
||||
};
|
||||
@BindView(R.id.container)
|
||||
ViewGroup container;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View layout = inflater.inflate(R.layout.fragment_main_settings, container, false);
|
||||
unbinder = ButterKnife.bind(this, layout);
|
||||
ButterKnife.apply(icons, apply);
|
||||
return layout;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
@OnClick({R.id.general_settings, R.id.audio_settings, R.id.now_playing_settings,
|
||||
R.id.image_settings, R.id.notification_settings, R.id.other_settings})
|
||||
public void onViewClicked(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.general_settings:
|
||||
inflateFragment(new ThemeSettingsFragment());
|
||||
break;
|
||||
case R.id.audio_settings:
|
||||
inflateFragment(new AudioSettings());
|
||||
break;
|
||||
case R.id.now_playing_settings:
|
||||
inflateFragment(new NowPlayingSettingsFragment());
|
||||
break;
|
||||
case R.id.image_settings:
|
||||
inflateFragment(new ImageSettingFragment());
|
||||
break;
|
||||
case R.id.notification_settings:
|
||||
inflateFragment(new NotificationSettingsFragment());
|
||||
break;
|
||||
case R.id.other_settings:
|
||||
inflateFragment(new OtherSettingsFragment());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void inflateFragment(Fragment fragment) {
|
||||
if (getActivity() != null) {
|
||||
((SettingsActivity) getActivity()).setupFragment(fragment);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.settings;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.TwoStatePreference;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class NotificationSettingsFragment extends AbsSettingsFragment {
|
||||
@Override
|
||||
public void invalidateSettings() {
|
||||
final TwoStatePreference classicNotification = (TwoStatePreference) findPreference("classic_notification");
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
classicNotification.setVisible(false);
|
||||
} else {
|
||||
classicNotification.setChecked(PreferenceUtil.getInstance(getActivity()).classicNotification());
|
||||
classicNotification.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
// Save preference
|
||||
PreferenceUtil.getInstance(getActivity()).setClassicNotification((Boolean) newValue);
|
||||
|
||||
final MusicService service = MusicPlayerRemote.musicService;
|
||||
if (service != null) {
|
||||
service.initNotification();
|
||||
service.updateNotification();
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.pref_notification);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.settings;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.preference.TwoStatePreference;
|
||||
import android.view.View;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.RetroApplication;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class NowPlayingSettingsFragment extends AbsSettingsFragment implements
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void invalidateSettings() {
|
||||
updateNowPlayingScreenSummary();
|
||||
|
||||
final TwoStatePreference cornerWindow = (TwoStatePreference) findPreference("corner_window");
|
||||
cornerWindow.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
if ((Boolean) newValue && !RetroApplication.isProVersion()) {
|
||||
showProToastAndNavigate(getActivity().getString(R.string.pref_title_round_corners));
|
||||
return false;
|
||||
}
|
||||
getActivity().recreate();
|
||||
return true;
|
||||
});
|
||||
final TwoStatePreference carouselEffect = (TwoStatePreference) findPreference(
|
||||
"carousel_effect");
|
||||
carouselEffect.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
if ((Boolean) newValue && !RetroApplication.isProVersion()) {
|
||||
showProToastAndNavigate(
|
||||
getActivity().getString(R.string.pref_title_toggle_carousel_effect));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
final TwoStatePreference toggleFullScreen = (TwoStatePreference) findPreference(
|
||||
"toggle_full_screen");
|
||||
toggleFullScreen.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
getActivity().recreate();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.pref_now_playing_screen);
|
||||
addPreferencesFromResource(R.xml.pref_ui);
|
||||
addPreferencesFromResource(R.xml.pref_window);
|
||||
addPreferencesFromResource(R.xml.pref_lockscreen);
|
||||
}
|
||||
|
||||
private void updateNowPlayingScreenSummary() {
|
||||
//noinspection ConstantConditions
|
||||
findPreference("now_playing_screen_id")
|
||||
.setSummary(PreferenceUtil.getInstance(getActivity()).getNowPlayingScreen().titleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
//noinspection ConstantConditions
|
||||
PreferenceUtil.getInstance(getContext()).registerOnSharedPreferenceChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
//noinspection ConstantConditions
|
||||
PreferenceUtil.getInstance(getContext()).unregisterOnSharedPreferenceChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
switch (key) {
|
||||
case PreferenceUtil.NOW_PLAYING_SCREEN_ID:
|
||||
updateNowPlayingScreenSummary();
|
||||
break;
|
||||
case PreferenceUtil.CIRCULAR_ALBUM_ART:
|
||||
case PreferenceUtil.CAROUSEL_EFFECT:
|
||||
invalidateSettings();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.settings;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class OtherSettingsFragment extends AbsSettingsFragment {
|
||||
@Override
|
||||
public void invalidateSettings() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.pref_blacklist);
|
||||
addPreferencesFromResource(R.xml.pref_playlists);
|
||||
addPreferencesFromResource(R.xml.pref_advanced);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
package code.name.monkey.retromusic.ui.fragments.settings;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.TwoStatePreference;
|
||||
|
||||
import com.afollestad.materialdialogs.color.ColorChooserDialog;
|
||||
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEColorPreference;
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil;
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.RetroApplication;
|
||||
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager;
|
||||
import code.name.monkey.retromusic.ui.activities.SettingsActivity;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class ThemeSettingsFragment extends AbsSettingsFragment {
|
||||
|
||||
@Override
|
||||
public void invalidateSettings() {
|
||||
|
||||
final ATEColorPreference primaryColorPref = (ATEColorPreference) findPreference(
|
||||
"primary_color");
|
||||
//noinspection ConstantConditions
|
||||
primaryColorPref.setVisible(PreferenceUtil.getInstance(getActivity()).getGeneralTheme() == R.style.Theme_RetroMusic_Color);
|
||||
final int primaryColor = ThemeStore.primaryColor(getActivity());
|
||||
primaryColorPref.setColor(primaryColor, ColorUtil.darkenColor(primaryColor));
|
||||
primaryColorPref.setOnPreferenceClickListener(preference -> {
|
||||
new ColorChooserDialog.Builder(getActivity(), R.string.primary_color)
|
||||
.accentMode(false)
|
||||
.allowUserColorInput(true)
|
||||
.allowUserColorInputAlpha(false)
|
||||
.preselect(primaryColor)
|
||||
.show(getActivity());
|
||||
return true;
|
||||
});
|
||||
|
||||
final Preference generalTheme = findPreference("general_theme");
|
||||
setSummary(generalTheme);
|
||||
generalTheme.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
String theme = (String) newValue;
|
||||
|
||||
if (theme.equals("color") && !RetroApplication.isProVersion()) {
|
||||
primaryColorPref.setVisible(false);
|
||||
showProToastAndNavigate("Color theme");
|
||||
return false;
|
||||
} else {
|
||||
primaryColorPref.setVisible(true);
|
||||
}
|
||||
|
||||
setSummary(generalTheme, newValue);
|
||||
|
||||
|
||||
switch (theme) {
|
||||
case "light":
|
||||
ThemeStore.editTheme(getContext()).primaryColor(Color.WHITE).commit();
|
||||
break;
|
||||
case "black":
|
||||
ThemeStore.editTheme(getContext()).primaryColor(Color.BLACK).commit();
|
||||
break;
|
||||
case "dark":
|
||||
ThemeStore.editTheme(getContext()).primaryColor(ContextCompat.getColor(getContext(), R.color.md_grey_900)).commit();
|
||||
break;
|
||||
case "color":
|
||||
ThemeStore.editTheme(getContext()).primaryColor(ContextCompat.getColor(getContext(), R.color.md_blue_grey_800)).commit();
|
||||
break;
|
||||
}
|
||||
|
||||
ThemeStore.editTheme(getActivity())
|
||||
.activityTheme(PreferenceUtil.getThemeResFromPrefValue(theme))
|
||||
.commit();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
getActivity().setTheme(PreferenceUtil.getThemeResFromPrefValue(theme));
|
||||
new DynamicShortcutManager(getActivity()).updateDynamicShortcuts();
|
||||
}
|
||||
getActivity().recreate();
|
||||
//invalidateSettings();
|
||||
return true;
|
||||
});
|
||||
|
||||
ATEColorPreference accentColorPref = (ATEColorPreference) findPreference("accent_color");
|
||||
final int accentColor = ThemeStore.accentColor(getActivity());
|
||||
accentColorPref.setColor(accentColor, ColorUtil.darkenColor(accentColor));
|
||||
|
||||
accentColorPref.setOnPreferenceClickListener(preference -> {
|
||||
new ColorChooserDialog.Builder(((SettingsActivity) getActivity()), R.string.accent_color)
|
||||
.accentMode(true)
|
||||
.allowUserColorInput(true)
|
||||
.allowUserColorInputAlpha(false)
|
||||
.preselect(accentColor)
|
||||
.show(getActivity());
|
||||
return true;
|
||||
});
|
||||
|
||||
TwoStatePreference colorNavBar = (TwoStatePreference) findPreference(
|
||||
"should_color_navigation_bar");
|
||||
if (!VersionUtils.hasLollipop()) {
|
||||
colorNavBar.setEnabled(false);
|
||||
colorNavBar.setSummary(R.string.pref_only_lollipop);
|
||||
} else {
|
||||
colorNavBar.setChecked(ThemeStore.coloredNavigationBar(getActivity()));
|
||||
colorNavBar.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
ThemeStore.editTheme(getActivity())
|
||||
.coloredNavigationBar((Boolean) newValue)
|
||||
.commit();
|
||||
getActivity().recreate();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
TwoStatePreference colorAppShortcuts = (TwoStatePreference) findPreference(
|
||||
"should_color_app_shortcuts");
|
||||
if (!VersionUtils.hasNougatMR()) {
|
||||
colorAppShortcuts.setVisible(false);
|
||||
} else {
|
||||
colorAppShortcuts.setChecked(PreferenceUtil.getInstance(getActivity()).coloredAppShortcuts());
|
||||
colorAppShortcuts.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
// Save preference
|
||||
PreferenceUtil.getInstance(getActivity()).setColoredAppShortcuts((Boolean) newValue);
|
||||
// Update app shortcuts
|
||||
new DynamicShortcutManager(getActivity()).updateDynamicShortcuts();
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.pref_general);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue