Renamed package to gramophone
This commit is contained in:
parent
200c50babf
commit
c28a75c61a
95 changed files with 412 additions and 415 deletions
|
|
@ -0,0 +1,416 @@
|
|||
package com.kabouzeid.gramophone.ui.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.graphics.Palette;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableListView;
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.adapter.songadapter.SongAdapter;
|
||||
import com.kabouzeid.gramophone.comparator.SongTrackNumberComparator;
|
||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||
import com.kabouzeid.gramophone.interfaces.OnMusicRemoteEventListener;
|
||||
import com.kabouzeid.gramophone.loader.AlbumLoader;
|
||||
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
||||
import com.kabouzeid.gramophone.model.Album;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.tageditor.AlbumTagEditorActivity;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||
import com.nhaarman.listviewanimations.appearance.AnimationAdapter;
|
||||
import com.nhaarman.listviewanimations.appearance.simple.ScaleInAnimationAdapter;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
import com.nineoldandroids.view.ViewPropertyAnimator;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
*
|
||||
* A lot of hackery is done in this activity. Changing things may will brake the whole activity.
|
||||
*
|
||||
* Should be kinda stable ONLY AS IT IS!!!
|
||||
*
|
||||
* */
|
||||
|
||||
public class AlbumDetailActivity extends AbsFabActivity implements OnMusicRemoteEventListener, KabViewsDisableAble {
|
||||
public static final String TAG = AlbumDetailActivity.class.getSimpleName();
|
||||
|
||||
private static final boolean TOOLBAR_IS_STICKY = true;
|
||||
private static final int DEFAULT_DELAY_NO_TRANSITION = 200;
|
||||
private static final int DEFAULT_DELAY = 450;
|
||||
private static final int DEFAULT_ANIMATION_TIME = 1000;
|
||||
|
||||
private App app;
|
||||
|
||||
private Album album;
|
||||
|
||||
private AnimationAdapter animatedSongsAdapter;
|
||||
private ObservableListView absSongListView;
|
||||
private View statusBar;
|
||||
private ImageView albumArtImageView;
|
||||
private View albumArtOverlayView;
|
||||
private View songsBackgroundView;
|
||||
private TextView albumTitleView;
|
||||
private Toolbar toolbar;
|
||||
private int toolbarHeight;
|
||||
private int headerOffset;
|
||||
private int titleViewHeight;
|
||||
private int albumArtViewHeight;
|
||||
private int toolbarColor;
|
||||
private SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||
super.onScrollChanged(scrollY, b, b2);
|
||||
// Translate overlay and image
|
||||
float flexibleRange = albumArtViewHeight - headerOffset;
|
||||
int minOverlayTransitionY = headerOffset - albumArtOverlayView.getHeight();
|
||||
ViewHelper.setTranslationY(albumArtOverlayView, Math.max(minOverlayTransitionY, Math.min(0, -scrollY)));
|
||||
ViewHelper.setTranslationY(albumArtImageView, Math.max(minOverlayTransitionY, Math.min(0, -scrollY / 2)));
|
||||
|
||||
// Translate list background
|
||||
ViewHelper.setTranslationY(songsBackgroundView, Math.max(0, -scrollY + albumArtViewHeight));
|
||||
|
||||
// Change alpha of overlay
|
||||
ViewHelper.setAlpha(albumArtOverlayView, Math.max(0, Math.min(1, (float) scrollY / flexibleRange)));
|
||||
|
||||
// Translate name text
|
||||
int maxTitleTranslationY = albumArtViewHeight;
|
||||
int titleTranslationY = maxTitleTranslationY - scrollY;
|
||||
if (TOOLBAR_IS_STICKY) {
|
||||
titleTranslationY = Math.max(headerOffset, titleTranslationY);
|
||||
}
|
||||
ViewHelper.setTranslationY(albumTitleView, titleTranslationY);
|
||||
|
||||
// Translate FAB
|
||||
int fabTranslationY = titleTranslationY + titleViewHeight - (getFab().getHeight() / 2);
|
||||
ViewHelper.setTranslationY(getFab(), fabTranslationY);
|
||||
|
||||
if (TOOLBAR_IS_STICKY) {
|
||||
// Change alpha of toolbar background
|
||||
if (-scrollY + albumArtViewHeight <= headerOffset) {
|
||||
ViewUtil.setBackgroundAlpha(toolbar, 1, toolbarColor);
|
||||
ViewUtil.setBackgroundAlpha(statusBar, 1, toolbarColor);
|
||||
|
||||
} else {
|
||||
ViewUtil.setBackgroundAlpha(toolbar, 0, toolbarColor);
|
||||
ViewUtil.setBackgroundAlpha(statusBar, 0, toolbarColor);
|
||||
}
|
||||
} else {
|
||||
// Translate Toolbar
|
||||
if (scrollY < albumArtViewHeight) {
|
||||
ViewHelper.setTranslationY(toolbar, 0);
|
||||
} else {
|
||||
ViewHelper.setTranslationY(toolbar, -scrollY);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
if (Util.hasLollipopSDK()) postponeEnterTransition();
|
||||
app = (App) getApplicationContext();
|
||||
setTheme(app.getAppTheme());
|
||||
setUpTranslucence();
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_album_detail);
|
||||
|
||||
Bundle intentExtras = getIntent().getExtras();
|
||||
int albumId = -1;
|
||||
if (intentExtras != null) {
|
||||
albumId = intentExtras.getInt(AppKeys.E_ALBUM);
|
||||
}
|
||||
album = AlbumLoader.getAlbum(this, albumId);
|
||||
if (album.id == -1) {
|
||||
finish();
|
||||
}
|
||||
|
||||
initViews();
|
||||
setUpObservableListViewParams();
|
||||
setUpToolBar();
|
||||
setUpViews();
|
||||
if (!Util.hasLollipopSDK()) animateEnterActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goToAlbum(int albumId) {
|
||||
if (album.id != albumId) {
|
||||
goToAlbum(albumId);
|
||||
}
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
albumArtImageView = (ImageView) findViewById(R.id.album_art);
|
||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
albumArtOverlayView = findViewById(R.id.overlay);
|
||||
absSongListView = (ObservableListView) findViewById(R.id.list);
|
||||
albumTitleView = (TextView) findViewById(R.id.album_title);
|
||||
songsBackgroundView = findViewById(R.id.list_background);
|
||||
statusBar = findViewById(R.id.statusBar);
|
||||
}
|
||||
|
||||
private void setUpObservableListViewParams() {
|
||||
albumArtViewHeight = getResources().getDimensionPixelSize(R.dimen.header_image_height);
|
||||
toolbarColor = getResources().getColor(R.color.materialmusic_default_bar_color);
|
||||
toolbarHeight = Util.getActionBarSize(this);
|
||||
titleViewHeight = getResources().getDimensionPixelSize(R.dimen.title_view_height);
|
||||
headerOffset = toolbarHeight;
|
||||
headerOffset += getResources().getDimensionPixelSize(R.dimen.statusMargin);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
albumTitleView.setText(album.title);
|
||||
ViewHelper.setAlpha(albumArtOverlayView, 0);
|
||||
|
||||
prepareViewsForOpenAnimation();
|
||||
setUpAlbumArtAndApplyPalette();
|
||||
setUpListView();
|
||||
}
|
||||
|
||||
private void prepareViewsForOpenAnimation() {
|
||||
albumTitleView.setPivotY(0);
|
||||
albumTitleView.setScaleY(0);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private void setUpAlbumArtAndApplyPalette() {
|
||||
ImageLoader.getInstance().displayImage(MusicUtil.getAlbumArtUri(album.id).toString(), albumArtImageView, new ImageLoadingListener() {
|
||||
@Override
|
||||
public void onLoadingStarted(String imageUri, View view) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
||||
albumArtImageView.setImageResource(R.drawable.default_album_art);
|
||||
if (Util.hasLollipopSDK()) {
|
||||
startPostponedEnterTransition();
|
||||
animateEnterActivity();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingComplete(String imageUri, final View view, Bitmap loadedImage) {
|
||||
applyPalette(loadedImage);
|
||||
if (Util.hasLollipopSDK()) {
|
||||
startPostponedEnterTransition();
|
||||
animateEnterActivity();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingCancelled(String imageUri, View view) {
|
||||
albumArtImageView.setImageResource(R.drawable.default_album_art);
|
||||
if (Util.hasLollipopSDK()) {
|
||||
startPostponedEnterTransition();
|
||||
animateEnterActivity();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void applyPalette(Bitmap bitmap) {
|
||||
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
|
||||
@Override
|
||||
public void onGenerated(Palette palette) {
|
||||
Palette.Swatch swatch = palette.getVibrantSwatch();
|
||||
if (swatch != null) {
|
||||
toolbarColor = swatch.getRgb();
|
||||
albumArtOverlayView.setBackgroundColor(swatch.getRgb());
|
||||
albumTitleView.setBackgroundColor(swatch.getRgb());
|
||||
albumTitleView.setTextColor(swatch.getTitleTextColor());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpListView() {
|
||||
absSongListView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
||||
setListViewPadding();
|
||||
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
|
||||
contentView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
songsBackgroundView.getLayoutParams().height = contentView.getHeight();
|
||||
observableScrollViewCallbacks.onScrollChanged(0, false, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setListViewPadding() {
|
||||
setListViewPaddingTop();
|
||||
if (app.isInPortraitMode() || app.isTablet()) {
|
||||
setListViewPaddingBottom();
|
||||
}
|
||||
}
|
||||
|
||||
private void setListViewPaddingTop() {
|
||||
final View paddingView = new View(AlbumDetailActivity.this);
|
||||
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
|
||||
albumArtViewHeight + titleViewHeight);
|
||||
paddingView.setLayoutParams(lp);
|
||||
paddingView.setClickable(true);
|
||||
absSongListView.addHeaderView(paddingView);
|
||||
}
|
||||
|
||||
private void setListViewPaddingBottom() {
|
||||
final View paddingView = new View(AlbumDetailActivity.this);
|
||||
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
|
||||
Util.getNavigationBarHeight(this));
|
||||
paddingView.setLayoutParams(lp);
|
||||
paddingView.setClickable(true);
|
||||
absSongListView.addFooterView(paddingView);
|
||||
}
|
||||
|
||||
private void setUpToolBar() {
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setTitle(null);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
if (!TOOLBAR_IS_STICKY) {
|
||||
toolbar.setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpTranslucence() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
Util.setStatusBarTranslucent(getWindow(), true);
|
||||
if (app.isInPortraitMode() || app.isTablet()) {
|
||||
Util.setNavBarTranslucent(getWindow(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void animateEnterActivity() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
animateHeader(0);
|
||||
setUpSongsAdapter();
|
||||
}
|
||||
}, DEFAULT_DELAY);
|
||||
|
||||
} else {
|
||||
setUpSongsAdapter();
|
||||
getFab().setScaleX(0);
|
||||
getFab().setScaleY(0);
|
||||
animateHeader(DEFAULT_DELAY_NO_TRANSITION);
|
||||
animateFab(DEFAULT_DELAY_NO_TRANSITION);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpSongsAdapter() {
|
||||
final List<Song> songs = AlbumSongLoader.getAlbumSongList(this, album.id, new SongTrackNumberComparator());
|
||||
final SongAdapter songAdapter = new SongAdapter(this, this, songs);
|
||||
|
||||
// SwingBottomInAnimationAdapter songsAdapter = new SwingBottomInAnimationAdapter(songAdapter);
|
||||
// SwingRightInAnimationAdapter songsAdapter = new SwingRightInAnimationAdapter(songAdapter);
|
||||
// SwingLeftInAnimationAdapter songsAdapter = new SwingLeftInAnimationAdapter(songAdapter);
|
||||
ScaleInAnimationAdapter songsAdapter = new ScaleInAnimationAdapter(songAdapter);
|
||||
// AlphaInAnimationAdapter songsAdapter = new AlphaInAnimationAdapter(songAdapter);
|
||||
|
||||
animatedSongsAdapter = songsAdapter;
|
||||
animatedSongsAdapter.setAbsListView(absSongListView);
|
||||
|
||||
absSongListView.setAdapter(animatedSongsAdapter);
|
||||
absSongListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (position > 0) {
|
||||
app.getMusicPlayerRemote().openQueue(songs, position - 1, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void animateHeader(int startDelay) {
|
||||
ViewPropertyAnimator.animate(albumTitleView)
|
||||
.scaleX(1)
|
||||
.scaleY(1)
|
||||
.setInterpolator(new DecelerateInterpolator(4))
|
||||
.setDuration(DEFAULT_ANIMATION_TIME)
|
||||
.setStartDelay(startDelay)
|
||||
.start();
|
||||
}
|
||||
|
||||
private void animateFab(int startDelay) {
|
||||
ViewPropertyAnimator.animate(getFab())
|
||||
.scaleX(1)
|
||||
.scaleY(1)
|
||||
.setInterpolator(new DecelerateInterpolator(4))
|
||||
.setDuration(DEFAULT_ANIMATION_TIME)
|
||||
.setStartDelay(startDelay)
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
super.enableViews();
|
||||
absSongListView.setEnabled(true);
|
||||
toolbar.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
super.disableViews();
|
||||
absSongListView.setEnabled(false);
|
||||
toolbar.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_album_detail, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_settings:
|
||||
return true;
|
||||
case R.id.action_current_playing:
|
||||
return openCurrentPlayingIfPossible(null);
|
||||
case R.id.action_tag_editor:
|
||||
Intent intent = new Intent(this, AlbumTagEditorActivity.class);
|
||||
intent.putExtra(AppKeys.E_ID, album.id);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.action_go_to_artist:
|
||||
goToArtist(album.artistId, null);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,501 @@
|
|||
package com.kabouzeid.gramophone.ui.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.v13.app.FragmentPagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.graphics.Palette;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.transition.Transition;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.google.samples.apps.iosched.ui.widget.SlidingTabLayout;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||
import com.kabouzeid.gramophone.interfaces.OnMusicRemoteEventListener;
|
||||
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistImageLoader;
|
||||
import com.kabouzeid.gramophone.loader.ArtistLoader;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.model.Artist;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||
import com.kabouzeid.gramophone.ui.fragments.artistviewpager.AbsViewPagerTabArtistListFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.artistviewpager.ViewPagerTabArtistAlbumFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.artistviewpager.ViewPagerTabArtistBioFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.artistviewpager.ViewPagerTabArtistSongListFragment;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||
import com.nineoldandroids.animation.Animator;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
import com.nineoldandroids.view.ViewPropertyAnimator;
|
||||
|
||||
/*
|
||||
*
|
||||
* A lot of hackery is done in this activity. Changing things may will brake the whole activity.
|
||||
*
|
||||
* Should be kinda stable ONLY AS IT IS!!!
|
||||
*
|
||||
* */
|
||||
|
||||
public class ArtistDetailActivity extends AbsFabActivity implements OnMusicRemoteEventListener, KabViewsDisableAble, ObservableScrollViewCallbacks {
|
||||
public static final String TAG = ArtistDetailActivity.class.getSimpleName();
|
||||
|
||||
public static final String ARG_ARTIST_ID = "com.kabouzeid.gramophone.artist.id";
|
||||
public static final String ARG_ARTIST_NAME = "com.kabouzeid.gramophone.artist.name";
|
||||
|
||||
private static final boolean TOOLBAR_IS_STICKY = true;
|
||||
|
||||
private boolean isAnimating;
|
||||
|
||||
private Artist artist;
|
||||
|
||||
private SlidingTabLayout slidingTabs;
|
||||
private View statusBar;
|
||||
private ImageView artistImageView;
|
||||
private View artistArtOverlayView;
|
||||
private View absAlbumListBackgroundView;
|
||||
private TextView artistTitleText;
|
||||
private Toolbar toolbar;
|
||||
private ViewPager viewPager;
|
||||
private NavigationAdapter navigationAdapter;
|
||||
private int toolbarHeight;
|
||||
private int headerOffset;
|
||||
private int titleViewHeight;
|
||||
private int artistImageViewHeight;
|
||||
private int toolbarColor;
|
||||
private int tabHeight;
|
||||
|
||||
private Fragment currentFragment;
|
||||
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setUpTranslucence(true, true);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_artist_detail);
|
||||
|
||||
getIntentExtras();
|
||||
initViews();
|
||||
setUpObservableListViewParams();
|
||||
setUpToolBar();
|
||||
setUpViews();
|
||||
|
||||
if (Util.hasLollipopSDK()) {
|
||||
getWindow().getSharedElementEnterTransition().addListener(new Transition.TransitionListener() {
|
||||
@Override
|
||||
public void onTransitionStart(Transition transition) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionEnd(Transition transition) {
|
||||
setUpArtistImageAndApplyPalette(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionCancel(Transition transition) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionPause(Transition transition) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionResume(Transition transition) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goToArtist(int artistId) {
|
||||
if (artist.id != artistId) {
|
||||
super.goToArtist(artistId);
|
||||
}
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
artistImageView = (ImageView) findViewById(R.id.artist_image);
|
||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
artistArtOverlayView = findViewById(R.id.overlay);
|
||||
artistTitleText = (TextView) findViewById(R.id.artist_name);
|
||||
absAlbumListBackgroundView = findViewById(R.id.list_background);
|
||||
statusBar = findViewById(R.id.statusBar);
|
||||
slidingTabs = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
|
||||
}
|
||||
|
||||
private void setUpObservableListViewParams() {
|
||||
artistImageViewHeight = getResources().getDimensionPixelSize(R.dimen.header_image_height);
|
||||
toolbarColor = Util.resolveColor(this, R.attr.colorPrimary);
|
||||
toolbarHeight = Util.getActionBarSize(this);
|
||||
titleViewHeight = getResources().getDimensionPixelSize(R.dimen.title_view_height);
|
||||
headerOffset = toolbarHeight;
|
||||
headerOffset += getResources().getDimensionPixelSize(R.dimen.statusMargin);
|
||||
tabHeight = getResources().getDimensionPixelSize(R.dimen.tab_height);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
artistTitleText.setText(artist.name);
|
||||
ViewHelper.setAlpha(artistArtOverlayView, 0);
|
||||
|
||||
setUpArtistImageAndApplyPalette(false);
|
||||
setUpViewPatch();
|
||||
setUpSlidingTabs();
|
||||
}
|
||||
|
||||
private void setUpSlidingTabs() {
|
||||
navigationAdapter = new NavigationAdapter(this, artist);
|
||||
viewPager = (ViewPager) findViewById(R.id.pager);
|
||||
viewPager.setOffscreenPageLimit(2);
|
||||
viewPager.setAdapter(navigationAdapter);
|
||||
viewPager.setCurrentItem(1);
|
||||
|
||||
slidingTabs.setViewPager(viewPager);
|
||||
slidingTabs.setDistributeEvenly(true);
|
||||
slidingTabs.setCustomTabView(R.layout.tab_indicator, android.R.id.text1);
|
||||
slidingTabs.setSelectedIndicatorColors(Util.resolveColor(this, R.attr.colorAccent));
|
||||
slidingTabs.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
currentFragment = navigationAdapter.getItemAt(position);
|
||||
if (currentFragment instanceof AbsViewPagerTabArtistListFragment) {
|
||||
restoreY(((AbsViewPagerTabArtistListFragment) currentFragment).getY());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void restoreY(final int scrollY) {
|
||||
translateToolBar(scrollY);
|
||||
int animationTime = 1000;
|
||||
DecelerateInterpolator interpolator = new DecelerateInterpolator(4);
|
||||
int titleTranslationY = getTitleTranslation(scrollY);
|
||||
ViewPropertyAnimator.animate(artistArtOverlayView).y(getOverlayTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||
ViewPropertyAnimator.animate(artistImageView).y(getImageViewTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||
ViewPropertyAnimator.animate(absAlbumListBackgroundView).y(getListBackgroundTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||
ViewPropertyAnimator.animate(artistArtOverlayView).alpha(getOverlayAlpha(scrollY)).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||
ViewPropertyAnimator.animate(slidingTabs).y(titleTranslationY + titleViewHeight).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||
ViewPropertyAnimator.animate(artistTitleText).y(titleTranslationY).setDuration(animationTime).setInterpolator(interpolator).start();
|
||||
ViewPropertyAnimator.animate(getFab()).y(getFabTranslation(scrollY)).setDuration(animationTime).setInterpolator(interpolator).setListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
isAnimating = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
translateToolBar(scrollY);
|
||||
isAnimating = false;
|
||||
if (currentFragment instanceof AbsViewPagerTabArtistListFragment) {
|
||||
onScrollChanged((((AbsViewPagerTabArtistListFragment) currentFragment).getY()), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
isAnimating = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
isAnimating = true;
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||
if (!isAnimating) {
|
||||
int titleTranslationY = getTitleTranslation(scrollY);
|
||||
ViewHelper.setTranslationY(artistArtOverlayView, getOverlayTranslation(scrollY));
|
||||
ViewHelper.setTranslationY(artistImageView, getImageViewTranslation(scrollY));
|
||||
ViewHelper.setTranslationY(absAlbumListBackgroundView, getListBackgroundTranslation(scrollY));
|
||||
ViewHelper.setAlpha(artistArtOverlayView, getOverlayAlpha(scrollY));
|
||||
ViewHelper.setTranslationY(artistTitleText, titleTranslationY);
|
||||
ViewHelper.setTranslationY(slidingTabs, titleTranslationY);
|
||||
ViewHelper.setTranslationY(getFab(), getFabTranslation(scrollY));
|
||||
translateToolBar(scrollY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
}
|
||||
|
||||
private int getImageViewTranslation(int scrollY) {
|
||||
int minOverlayTransitionY = headerOffset - artistArtOverlayView.getHeight();
|
||||
return Math.max(minOverlayTransitionY, Math.min(0, -scrollY / 2));
|
||||
}
|
||||
|
||||
private int getOverlayTranslation(int scrollY) {
|
||||
int minOverlayTransitionY = headerOffset - artistArtOverlayView.getHeight();
|
||||
return Math.max(minOverlayTransitionY, Math.min(0, -scrollY));
|
||||
}
|
||||
|
||||
private int getListBackgroundTranslation(int scrollY) {
|
||||
return Math.max(0, -scrollY + artistImageViewHeight - 200);
|
||||
}
|
||||
|
||||
private int getTitleTranslation(int scrollY) {
|
||||
int maxTitleTranslationY = artistImageViewHeight;
|
||||
int titleTranslationY = maxTitleTranslationY - scrollY;
|
||||
if (TOOLBAR_IS_STICKY) {
|
||||
titleTranslationY = Math.max(headerOffset, titleTranslationY);
|
||||
}
|
||||
return titleTranslationY;
|
||||
}
|
||||
|
||||
private int getFabTranslation(int scrollY) {
|
||||
return getTitleTranslation(scrollY) + titleViewHeight + tabHeight - (getFab().getHeight() / 2);
|
||||
}
|
||||
|
||||
private float getOverlayAlpha(int scrollY) {
|
||||
float flexibleRange = artistImageViewHeight - headerOffset;
|
||||
return Math.max(0, Math.min(1, (float) scrollY / flexibleRange));
|
||||
}
|
||||
|
||||
private void translateToolBar(int scrollY) {
|
||||
if (TOOLBAR_IS_STICKY) {
|
||||
// Change alpha of toolbar background
|
||||
if (-scrollY + artistImageViewHeight <= headerOffset) {
|
||||
ViewUtil.setBackgroundAlpha(toolbar, 1, toolbarColor);
|
||||
ViewUtil.setBackgroundAlpha(statusBar, 1, toolbarColor);
|
||||
|
||||
} else {
|
||||
ViewUtil.setBackgroundAlpha(toolbar, 0, toolbarColor);
|
||||
ViewUtil.setBackgroundAlpha(statusBar, 0, toolbarColor);
|
||||
}
|
||||
} else {
|
||||
// Translate Toolbar
|
||||
if (scrollY < artistImageViewHeight) {
|
||||
ViewHelper.setTranslationY(toolbar, 0);
|
||||
} else {
|
||||
ViewHelper.setTranslationY(toolbar, -scrollY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpArtistImageAndApplyPalette(final boolean forceDownload) {
|
||||
LastFMArtistImageLoader.loadArtistImage(this, artist.name, forceDownload, new LastFMArtistImageLoader.ArtistImageLoaderCallback() {
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void onArtistImageLoaded(Bitmap artistImage) {
|
||||
if (artistImage != null) {
|
||||
artistImageView.setImageBitmap(artistImage);
|
||||
applyPalette(artistImage);
|
||||
}
|
||||
if(forceDownload){
|
||||
Toast.makeText(ArtistDetailActivity.this, getResources().getString(R.string.updated_artist_image_for) + " " + artist.name, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void applyPalette(Bitmap bitmap) {
|
||||
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
|
||||
@Override
|
||||
public void onGenerated(Palette palette) {
|
||||
Palette.Swatch swatch = palette.getVibrantSwatch();
|
||||
if (swatch != null) {
|
||||
toolbarColor = swatch.getRgb();
|
||||
artistArtOverlayView.setBackgroundColor(swatch.getRgb());
|
||||
artistTitleText.setBackgroundColor(swatch.getRgb());
|
||||
slidingTabs.setBackgroundColor(swatch.getRgb());
|
||||
artistTitleText.setTextColor(swatch.getTitleTextColor());
|
||||
} else {
|
||||
setStandardColors();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setStandardColors() {
|
||||
int titleTextColor = Util.resolveColor(this, R.attr.title_text_color);
|
||||
int defaultBarColor = getResources().getColor(R.color.materialmusic_default_bar_color);
|
||||
|
||||
toolbarColor = defaultBarColor;
|
||||
artistArtOverlayView.setBackgroundColor(defaultBarColor);
|
||||
artistTitleText.setBackgroundColor(defaultBarColor);
|
||||
slidingTabs.setBackgroundColor(defaultBarColor);
|
||||
artistTitleText.setTextColor(titleTextColor);
|
||||
}
|
||||
|
||||
private void setUpViewPatch() {
|
||||
final View contentView = getWindow().getDecorView().findViewById(android.R.id.content);
|
||||
contentView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
absAlbumListBackgroundView.getLayoutParams().height = contentView.getHeight();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpToolBar() {
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setTitle(null);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
if (!TOOLBAR_IS_STICKY) {
|
||||
toolbar.setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
private void getIntentExtras() {
|
||||
Bundle intentExtras = getIntent().getExtras();
|
||||
final int artistId = intentExtras.getInt(AppKeys.E_ARTIST);
|
||||
artist = ArtistLoader.getArtist(this, artistId);
|
||||
if (artist == null) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_artist_detail, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_re_download_artist_image:
|
||||
Toast.makeText(ArtistDetailActivity.this, getResources().getString(R.string.updating), Toast.LENGTH_SHORT).show();
|
||||
setUpArtistImageAndApplyPalette(true);
|
||||
case R.id.action_settings:
|
||||
return true;
|
||||
case R.id.action_current_playing:
|
||||
openCurrentPlayingIfPossible(null);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
super.enableViews();
|
||||
viewPager.setEnabled(true);
|
||||
toolbar.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
super.disableViews();
|
||||
viewPager.setEnabled(false);
|
||||
toolbar.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
|
||||
}
|
||||
|
||||
private static class NavigationAdapter extends FragmentPagerAdapter {
|
||||
|
||||
private String[] titles;
|
||||
|
||||
private SparseArray<Fragment> pages; //TODO check if this must be static
|
||||
private Artist artist;
|
||||
private Context context;
|
||||
|
||||
public NavigationAdapter(Activity activity, Artist artist) {
|
||||
super(activity.getFragmentManager());
|
||||
this.artist = artist;
|
||||
pages = new SparseArray<>();
|
||||
context = activity;
|
||||
titles = new String[]{
|
||||
context.getResources().getString(R.string.tab_songs),
|
||||
context.getResources().getString(R.string.tab_albums),
|
||||
context.getResources().getString(R.string.tab_biography)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
final Bundle args = new Bundle();
|
||||
args.putInt(ARG_ARTIST_ID, artist.id);
|
||||
args.putString(ARG_ARTIST_NAME, artist.name);
|
||||
|
||||
Fragment f = getOrCreateFragmentAt(position);
|
||||
f.setArguments(args);
|
||||
|
||||
pages.put(position, f);
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||
if (0 <= pages.indexOfKey(position)) {
|
||||
pages.remove(position);
|
||||
}
|
||||
super.destroyItem(container, position, object);
|
||||
}
|
||||
|
||||
private Fragment getOrCreateFragmentAt(int position) {
|
||||
switch (position) {
|
||||
case 1:
|
||||
return pages.get(position, new ViewPagerTabArtistAlbumFragment());
|
||||
case 0:
|
||||
return pages.get(position, new ViewPagerTabArtistSongListFragment());
|
||||
case 2:
|
||||
return pages.get(position, new ViewPagerTabArtistBioFragment());
|
||||
default:
|
||||
return pages.get(position, new MainActivity.PlaceholderFragment());
|
||||
}
|
||||
}
|
||||
|
||||
public Fragment getItemAt(int position) {
|
||||
return pages.get(position, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return titles.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return titles[position];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,354 @@
|
|||
package com.kabouzeid.gramophone.ui.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.support.v13.app.FragmentPagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.google.samples.apps.iosched.ui.widget.SlidingTabLayout;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.helper.AboutDeveloperDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.PlayingQueueDialogHelper;
|
||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||
import com.kabouzeid.gramophone.interfaces.OnMusicRemoteEventListener;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.model.MusicRemoteEvent;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||
import com.kabouzeid.gramophone.ui.fragments.NavigationDrawerFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.AlbumViewFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.ArtistViewFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.MainActivityFragment;
|
||||
import com.kabouzeid.gramophone.ui.fragments.mainactivityfragments.SongViewFragment;
|
||||
import com.kabouzeid.gramophone.util.ImageLoaderUtil;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
|
||||
|
||||
public class MainActivity extends AbsFabActivity
|
||||
implements NavigationDrawerFragment.NavigationDrawerCallbacks, OnMusicRemoteEventListener, KabViewsDisableAble {
|
||||
public static final String TAG = MainActivity.class.getSimpleName();
|
||||
|
||||
private DrawerLayout drawerLayout;
|
||||
private ActionBarDrawerToggle drawerToggle;
|
||||
private NavigationDrawerFragment navigationDrawerFragment;
|
||||
private Toolbar toolbar;
|
||||
private View statusBar;
|
||||
private MainActivityViewPagerAdapter viewPagerAdapter;
|
||||
private ViewPager viewPager;
|
||||
private SlidingTabLayout slidingTabLayout;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setUpTranslucence(true, true);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
initViews();
|
||||
navigationDrawerFragment.setUp(
|
||||
R.id.navigation_drawer,
|
||||
drawerLayout
|
||||
);
|
||||
setUpToolBar();
|
||||
setUpViewPager();
|
||||
}
|
||||
|
||||
private void setUpViewPager() {
|
||||
viewPagerAdapter = new MainActivityViewPagerAdapter(this);
|
||||
viewPager.setAdapter(viewPagerAdapter);
|
||||
int startPosition = getApp().getDefaultSharedPreferences().getInt(AppKeys.SP_VIEWPAGER_ITEM_POSITION, 1);
|
||||
viewPager.setCurrentItem(startPosition);
|
||||
navigationDrawerFragment.setItemChecked(startPosition);
|
||||
|
||||
slidingTabLayout.setSelectedIndicatorColors(Util.resolveColor(MainActivity.this, R.attr.colorAccent));
|
||||
slidingTabLayout.setViewPager(viewPager);
|
||||
slidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(final int position) {
|
||||
getApp().getDefaultSharedPreferences().edit().putInt(AppKeys.SP_VIEWPAGER_ITEM_POSITION, position).apply();
|
||||
navigationDrawerFragment.setItemChecked(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
viewPager = (ViewPager) findViewById(R.id.pager);
|
||||
slidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
|
||||
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||
navigationDrawerFragment = (NavigationDrawerFragment)
|
||||
getFragmentManager().findFragmentById(R.id.navigation_drawer);
|
||||
}
|
||||
|
||||
private void setUpToolBar() {
|
||||
setTitle(getResources().getString(R.string.app_name));
|
||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
statusBar = findViewById(R.id.statusBar);
|
||||
setSupportActionBar(toolbar);
|
||||
float alpha = 0.97f;
|
||||
ViewUtil.setBackgroundAlpha(toolbar, alpha, Util.resolveColor(this, R.attr.colorPrimary));
|
||||
ViewUtil.setBackgroundAlpha(statusBar, alpha, Util.resolveColor(this, R.attr.colorPrimary));
|
||||
ViewUtil.setBackgroundAlpha(slidingTabLayout, alpha, Util.resolveColor(this, R.attr.colorPrimary));
|
||||
setUpDrawerToggle();
|
||||
}
|
||||
|
||||
private void setUpDrawerToggle() {
|
||||
drawerToggle = new ActionBarDrawerToggle(
|
||||
this,
|
||||
drawerLayout,
|
||||
R.string.navigation_drawer_open,
|
||||
R.string.navigation_drawer_close
|
||||
);
|
||||
drawerLayout.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
drawerToggle.syncState();
|
||||
}
|
||||
});
|
||||
drawerLayout.setDrawerListener(drawerToggle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
updateNavigationDrawerHeader();
|
||||
}
|
||||
|
||||
private void updateNavigationDrawerHeader() {
|
||||
if (navigationDrawerFragment != null) {
|
||||
Song song = getApp().getMusicPlayerRemote().getCurrentSong();
|
||||
if (song.id != -1) {
|
||||
ImageLoader.getInstance().displayImage(MusicUtil.getAlbumArtUri(song.albumId).toString(), navigationDrawerFragment.getAlbumArtImageView(), new ImageLoaderUtil.defaultAlbumArtOnFailed());
|
||||
navigationDrawerFragment.getSongTitle().setText(song.title);
|
||||
navigationDrawerFragment.getSongArtist().setText(song.artistName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
try {
|
||||
super.enableViews();
|
||||
toolbar.setEnabled(true);
|
||||
((MainActivityFragment)viewPagerAdapter.getItem(viewPager.getCurrentItem())).enableViews();
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(TAG, "wasn't able to enable the views", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
try {
|
||||
super.disableViews();
|
||||
((MainActivityFragment)viewPagerAdapter.getItem(viewPager.getCurrentItem())).disableViews();
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(TAG, "wasn't able to disable the views", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMusicRemoteEvent(MusicRemoteEvent event) {
|
||||
super.onMusicRemoteEvent(event);
|
||||
if (event.getAction() == MusicRemoteEvent.STATE_RESTORED || event.getAction() == MusicRemoteEvent.TRACK_CHANGED) {
|
||||
updateNavigationDrawerHeader();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNavigationDrawerItemSelected(int position) {
|
||||
if (position == NavigationDrawerFragment.NAVIGATION_DRAWER_HEADER) {
|
||||
openCurrentPlayingIfPossible(null);
|
||||
} else {
|
||||
if (viewPager != null) {
|
||||
viewPager.setCurrentItem(position, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.drawer, menu);
|
||||
restoreActionBar();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void restoreActionBar() {
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
actionBar.setDisplayShowTitleEnabled(true);
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setHomeButtonEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (drawerToggle.onOptionsItemSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case R.id.action_search:
|
||||
startActivity(new Intent(MainActivity.this, SearchActivity.class));
|
||||
return true;
|
||||
case R.id.action_settings:
|
||||
return true;
|
||||
case R.id.action_about:
|
||||
AboutDeveloperDialogHelper.getDialog(this).show();
|
||||
return true;
|
||||
case R.id.action_current_playing:
|
||||
openCurrentPlayingIfPossible(null);
|
||||
return true;
|
||||
case R.id.action_playing_queue:
|
||||
final MaterialDialog materialDialog = PlayingQueueDialogHelper.getDialog(this, this);
|
||||
if (materialDialog != null) {
|
||||
materialDialog.show();
|
||||
} else {
|
||||
Toast.makeText(this, getResources().getString(R.string.nothing_playing), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
drawerToggle.onConfigurationChanged(newConfig);
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
getApp().getMusicPlayerRemote().removeAllOnMusicRemoteEventListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (navigationDrawerFragment.isDrawerOpen()) {
|
||||
drawerLayout.closeDrawers();
|
||||
return;
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
public static class PlaceholderFragment extends MainActivityFragment {
|
||||
|
||||
public PlaceholderFragment() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View rootView = inflater.inflate(R.layout.fragment_place_holder, container, false);
|
||||
TextView text = (TextView) rootView.findViewById(R.id.text);
|
||||
text.setText("Coming soon!");
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void search(String query) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnToNonSearch() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areViewsEnabled() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class MainActivityViewPagerAdapter extends FragmentPagerAdapter {
|
||||
|
||||
private String[] titles;
|
||||
|
||||
private SparseArray<MainActivityFragment> pages; //TODO check if this must be static
|
||||
private Context context;
|
||||
|
||||
public MainActivityViewPagerAdapter(Activity activity) {
|
||||
super(activity.getFragmentManager());
|
||||
pages = new SparseArray<>();
|
||||
context = activity;
|
||||
titles = new String[]{
|
||||
context.getResources().getString(R.string.songs),
|
||||
context.getResources().getString(R.string.albums),
|
||||
context.getResources().getString(R.string.artists),
|
||||
context.getResources().getString(R.string.genres),
|
||||
context.getResources().getString(R.string.playlists)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(final int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
return pages.get(position, new SongViewFragment());
|
||||
case 1:
|
||||
return pages.get(position, new AlbumViewFragment());
|
||||
case 2:
|
||||
return pages.get(position, new ArtistViewFragment());
|
||||
case 3:
|
||||
//TODO genres
|
||||
case 4:
|
||||
//TODO playlists
|
||||
}
|
||||
return pages.get(position, new PlaceholderFragment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return titles.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return titles[position];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,440 @@
|
|||
package com.kabouzeid.gramophone.ui.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.graphics.Palette;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.helper.PlayingQueueDialogHelper;
|
||||
import com.kabouzeid.gramophone.helper.SongDetailDialogHelper;
|
||||
import com.kabouzeid.gramophone.interfaces.OnMusicRemoteEventListener;
|
||||
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistImageLoader;
|
||||
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.model.MusicRemoteEvent;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.service.MusicService;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||
import com.nineoldandroids.view.ViewPropertyAnimator;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class MusicControllerActivity extends AbsFabActivity implements OnMusicRemoteEventListener {
|
||||
public static final String TAG = MusicControllerActivity.class.getSimpleName();
|
||||
|
||||
private static final int DEFAULT_DELAY = 350;
|
||||
private static final int DEFAULT_ANIMATION_TIME = 1000;
|
||||
|
||||
private Song song;
|
||||
private ImageView albumArt;
|
||||
private ImageView artistArt;
|
||||
private TextView songTitle;
|
||||
private TextView songArtist;
|
||||
private TextView currentSongProgress;
|
||||
private TextView totalSongDuration;
|
||||
private View footer;
|
||||
private SeekBar progressSlider;
|
||||
private ImageButton nextButton;
|
||||
private ImageButton prevButton;
|
||||
private ImageButton repeatButton;
|
||||
private ImageButton shuffleButton;
|
||||
|
||||
private int lastFooterColor = -1;
|
||||
|
||||
private boolean killThreads = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setUpTranslucence(true, false);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_music_controller);
|
||||
|
||||
initViews();
|
||||
|
||||
moveSeekBarIntoPlace();
|
||||
|
||||
setUpMusicControllers();
|
||||
|
||||
prepareViewsForOpenAnimation();
|
||||
|
||||
setUpToolBar();
|
||||
}
|
||||
|
||||
private void moveSeekBarIntoPlace() {
|
||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) progressSlider.getLayoutParams();
|
||||
progressSlider.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
lp.setMargins(0, 0, 0, -(progressSlider.getMeasuredHeight() / 2));
|
||||
progressSlider.setLayoutParams(lp);
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
nextButton = (ImageButton) findViewById(R.id.next_button);
|
||||
prevButton = (ImageButton) findViewById(R.id.prev_button);
|
||||
repeatButton = (ImageButton) findViewById(R.id.repeat_button);
|
||||
shuffleButton = (ImageButton) findViewById(R.id.shuffle_button);
|
||||
albumArt = (ImageView) findViewById(R.id.album_art);
|
||||
artistArt = (ImageView) findViewById(R.id.artist_image);
|
||||
songTitle = (TextView) findViewById(R.id.song_title);
|
||||
songArtist = (TextView) findViewById(R.id.song_artist);
|
||||
currentSongProgress = (TextView) findViewById(R.id.song_current_progress);
|
||||
totalSongDuration = (TextView) findViewById(R.id.song_total_time);
|
||||
footer = findViewById(R.id.footer);
|
||||
progressSlider = (SeekBar) findViewById(R.id.progress_slider);
|
||||
}
|
||||
|
||||
private void setUpMusicControllers() {
|
||||
setUpPrevNext();
|
||||
setUpRepeatButton();
|
||||
setUpShuffleButton();
|
||||
setUpProgressSlider();
|
||||
}
|
||||
|
||||
private void setUpProgressSlider() {
|
||||
progressSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
getApp().getMusicPlayerRemote().seekTo(progress);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpPrevNext() {
|
||||
nextButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getApp().getMusicPlayerRemote().playNextSong();
|
||||
}
|
||||
});
|
||||
prevButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getApp().getMusicPlayerRemote().back();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpShuffleButton() {
|
||||
updateShuffleState();
|
||||
shuffleButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getApp().getMusicPlayerRemote().toggleShuffleMode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateShuffleState() {
|
||||
switch (getApp().getMusicPlayerRemote().getShuffleMode()) {
|
||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||
shuffleButton.setImageResource(R.drawable.ic_shuffle_white_48dp);
|
||||
break;
|
||||
default:
|
||||
shuffleButton.setImageResource(R.drawable.ic_shuffle_grey600_48dp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpRepeatButton() {
|
||||
updateRepeatState();
|
||||
repeatButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getApp().getMusicPlayerRemote().cycleRepeatMode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateRepeatState() {
|
||||
switch (getApp().getMusicPlayerRemote().getRepeatMode()) {
|
||||
case MusicService.REPEAT_MODE_NONE:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_grey600_48dp);
|
||||
break;
|
||||
case MusicService.REPEAT_MODE_ALL:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_white_48dp);
|
||||
break;
|
||||
default:
|
||||
repeatButton.setImageResource(R.drawable.ic_repeat_one_white_48dp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareViewsForOpenAnimation() {
|
||||
footer.setPivotY(0);
|
||||
footer.setScaleY(0);
|
||||
}
|
||||
|
||||
private void setUpToolBar() {
|
||||
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
|
||||
getSupportActionBar().setTitle(null);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
startMusicControllerStateUpdateThread();
|
||||
updateCurrentSong();
|
||||
}
|
||||
|
||||
private void updateCurrentSong() {
|
||||
getCurrentSong();
|
||||
setHeadersText();
|
||||
setUpArtistArt();
|
||||
setUpAlbumArtAndApplyPalette();
|
||||
totalSongDuration.setText(MusicUtil.getReadableDurationString(song.duration));
|
||||
currentSongProgress.setText(MusicUtil.getReadableDurationString(-1));
|
||||
}
|
||||
|
||||
private void setHeadersText() {
|
||||
songTitle.setText(song.title);
|
||||
songArtist.setText(song.artistName);
|
||||
}
|
||||
|
||||
private void setUpAlbumArtAndApplyPalette() {
|
||||
ImageLoader.getInstance().displayImage(MusicUtil.getAlbumArtUri(song.albumId).toString(), albumArt, new ImageLoadingListener() {
|
||||
@Override
|
||||
public void onLoadingStarted(String imageUri, View view) {
|
||||
albumArt.setImageResource(R.drawable.default_album_art);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
|
||||
albumArt.setImageResource(R.drawable.default_album_art);
|
||||
setStandardColors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingComplete(String imageUri, final View view, Bitmap loadedImage) {
|
||||
applyPalette(loadedImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingCancelled(String imageUri, View view) {
|
||||
albumArt.setImageResource(R.drawable.default_album_art);
|
||||
setStandardColors();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void applyPalette(Bitmap bitmap) {
|
||||
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
|
||||
@Override
|
||||
public void onGenerated(Palette palette) {
|
||||
Palette.Swatch swatch = palette.getVibrantSwatch();
|
||||
if (swatch != null) {
|
||||
animateColorChange(swatch.getRgb());
|
||||
songTitle.setTextColor(swatch.getTitleTextColor());
|
||||
songArtist.setTextColor(swatch.getBodyTextColor());
|
||||
} else {
|
||||
setStandardColors();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setStandardColors() {
|
||||
int songTitleTextColor = Util.resolveColor(this, R.attr.title_text_color);
|
||||
int artistNameTextColor = Util.resolveColor(this, R.attr.caption_text_color);
|
||||
int defaultBarColor = getResources().getColor(R.color.materialmusic_default_bar_color);
|
||||
|
||||
animateColorChange(defaultBarColor);
|
||||
|
||||
songTitle.setTextColor(songTitleTextColor);
|
||||
songArtist.setTextColor(artistNameTextColor);
|
||||
}
|
||||
|
||||
private void animateColorChange(final int newColor) {
|
||||
if (lastFooterColor != -1 && lastFooterColor != newColor) {
|
||||
ViewUtil.animateViewColor(footer, lastFooterColor, newColor, 300);
|
||||
} else {
|
||||
footer.setBackgroundColor(newColor);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setNavigationBarColor(newColor);
|
||||
}
|
||||
lastFooterColor = newColor;
|
||||
}
|
||||
|
||||
private void setUpArtistArt() {
|
||||
if (artistArt != null) {
|
||||
artistArt.setImageResource(R.drawable.default_artist_image);
|
||||
LastFMArtistImageLoader.loadArtistImage(this, song.artistName, new LastFMArtistImageLoader.ArtistImageLoaderCallback() {
|
||||
@Override
|
||||
public void onArtistImageLoaded(Bitmap artistImage) {
|
||||
artistArt.setImageBitmap(artistImage);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void getCurrentSong() {
|
||||
song = getApp().getMusicPlayerRemote().getCurrentSong();
|
||||
if (song.id == -1) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void startMusicControllerStateUpdateThread() {
|
||||
killThreads = false;
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int currentPosition = 0;
|
||||
int total = 0;
|
||||
while (getApp().getMusicPlayerRemote().isMusicBound() && !killThreads) {
|
||||
try {
|
||||
total = getApp().getMusicPlayerRemote().getSongDurationMillis();
|
||||
currentPosition = getApp().getMusicPlayerRemote().getSongProgressMillis();
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
final int finalTotal = total;
|
||||
final int finalCurrentPosition = currentPosition;
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressSlider.setMax(finalTotal);
|
||||
progressSlider.setProgress(finalCurrentPosition);
|
||||
currentSongProgress.setText(MusicUtil.getReadableDurationString(finalCurrentPosition));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean openCurrentPlayingIfPossible(Pair[] sharedViews) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateControllerState() {
|
||||
super.updateControllerState();
|
||||
updateRepeatState();
|
||||
updateShuffleState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMusicRemoteEvent(MusicRemoteEvent event) {
|
||||
super.onMusicRemoteEvent(event);
|
||||
switch (event.getAction()) {
|
||||
case MusicRemoteEvent.TRACK_CHANGED:
|
||||
updateCurrentSong();
|
||||
break;
|
||||
case MusicRemoteEvent.REPEAT_MODE_CHANGED:
|
||||
updateRepeatState();
|
||||
break;
|
||||
case MusicRemoteEvent.SHUFFLE_MODE_CHANGED:
|
||||
updateShuffleState();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
killThreads = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (hasFocus) {
|
||||
animateActivityOpened(DEFAULT_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_title_playing, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_playing_queue:
|
||||
final MaterialDialog materialDialog = PlayingQueueDialogHelper.getDialog(this, this);
|
||||
if (materialDialog != null) {
|
||||
materialDialog.show();
|
||||
} else {
|
||||
Toast.makeText(this, getResources().getString(R.string.nothing_playing), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
return true;
|
||||
case R.id.action_tag_editor:
|
||||
Intent intent = new Intent(this, SongTagEditorActivity.class);
|
||||
intent.putExtra(AppKeys.E_ID, song.id);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.action_details:
|
||||
String songFilePath = SongFilePathLoader.getSongFilePath(this, song.id);
|
||||
File songFile = new File(songFilePath);
|
||||
SongDetailDialogHelper.getDialog(this, songFile).show();
|
||||
return true;
|
||||
case R.id.action_go_to_album:
|
||||
goToAlbum(song.albumId, null);
|
||||
return true;
|
||||
case R.id.action_go_to_artist:
|
||||
goToArtist(song.artistId, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void animateActivityOpened(int startDelay) {
|
||||
ViewPropertyAnimator.animate(footer)
|
||||
.scaleX(1)
|
||||
.scaleY(1)
|
||||
.setInterpolator(new DecelerateInterpolator(4))
|
||||
.setDuration(DEFAULT_ANIMATION_TIME)
|
||||
.setStartDelay(startDelay)
|
||||
.start();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
package com.kabouzeid.gramophone.ui.activities;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActionBar;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.adapter.SearchAdapter;
|
||||
import com.kabouzeid.gramophone.loader.AlbumLoader;
|
||||
import com.kabouzeid.gramophone.loader.ArtistLoader;
|
||||
import com.kabouzeid.gramophone.loader.SongLoader;
|
||||
import com.kabouzeid.gramophone.model.Album;
|
||||
import com.kabouzeid.gramophone.model.Artist;
|
||||
import com.kabouzeid.gramophone.model.SearchEntry;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SearchActivity extends AbsBaseActivity {
|
||||
public static final String TAG = SearchActivity.class.getSimpleName();
|
||||
|
||||
private ListView listView;
|
||||
private SearchView searchView;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
setUpTranslucence(false, false);
|
||||
setTitle(null);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_search);
|
||||
|
||||
if (Util.hasLollipopSDK()) {
|
||||
getWindow().setStatusBarColor(Util.resolveColor(this, R.attr.colorPrimaryDark));
|
||||
getWindow().setNavigationBarColor(Util.resolveColor(this, R.attr.colorPrimaryDark));
|
||||
}
|
||||
|
||||
listView = (ListView) findViewById(R.id.list);
|
||||
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
Object item = parent.getItemAtPosition(position);
|
||||
if (item instanceof SearchEntry) {
|
||||
if (item instanceof Song) {
|
||||
List<Song> playList = new ArrayList<>();
|
||||
playList.add((Song) item);
|
||||
getApp().getMusicPlayerRemote().openQueue(playList, 0, true);
|
||||
} else if (item instanceof Album) {
|
||||
goToAlbum(((Album) item).id, new Pair[]{Pair.create(view.findViewById(R.id.image), getResources().getString(R.string.transition_album_cover))});
|
||||
} else if (item instanceof Artist) {
|
||||
goToArtist(((Artist) item).id, new Pair[]{Pair.create(view.findViewById(R.id.image), getResources().getString(R.string.transition_artist_image))});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
listView.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
Util.hideSoftKeyboard(SearchActivity.this);
|
||||
if(searchView != null){
|
||||
searchView.clearFocus();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
super.enableViews();
|
||||
listView.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
super.disableViews();
|
||||
listView.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_search, menu);
|
||||
|
||||
final MenuItem search = menu.findItem(R.id.action_search);
|
||||
searchView = (SearchView) MenuItemCompat.getActionView(search);
|
||||
searchView.setIconified(false);
|
||||
searchView.setIconifiedByDefault(false);
|
||||
|
||||
ActionBar.LayoutParams params = new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT);
|
||||
searchView.setLayoutParams(params);
|
||||
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
onQueryTextChange(query);
|
||||
Util.hideSoftKeyboard(SearchActivity.this);
|
||||
searchView.clearFocus();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
search(newText);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
MenuItemCompat.setOnActionExpandListener(search, new MenuItemCompat.OnActionExpandListener() {
|
||||
@Override
|
||||
public boolean onMenuItemActionExpand(MenuItem item) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemActionCollapse(MenuItem item) {
|
||||
finish();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
MenuItemCompat.expandActionView(search);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.action_settings) {
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void search(String query) {
|
||||
List<SearchEntry> results = new ArrayList<>();
|
||||
if (!query.trim().equals("")) {
|
||||
LabelEntry songLabel = new LabelEntry(getResources().getString(R.string.songs).toUpperCase());
|
||||
results.add(songLabel);
|
||||
List<Song> songs = SongLoader.getSongs(this, query);
|
||||
results.addAll(songs);
|
||||
songLabel.setNumber(songs.size());
|
||||
|
||||
LabelEntry artistLabel = new LabelEntry(getResources().getString(R.string.artists).toUpperCase());
|
||||
results.add(artistLabel);
|
||||
List<Artist> artists = ArtistLoader.getArtists(this, query);
|
||||
results.addAll(artists);
|
||||
artistLabel.setNumber(artists.size());
|
||||
|
||||
LabelEntry albumLabel = new LabelEntry(getResources().getString(R.string.albums).toUpperCase());
|
||||
results.add(albumLabel);
|
||||
List<Album> albums = AlbumLoader.getAlbums(this, query);
|
||||
results.addAll(albums);
|
||||
albumLabel.setNumber(albums.size());
|
||||
}
|
||||
if(results.size() <= 3){
|
||||
results.clear();
|
||||
results.add(new LabelEntry(getResources().getString(R.string.no_results).toUpperCase()));
|
||||
}
|
||||
ArrayAdapter adapter = new SearchAdapter(this, results);
|
||||
listView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class LabelEntry implements SearchEntry {
|
||||
String title;
|
||||
String label;
|
||||
|
||||
public LabelEntry(String label) {
|
||||
this.label = label;
|
||||
this.title = label;
|
||||
}
|
||||
|
||||
public void setNumber(int number){
|
||||
if(number != -1) {
|
||||
label = title + " (" + number + ")";
|
||||
} else {
|
||||
label = title;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSubTitle() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadImage(Context context, ImageView imageView) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package com.kabouzeid.gramophone.ui.activities.base;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.ActivityOptionsCompat;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.adapter.songadapter.SongAdapter;
|
||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.ui.activities.AlbumDetailActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.ArtistDetailActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.MusicControllerActivity;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
|
||||
/**
|
||||
* Created by karim on 20.01.15.
|
||||
*/
|
||||
public abstract class AbsBaseActivity extends ActionBarActivity implements KabViewsDisableAble, SongAdapter.GoToAble {
|
||||
private App app;
|
||||
private boolean areViewsEnabled;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
Crashlytics.setString(AppKeys.CL_CURRENT_ACTIVITY, getTag());
|
||||
setTheme(getApp().getAppTheme());
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
protected App getApp() {
|
||||
if (app == null) {
|
||||
app = (App) getApplicationContext();
|
||||
}
|
||||
return app;
|
||||
}
|
||||
|
||||
public abstract String getTag();
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
enableViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
areViewsEnabled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
areViewsEnabled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areViewsEnabled() {
|
||||
return areViewsEnabled;
|
||||
}
|
||||
|
||||
protected void setUpTranslucence(boolean statusBarTranslucent, boolean navigationBarTranslucent) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
Util.setStatusBarTranslucent(getWindow(), statusBarTranslucent);
|
||||
if (getApp().isInPortraitMode() || getApp().isTablet()) {
|
||||
Util.setNavBarTranslucent(getWindow(), navigationBarTranslucent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean openCurrentPlayingIfPossible(Pair[] sharedViews) {
|
||||
if (getApp().getMusicPlayerRemote().getPosition() != -1) {
|
||||
if (areViewsEnabled()) {
|
||||
disableViews();
|
||||
Intent intent = new Intent(this, MusicControllerActivity.class);
|
||||
if (sharedViews != null) {
|
||||
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this,
|
||||
sharedViews
|
||||
);
|
||||
ActivityCompat.startActivity(this, intent, optionsCompat.toBundle());
|
||||
} else {
|
||||
startActivity(intent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(this, getResources().getString(R.string.nothing_playing), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goToAlbum(int albumId) {
|
||||
goToAlbum(albumId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goToArtist(int artistId) {
|
||||
goToArtist(artistId, null);
|
||||
}
|
||||
|
||||
public void goToArtist(int artistId, Pair[] sharedViews) {
|
||||
if(areViewsEnabled()) {
|
||||
disableViews();
|
||||
final Intent intent = new Intent(this, ArtistDetailActivity.class);
|
||||
intent.putExtra(AppKeys.E_ARTIST, artistId);
|
||||
if (sharedViews != null) {
|
||||
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this,
|
||||
sharedViews
|
||||
);
|
||||
ActivityCompat.startActivity(this, intent, optionsCompat.toBundle());
|
||||
} else {
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void goToAlbum(int albumId, Pair[] sharedViews) {
|
||||
if(areViewsEnabled()) {
|
||||
disableViews();
|
||||
final Intent intent = new Intent(this, AlbumDetailActivity.class);
|
||||
intent.putExtra(AppKeys.E_ALBUM, albumId);
|
||||
if (sharedViews != null) {
|
||||
ActivityOptionsCompat optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this,
|
||||
sharedViews
|
||||
);
|
||||
ActivityCompat.startActivity(this, intent, optionsCompat.toBundle());
|
||||
} else {
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
package com.kabouzeid.gramophone.ui.activities.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.interfaces.OnMusicRemoteEventListener;
|
||||
import com.kabouzeid.gramophone.misc.SmallOnGestureListener;
|
||||
import com.kabouzeid.gramophone.model.MusicRemoteEvent;
|
||||
import com.melnykov.fab.FloatingActionButton;
|
||||
|
||||
/**
|
||||
* Created by karim on 22.01.15.
|
||||
*/
|
||||
public abstract class AbsFabActivity extends AbsBaseActivity implements OnMusicRemoteEventListener {
|
||||
private FloatingActionButton fab;
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
setUpFab();
|
||||
}
|
||||
|
||||
private void setUpFab() {
|
||||
updateFabState();
|
||||
final GestureDetector gestureDetector = new GestureDetector(this, new SmallOnGestureListener() {
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
openCurrentPlayingIfPossible(null);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
getFab().setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getApp().getMusicPlayerRemote().getPosition() != -1) {
|
||||
if (getApp().getMusicPlayerRemote().isPlaying()) {
|
||||
getApp().getMusicPlayerRemote().pauseSong();
|
||||
} else {
|
||||
getApp().getMusicPlayerRemote().resumePlaying();
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(AbsFabActivity.this, getResources().getString(R.string.nothing_playing), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getFab().setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
Toast.makeText(AbsFabActivity.this, getResources().getString(R.string.hint_fling_to_open), Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
getFab().setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent event) {
|
||||
gestureDetector.onTouchEvent(event);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateFabState() {
|
||||
if (getApp().getMusicPlayerRemote().isPlaying()) {
|
||||
getFab().setImageResource(R.drawable.ic_pause_white_24dp);
|
||||
} else {
|
||||
getFab().setImageResource(R.drawable.ic_play_arrow_white_24dp);
|
||||
}
|
||||
}
|
||||
|
||||
protected FloatingActionButton getFab() {
|
||||
if (fab == null) {
|
||||
fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||
if (fab == null) {
|
||||
fab = new FloatingActionButton(this);
|
||||
Log.e(getTag(), "No FAB found created default FAB.");
|
||||
}
|
||||
}
|
||||
return fab;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
updateControllerState();
|
||||
getApp().getMusicPlayerRemote().addOnMusicRemoteEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
super.enableViews();
|
||||
getFab().setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
super.disableViews();
|
||||
getFab().setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean openCurrentPlayingIfPossible(Pair[] sharedViews) {
|
||||
return super.openCurrentPlayingIfPossible(getSharedViewsWithFab(sharedViews));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goToArtist(int artistId, Pair[] sharedViews) {
|
||||
super.goToArtist(artistId, getSharedViewsWithFab(sharedViews));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void goToAlbum(int albumId, Pair[] sharedViews) {
|
||||
super.goToAlbum(albumId, getSharedViewsWithFab(sharedViews));
|
||||
}
|
||||
|
||||
private Pair[] getSharedViewsWithFab(Pair[] sharedViews) {
|
||||
Pair[] sharedViewsWithFab;
|
||||
if (sharedViews != null) {
|
||||
sharedViewsWithFab = new Pair[sharedViews.length + 1];
|
||||
for (int i = 0; i < sharedViews.length; i++) {
|
||||
sharedViewsWithFab[i] = sharedViews[i];
|
||||
}
|
||||
} else {
|
||||
sharedViewsWithFab = new Pair[1];
|
||||
}
|
||||
sharedViewsWithFab[sharedViewsWithFab.length - 1] = Pair.create((View) getFab(), getString(R.string.transition_fab));
|
||||
return sharedViewsWithFab;
|
||||
}
|
||||
|
||||
protected void updateControllerState() {
|
||||
updateFabState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
getApp().getMusicPlayerRemote().removeOnMusicRemoteEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMusicRemoteEvent(MusicRemoteEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MusicRemoteEvent.PLAY:
|
||||
getFab().setImageDrawable(getResources().getDrawable(R.drawable.ic_pause_white_24dp));
|
||||
break;
|
||||
case MusicRemoteEvent.PAUSE:
|
||||
getFab().setImageDrawable(getResources().getDrawable(R.drawable.ic_play_arrow_white_24dp));
|
||||
break;
|
||||
case MusicRemoteEvent.RESUME:
|
||||
getFab().setImageDrawable(getResources().getDrawable(R.drawable.ic_pause_white_24dp));
|
||||
break;
|
||||
case MusicRemoteEvent.STOP:
|
||||
getFab().setImageDrawable(getResources().getDrawable(R.drawable.ic_play_arrow_white_24dp));
|
||||
break;
|
||||
case MusicRemoteEvent.QUEUE_COMPLETED:
|
||||
getFab().setImageResource(R.drawable.ic_play_arrow_white_24dp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,497 @@
|
|||
package com.kabouzeid.gramophone.ui.activities.tageditor;
|
||||
|
||||
import android.app.SearchManager;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.graphics.Palette;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.misc.SmallObservableScrollViewCallbacks;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||
import com.melnykov.fab.FloatingActionButton;
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
import com.nineoldandroids.view.ViewPropertyAnimator;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.utils.MemoryCacheUtils;
|
||||
|
||||
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 java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by karim on 18.01.15.
|
||||
*/
|
||||
public abstract class AbsTagEditorActivity extends ActionBarActivity {
|
||||
public static final String TAG = AbsTagEditorActivity.class.getSimpleName();
|
||||
private static final int REQUEST_CODE_SELECT_IMAGE = 1337;
|
||||
|
||||
private App app;
|
||||
private int id;
|
||||
private int headerVariableSpace;
|
||||
private int paletteColorPrimary;
|
||||
private boolean isInNoImageMode;
|
||||
|
||||
private FloatingActionButton fab;
|
||||
private ObservableScrollView scrollView;
|
||||
private Toolbar toolBar;
|
||||
private ImageView image;
|
||||
private View header;
|
||||
private SmallObservableScrollViewCallbacks observableScrollViewCallbacks = new SmallObservableScrollViewCallbacks() {
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||
float alpha;
|
||||
if (!isInNoImageMode) {
|
||||
alpha = 1 - (float) Math.max(0, headerVariableSpace - scrollY) / headerVariableSpace;
|
||||
} else {
|
||||
ViewHelper.setTranslationY(header, scrollY);
|
||||
alpha = 1;
|
||||
}
|
||||
ViewUtil.setBackgroundAlpha(toolBar, alpha, paletteColorPrimary);
|
||||
ViewUtil.setBackgroundAlpha(header, alpha, paletteColorPrimary);
|
||||
ViewHelper.setTranslationY(image, scrollY / 2);
|
||||
}
|
||||
};
|
||||
private List<String> songPaths;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
app = (App) getApplicationContext();
|
||||
setTheme(app.getAppTheme());
|
||||
setUpTranslucence();
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(getContentViewResId());
|
||||
|
||||
getIntentExtras();
|
||||
headerVariableSpace = getResources().getDimensionPixelSize(R.dimen.tagEditorHeaderVariableSpace);
|
||||
songPaths = getSongPaths();
|
||||
|
||||
initViews();
|
||||
setUpViews();
|
||||
setUpToolBar();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
fab = (FloatingActionButton) findViewById(R.id.fab);
|
||||
scrollView = (ObservableScrollView) findViewById(R.id.observableScrollView);
|
||||
toolBar = (Toolbar) findViewById(R.id.toolbar);
|
||||
image = (ImageView) findViewById(R.id.image);
|
||||
header = findViewById(R.id.header);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
restoreStandardColors();
|
||||
setUpScrollView();
|
||||
setUpFab();
|
||||
setUpImageView();
|
||||
}
|
||||
|
||||
private void setUpScrollView() {
|
||||
scrollView.setScrollViewCallbacks(observableScrollViewCallbacks);
|
||||
scrollView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollView.scrollVerticallyTo(headerVariableSpace / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpImageView() {
|
||||
loadCurrentImage();
|
||||
image.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
new MaterialDialog.Builder(AbsTagEditorActivity.this)
|
||||
.title("Update image")
|
||||
.items(new CharSequence[]{"Download from LastFM", "Pick from internal storage", "Web search", "Delete"})
|
||||
.itemsCallback(new MaterialDialog.ListCallback() {
|
||||
@Override
|
||||
public void onSelection(MaterialDialog dialog, View view, int which, CharSequence text) {
|
||||
switch (which) {
|
||||
case 0:
|
||||
getImageFromLastFM();
|
||||
break;
|
||||
case 1:
|
||||
startImagePicker();
|
||||
break;
|
||||
case 2:
|
||||
searchImageOnWeb();
|
||||
break;
|
||||
case 3:
|
||||
deleteImage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
.build()
|
||||
.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startImagePicker() {
|
||||
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
|
||||
photoPickerIntent.setType("image/*");
|
||||
startActivityForResult(photoPickerIntent, REQUEST_CODE_SELECT_IMAGE);
|
||||
}
|
||||
|
||||
protected abstract void loadCurrentImage();
|
||||
|
||||
protected abstract void getImageFromLastFM();
|
||||
|
||||
protected abstract void searchImageOnWeb();
|
||||
|
||||
protected abstract void deleteImage();
|
||||
|
||||
protected void setUpFab() {
|
||||
ViewHelper.setScaleX(fab, 0);
|
||||
ViewHelper.setScaleY(fab, 0);
|
||||
fab.setEnabled(false);
|
||||
fab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
save();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract void save();
|
||||
|
||||
private void restoreStandardColors() {
|
||||
final int vibrantColor = Util.resolveColor(this, R.attr.colorPrimary);
|
||||
paletteColorPrimary = vibrantColor;
|
||||
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setStatusBarColor(vibrantColor);
|
||||
getWindow().setNavigationBarColor(vibrantColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpTranslucence() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
Util.setStatusBarTranslucent(getWindow(), false);
|
||||
Util.setNavBarTranslucent(getWindow(), false);
|
||||
}
|
||||
}
|
||||
|
||||
private void getIntentExtras() {
|
||||
Bundle intentExtras = getIntent().getExtras();
|
||||
if (intentExtras != null) {
|
||||
id = intentExtras.getInt(AppKeys.E_ID);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setUpToolBar() {
|
||||
setSupportActionBar(toolBar);
|
||||
getSupportActionBar().setTitle(getResources().getString(R.string.tag_editor));
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
protected abstract int getContentViewResId();
|
||||
|
||||
protected abstract List<String> getSongPaths();
|
||||
|
||||
protected void searchWebFor(List<String> strings) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (String string : strings) {
|
||||
stringBuilder.append(string);
|
||||
stringBuilder.append(" ");
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
|
||||
intent.putExtra(SearchManager.QUERY, stringBuilder.toString());
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_tag_editor, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
super.onBackPressed();
|
||||
return true;
|
||||
case R.id.action_settings:
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
protected void setNoImageMode() {
|
||||
isInNoImageMode = true;
|
||||
image.setVisibility(View.GONE);
|
||||
image.setEnabled(false);
|
||||
scrollView.setPadding(0, Util.getActionBarSize(this), 0, 0);
|
||||
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
||||
}
|
||||
|
||||
protected void dataChanged() {
|
||||
showFab();
|
||||
}
|
||||
|
||||
private void showFab() {
|
||||
ViewPropertyAnimator.animate(fab)
|
||||
.setDuration(500)
|
||||
.setInterpolator(new OvershootInterpolator())
|
||||
.scaleX(1)
|
||||
.scaleY(1)
|
||||
.start();
|
||||
fab.setEnabled(true);
|
||||
}
|
||||
|
||||
protected void setImageRes(int resId) {
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);
|
||||
setImageBitmap(bitmap);
|
||||
}
|
||||
|
||||
protected void setImageBitmap(final Bitmap bitmap) {
|
||||
if (bitmap != null) {
|
||||
image.setImageBitmap(bitmap);
|
||||
applyPalette(bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyPalette(final Bitmap bitmap) {
|
||||
if (bitmap != null) {
|
||||
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
|
||||
@Override
|
||||
public void onGenerated(Palette palette) {
|
||||
final int vibrantColor = palette.getVibrantColor(getResources().getColor(R.color.materialmusic_default_bar_color));
|
||||
paletteColorPrimary = vibrantColor;
|
||||
observableScrollViewCallbacks.onScrollChanged(scrollView.getCurrentScrollY(), false, false);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setStatusBarColor(vibrantColor);
|
||||
getWindow().setNavigationBarColor(vibrantColor);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
restoreStandardColors();
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap) {
|
||||
writeValuesToFiles(fieldKeyValueMap, null, false);
|
||||
}
|
||||
|
||||
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap, final Artwork artwork, final boolean deleteArtwork) {
|
||||
Util.hideSoftKeyboard(this);
|
||||
final String writingFileStr = getResources().getString(R.string.writing_file_number);
|
||||
final String savingStr = getResources().getString(R.string.saving_changes);
|
||||
final MaterialDialog progressDialog = new MaterialDialog.Builder(AbsTagEditorActivity.this)
|
||||
.title(savingStr)
|
||||
.cancelable(false)
|
||||
.progress(true, 0)
|
||||
.build();
|
||||
progressDialog.show();
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < songPaths.size(); i++) {
|
||||
String songPath = songPaths.get(i);
|
||||
final int finalI = i;
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
progressDialog.setContent(writingFileStr + " " + ((finalI + 1) + "/" + songPaths.size()));
|
||||
}
|
||||
});
|
||||
try {
|
||||
AudioFile audioFile = AudioFileIO.read(new File(songPath));
|
||||
Tag tag = audioFile.getTagOrCreateAndSetDefault();
|
||||
for (Map.Entry<FieldKey, String> entry : fieldKeyValueMap.entrySet()) {
|
||||
try {
|
||||
tag.setField(entry.getKey(), entry.getValue());
|
||||
} catch (NumberFormatException e) {
|
||||
tag.deleteField(entry.getKey());
|
||||
}
|
||||
}
|
||||
if (deleteArtwork) {
|
||||
tag.deleteArtworkField();
|
||||
} else if (artwork != null) {
|
||||
tag.deleteArtworkField();
|
||||
tag.setField(artwork);
|
||||
}
|
||||
audioFile.commit();
|
||||
} catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||
Log.e(TAG, "Error while reading audio file.", e);
|
||||
} catch (CannotWriteException e) {
|
||||
Log.e(TAG, "Error while writing audio file.", e);
|
||||
}
|
||||
}
|
||||
if (deleteArtwork) {
|
||||
String imagePath = MusicUtil.getAlbumArtUri(getId()).toString();
|
||||
ImageLoader.getInstance().getDiskCache().remove(imagePath);
|
||||
MemoryCacheUtils.removeFromCache(imagePath, ImageLoader.getInstance().getMemoryCache());
|
||||
MusicUtil.deleteAlbumArt(AbsTagEditorActivity.this, getId());
|
||||
} else if (artwork != null) {
|
||||
String imagePath = MusicUtil.getAlbumArtUri(getId()).toString();
|
||||
MemoryCacheUtils.removeFromCache(imagePath, ImageLoader.getInstance().getMemoryCache());
|
||||
ImageLoader.getInstance().getDiskCache().remove(imagePath);
|
||||
}
|
||||
progressDialog.dismiss();
|
||||
rescanMedia();
|
||||
restartApp();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void rescanMedia() {
|
||||
String[] toBeScanned = new String[songPaths.size()];
|
||||
toBeScanned = songPaths.toArray(toBeScanned);
|
||||
MediaScannerConnection.scanFile(this, toBeScanned, null, null);
|
||||
}
|
||||
|
||||
private void restartApp() {
|
||||
Intent i = getBaseContext().getPackageManager()
|
||||
.getLaunchIntentForPackage(getBaseContext().getPackageName());
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
startActivity(i);
|
||||
}
|
||||
|
||||
protected int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap, final Artwork artwork) {
|
||||
if (artwork == null) {
|
||||
writeValuesToFiles(fieldKeyValueMap, null, true);
|
||||
} else {
|
||||
writeValuesToFiles(fieldKeyValueMap, artwork, false);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeValuesToFiles(final Map<FieldKey, String> fieldKeyValueMap, boolean deleteArtwork) {
|
||||
writeValuesToFiles(fieldKeyValueMap, null, deleteArtwork);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
|
||||
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
|
||||
switch (requestCode) {
|
||||
case REQUEST_CODE_SELECT_IMAGE:
|
||||
if (resultCode == RESULT_OK) {
|
||||
Uri selectedImage = imageReturnedIntent.getData();
|
||||
loadImageFromFile(selectedImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void loadImageFromFile(Uri selectedFile);
|
||||
|
||||
protected App getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
protected String getSongTitle() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.TITLE);
|
||||
} catch (NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private AudioFile getAudioFile(String path) {
|
||||
try {
|
||||
return AudioFileIO.read(new File(path));
|
||||
} catch (CannotReadException | ReadOnlyFileException | InvalidAudioFrameException | TagException | IOException e) {
|
||||
Log.e(TAG, "Error while trying to create the AudioFile from java.io.File", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getAlbumTitle() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ALBUM);
|
||||
} catch (NullPointerException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getArtistName() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ARTIST);
|
||||
} catch (NullPointerException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getAlbumArtistName() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.ALBUM_ARTIST);
|
||||
} catch (NullPointerException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getGenreName() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.GENRE);
|
||||
} catch (NullPointerException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getSongYear() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.YEAR);
|
||||
} catch (NullPointerException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getTrackNumber() {
|
||||
try {
|
||||
return getAudioFile(songPaths.get(0)).getTagOrCreateAndSetDefault().getFirst(FieldKey.TRACK);
|
||||
} catch (NullPointerException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
} catch (NullPointerException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
package com.kabouzeid.gramophone.ui.activities.tageditor;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.lastfm.album.LastFMAlbumImageLoader;
|
||||
import com.kabouzeid.gramophone.loader.AlbumSongLoader;
|
||||
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.process.BitmapProcessor;
|
||||
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
import org.jaudiotagger.tag.images.Artwork;
|
||||
import org.jaudiotagger.tag.images.ArtworkFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AlbumTagEditorActivity extends AbsTagEditorActivity implements TextWatcher {
|
||||
public static final String TAG = AlbumTagEditorActivity.class.getSimpleName();
|
||||
|
||||
private File albumArtFile;
|
||||
private Bitmap albumArtBitmap;
|
||||
private boolean deleteAlbumArt;
|
||||
|
||||
private EditText albumTitle;
|
||||
private EditText albumArtistName;
|
||||
private EditText genreName;
|
||||
private EditText year;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
initViews();
|
||||
setUpViews();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
albumTitle = (EditText) findViewById(R.id.album_title);
|
||||
albumArtistName = (EditText) findViewById(R.id.album_artist);
|
||||
genreName = (EditText) findViewById(R.id.genre);
|
||||
year = (EditText) findViewById(R.id.year);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
fillViewsWithFileTags();
|
||||
albumTitle.addTextChangedListener(this);
|
||||
albumArtistName.addTextChangedListener(this);
|
||||
genreName.addTextChangedListener(this);
|
||||
year.addTextChangedListener(this);
|
||||
}
|
||||
|
||||
|
||||
private void fillViewsWithFileTags() {
|
||||
albumTitle.setText(getAlbumTitle());
|
||||
albumArtistName.setText(getAlbumArtistName());
|
||||
genreName.setText(getGenreName());
|
||||
year.setText(getSongYear());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadCurrentImage() {
|
||||
setImageBitmap(getAlbumArt());
|
||||
deleteAlbumArt = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getImageFromLastFM() {
|
||||
String albumTitleStr = albumTitle.getText().toString();
|
||||
String albumArtistNameStr = albumArtistName.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;
|
||||
}
|
||||
LastFMAlbumImageLoader.loadAlbumImage(this, albumTitleStr, albumArtistNameStr, new LastFMAlbumImageLoader.AlbumImageLoaderCallback() {
|
||||
@Override
|
||||
public void onAlbumImageLoaded(Bitmap albumImage, String uri) {
|
||||
if (albumImage != null) {
|
||||
setImageBitmap(albumImage);
|
||||
albumArtBitmap = albumImage;
|
||||
deleteAlbumArt = false;
|
||||
dataChanged();
|
||||
Toast.makeText(AlbumTagEditorActivity.this, "Success.", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(AlbumTagEditorActivity.this, "Failed.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void searchImageOnWeb() {
|
||||
List<String> query = new ArrayList<>();
|
||||
query.add(albumTitle.getText().toString());
|
||||
query.add(albumArtistName.getText().toString());
|
||||
searchWebFor(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteImage() {
|
||||
setImageRes(R.drawable.default_album_art);
|
||||
deleteAlbumArt = true;
|
||||
dataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void save() {
|
||||
Artwork artwork = null;
|
||||
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, albumArtistName.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.ALBUM_ARTIST, albumArtistName.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.GENRE, genreName.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString());
|
||||
|
||||
try {
|
||||
albumArtFile = MusicUtil.getAlbumArtFile(this, String.valueOf(getId()));
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "error while creating albumArtFile", e);
|
||||
}
|
||||
|
||||
if (albumArtBitmap != null && albumArtFile != null) {
|
||||
try {
|
||||
albumArtBitmap.compress(Bitmap.CompressFormat.PNG, 0, new FileOutputStream(albumArtFile));
|
||||
artwork = ArtworkFactory.createArtworkFromFile(albumArtFile);
|
||||
MusicUtil.insertAlbumArt(this, getId(), albumArtFile.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "error while trying to create the artwork from file", e);
|
||||
}
|
||||
}
|
||||
writeValuesToFiles(fieldKeyValueMap, artwork, deleteAlbumArt);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContentViewResId() {
|
||||
return R.layout.activity_album_tag_editor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getSongPaths() {
|
||||
List<Song> songs = AlbumSongLoader.getAlbumSongList(this, getId());
|
||||
int[] songIds = new int[songs.size()];
|
||||
for (int i = 0; i < songs.size(); i++) {
|
||||
songIds[i] = songs.get(i).id;
|
||||
}
|
||||
return SongFilePathLoader.getSongFilePaths(this, songIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadImageFromFile(final Uri selectedFileUri) {
|
||||
DisplayImageOptions options = new DisplayImageOptions.Builder()
|
||||
.cacheInMemory(true)
|
||||
.cacheOnDisk(false)
|
||||
.postProcessor(new BitmapProcessor() {
|
||||
@Override
|
||||
public Bitmap process(Bitmap bmp) {
|
||||
Bitmap scaledBitmap = Util.getAlbumArtScaledBitmap(bmp, true);
|
||||
bmp.recycle();
|
||||
return scaledBitmap;
|
||||
}
|
||||
})
|
||||
.build();
|
||||
albumArtBitmap = ImageLoader.getInstance().loadImageSync(selectedFileUri.toString(), options);
|
||||
if (albumArtBitmap != null) {
|
||||
setImageBitmap(albumArtBitmap);
|
||||
deleteAlbumArt = false;
|
||||
dataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
package com.kabouzeid.gramophone.ui.activities.tageditor;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.EditText;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.loader.SongFilePathLoader;
|
||||
|
||||
import org.jaudiotagger.tag.FieldKey;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SongTagEditorActivity extends AbsTagEditorActivity implements TextWatcher {
|
||||
public static final String TAG = SongTagEditorActivity.class.getSimpleName();
|
||||
|
||||
private EditText songTitle;
|
||||
private EditText albumTitle;
|
||||
private EditText artistName;
|
||||
private EditText genreName;
|
||||
private EditText year;
|
||||
private EditText trackNumber;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setNoImageMode();
|
||||
initViews();
|
||||
setUpViews();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
songTitle = (EditText) findViewById(R.id.title1);
|
||||
albumTitle = (EditText) findViewById(R.id.title2);
|
||||
artistName = (EditText) findViewById(R.id.artist);
|
||||
genreName = (EditText) findViewById(R.id.genre);
|
||||
year = (EditText) findViewById(R.id.year);
|
||||
trackNumber = (EditText) findViewById(R.id.track_number);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
fillViewsWithFileTags();
|
||||
songTitle.addTextChangedListener(this);
|
||||
albumTitle.addTextChangedListener(this);
|
||||
artistName.addTextChangedListener(this);
|
||||
genreName.addTextChangedListener(this);
|
||||
year.addTextChangedListener(this);
|
||||
trackNumber.addTextChangedListener(this);
|
||||
}
|
||||
|
||||
|
||||
private void fillViewsWithFileTags() {
|
||||
songTitle.setText(getSongTitle());
|
||||
albumTitle.setText(getAlbumTitle());
|
||||
artistName.setText(getArtistName());
|
||||
genreName.setText(getGenreName());
|
||||
year.setText(getSongYear());
|
||||
trackNumber.setText(getTrackNumber());
|
||||
}
|
||||
|
||||
@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, artistName.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.GENRE, genreName.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.YEAR, year.getText().toString());
|
||||
fieldKeyValueMap.put(FieldKey.TRACK, trackNumber.getText().toString());
|
||||
writeValuesToFiles(fieldKeyValueMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContentViewResId() {
|
||||
return R.layout.activity_song_tag_editor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getSongPaths() {
|
||||
return SongFilePathLoader.getSongFilePaths(this, new int[]{getId()});
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
package com.kabouzeid.gramophone.ui.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.adapter.NavigationDrawerItemAdapter;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.model.NavigationDrawerItem;
|
||||
import com.nhaarman.listviewanimations.appearance.simple.AlphaInAnimationAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class NavigationDrawerFragment extends Fragment {
|
||||
public static final int NAVIGATION_DRAWER_HEADER = -1;
|
||||
private static final String TAG = NavigationDrawerFragment.class.getSimpleName();
|
||||
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
|
||||
public View fragmentRootView;
|
||||
private App app;
|
||||
private NavigationDrawerCallbacks callbacks;
|
||||
private NavigationDrawerItemAdapter drawerAdapter;
|
||||
private DrawerLayout drawerLayout;
|
||||
private ListView drawerListView;
|
||||
private View fragmentContainerView;
|
||||
|
||||
private Button headerButton;
|
||||
private ImageView albumArt;
|
||||
private TextView songTitle;
|
||||
private TextView songArtist;
|
||||
|
||||
private boolean fromSavedInstanceState;
|
||||
private boolean userLearnedDrawer;
|
||||
|
||||
private int checkedPosition = 0;
|
||||
|
||||
public NavigationDrawerFragment() {
|
||||
}
|
||||
|
||||
public boolean isDrawerOpen() {
|
||||
return drawerLayout != null && drawerLayout.isDrawerOpen(fragmentContainerView);
|
||||
}
|
||||
|
||||
public void setUp(int fragmentId, final DrawerLayout drawerLayout) {
|
||||
fragmentContainerView = getActivity().findViewById(fragmentId);
|
||||
this.drawerLayout = drawerLayout;
|
||||
this.drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
|
||||
|
||||
|
||||
if (!userLearnedDrawer && !fromSavedInstanceState) {
|
||||
this.drawerLayout.openDrawer(fragmentContainerView);
|
||||
userLearnedDrawer = true;
|
||||
app.getDefaultSharedPreferences().edit().putBoolean(AppKeys.SP_USER_LEARNED_DRAWER, true).apply();
|
||||
}
|
||||
}
|
||||
|
||||
public TextView getSongArtist() {
|
||||
return songArtist;
|
||||
}
|
||||
|
||||
public ImageView getAlbumArtImageView() {
|
||||
return albumArt;
|
||||
}
|
||||
|
||||
public TextView getSongTitle() {
|
||||
return songTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
callbacks = (NavigationDrawerCallbacks) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
app = (App) getActivity().getApplicationContext();
|
||||
userLearnedDrawer = app.getDefaultSharedPreferences().getBoolean(AppKeys.SP_USER_LEARNED_DRAWER, false);
|
||||
if (savedInstanceState != null) {
|
||||
setItemChecked(savedInstanceState.getInt(STATE_SELECTED_POSITION));
|
||||
fromSavedInstanceState = true;
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
fragmentRootView = view;
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
initViews();
|
||||
setUpViews();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
drawerListView = (ListView) fragmentRootView.findViewById(R.id.navigation_drawer_list);
|
||||
final View drawerHeader = fragmentRootView.findViewById(R.id.header);
|
||||
headerButton = (Button) drawerHeader.findViewById(R.id.header_clickable);
|
||||
albumArt = (ImageView) drawerHeader.findViewById(R.id.album_art);
|
||||
songTitle = (TextView) drawerHeader.findViewById(R.id.song_title);
|
||||
songArtist = (TextView) drawerHeader.findViewById(R.id.song_artist);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
headerButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
selectItem(NAVIGATION_DRAWER_HEADER);
|
||||
}
|
||||
});
|
||||
setUpListView();
|
||||
}
|
||||
|
||||
private void setUpListView() {
|
||||
final ArrayList<NavigationDrawerItem> navigationDrawerItems = new ArrayList<>();
|
||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.songs), R.drawable.ic_my_library_music_white_24dp));
|
||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.albums), R.drawable.ic_album_white_24dp));
|
||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.artists), R.drawable.ic_person_white_24dp));
|
||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.genres), R.drawable.ic_my_library_music_white_24dp));
|
||||
navigationDrawerItems.add(new NavigationDrawerItem(getString(R.string.playlists), R.drawable.ic_queue_music_white_24dp));
|
||||
|
||||
drawerAdapter = new NavigationDrawerItemAdapter(getActivity(), R.id.navigation_drawer, navigationDrawerItems);
|
||||
|
||||
final AlphaInAnimationAdapter animationAdapter = new AlphaInAnimationAdapter(drawerAdapter);
|
||||
animationAdapter.setAbsListView(drawerListView);
|
||||
|
||||
drawerListView.setAdapter(animationAdapter);
|
||||
drawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
selectItem(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void selectItem(final int position) {
|
||||
if (position != NAVIGATION_DRAWER_HEADER) {
|
||||
setItemChecked(position);
|
||||
if (drawerLayout != null) {
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
drawerLayout.closeDrawer(fragmentContainerView);
|
||||
}
|
||||
}, 400);
|
||||
}
|
||||
|
||||
}
|
||||
if (callbacks != null) {
|
||||
callbacks.onNavigationDrawerItemSelected(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt(STATE_SELECTED_POSITION, checkedPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
callbacks = null;
|
||||
}
|
||||
|
||||
public void setItemChecked(final int position) {
|
||||
if (drawerAdapter != null) {
|
||||
drawerAdapter.setChecked(position);
|
||||
checkedPosition = position;
|
||||
}
|
||||
}
|
||||
|
||||
public static interface NavigationDrawerCallbacks {
|
||||
void onNavigationDrawerItemSelected(int position);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
package com.kabouzeid.gramophone.ui.fragments.artistviewpager;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListAdapter;
|
||||
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableGridView;
|
||||
import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks;
|
||||
import com.github.ksoichiro.android.observablescrollview.ScrollState;
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||
import com.kabouzeid.gramophone.ui.activities.ArtistDetailActivity;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
|
||||
public abstract class AbsViewPagerTabArtistListFragment extends Fragment implements ObservableScrollViewCallbacks, KabViewsDisableAble {
|
||||
public static final String TAG = AbsViewPagerTabArtistListFragment.class.getSimpleName();
|
||||
protected App app;
|
||||
private ObservableGridView observableGridView;
|
||||
private Activity parentActivity;
|
||||
private int artistId = -1;
|
||||
private String artistName = "";
|
||||
private int paddingViewHeight;
|
||||
private boolean areViewsEnabled;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
app = (App) getActivity().getApplicationContext();
|
||||
parentActivity = getActivity();
|
||||
getArgs();
|
||||
|
||||
View view = inflater.inflate(R.layout.fragment_gridview, container, false);
|
||||
observableGridView = (ObservableGridView) view.findViewById(R.id.scroll);
|
||||
setGridViewPadding();
|
||||
observableGridView.setScrollViewCallbacks(this);
|
||||
ListAdapter adapter = getAdapter();
|
||||
if (adapter != null) {
|
||||
observableGridView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void setGridViewPadding() {
|
||||
final int artistImageViewHeight = getResources().getDimensionPixelSize(R.dimen.header_image_height);
|
||||
final int titleViewHeight = getResources().getDimensionPixelSize(R.dimen.title_view_height);
|
||||
final int tabHeight = getResources().getDimensionPixelSize(R.dimen.tab_height);
|
||||
|
||||
paddingViewHeight = artistImageViewHeight + titleViewHeight + tabHeight;
|
||||
|
||||
if (app.isInPortraitMode() || app.isTablet()) {
|
||||
observableGridView.setPadding(0, paddingViewHeight, 0, Util.getNavigationBarHeight(getActivity()));
|
||||
} else {
|
||||
observableGridView.setPadding(0, paddingViewHeight, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void getArgs() {
|
||||
Bundle args = getArguments();
|
||||
if (args != null) {
|
||||
artistId = args.getInt(ArtistDetailActivity.ARG_ARTIST_ID, -1);
|
||||
artistName = args.getString(ArtistDetailActivity.ARG_ARTIST_NAME, "");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* IMPORTANT:
|
||||
*
|
||||
* You CAN return null here and use setAdapter(ListAdapter adapter) inside getAdapter() to manually set the adapter.
|
||||
*
|
||||
* (i.e. if you must set the adapter async).
|
||||
*
|
||||
* */
|
||||
protected abstract ListAdapter getAdapter();
|
||||
|
||||
protected void setAdapter(ListAdapter adapter) {
|
||||
observableGridView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
enableViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
areViewsEnabled = true;
|
||||
observableGridView.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
areViewsEnabled = false;
|
||||
observableGridView.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areViewsEnabled() {
|
||||
return areViewsEnabled;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return observableGridView.getCurrentScrollY() + paddingViewHeight;
|
||||
}
|
||||
|
||||
protected int getArtistId() {
|
||||
return artistId;
|
||||
}
|
||||
|
||||
protected String getArtistName() {
|
||||
return artistName;
|
||||
}
|
||||
|
||||
public Activity getParentActivity() {
|
||||
return parentActivity;
|
||||
}
|
||||
|
||||
protected void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {
|
||||
observableGridView.setOnItemClickListener(onItemClickListener);
|
||||
}
|
||||
|
||||
protected void setColumns(int columns) {
|
||||
observableGridView.setNumColumns(columns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollChanged(int scrollY, boolean b, boolean b2) {
|
||||
if (parentActivity instanceof ObservableScrollViewCallbacks) {
|
||||
if (getUserVisibleHint()) {
|
||||
((ObservableScrollViewCallbacks) parentActivity).onScrollChanged(scrollY + paddingViewHeight, b, b2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownMotionEvent() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package com.kabouzeid.gramophone.ui.fragments.artistviewpager;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.ActivityOptionsCompat;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListAdapter;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.adapter.AlbumViewGridAdapter;
|
||||
import com.kabouzeid.gramophone.comparator.AlbumAlphabeticComparator;
|
||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||
import com.kabouzeid.gramophone.loader.ArtistAlbumLoader;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.model.Album;
|
||||
import com.kabouzeid.gramophone.ui.activities.AlbumDetailActivity;
|
||||
import com.melnykov.fab.FloatingActionButton;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by karim on 04.01.15.
|
||||
*/
|
||||
public class ViewPagerTabArtistAlbumFragment extends AbsViewPagerTabArtistListFragment {
|
||||
private FloatingActionButton fab;
|
||||
|
||||
@Override
|
||||
protected ListAdapter getAdapter() {
|
||||
List<Album> albums = ArtistAlbumLoader.getArtistAlbumList(getParentActivity(), getArtistId());
|
||||
Collections.sort(albums, new AlbumAlphabeticComparator());
|
||||
ListAdapter adapter = new AlbumViewGridAdapter(getParentActivity(), albums);
|
||||
setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
Album album = (Album) parent.getItemAtPosition(position);
|
||||
View albumArtView = view.findViewById(R.id.album_art);
|
||||
|
||||
openAlbumDetailsActivityIfPossible(album, albumArtView);
|
||||
}
|
||||
});
|
||||
setColumns(getResources().getInteger(R.integer.grid_columns));
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void openAlbumDetailsActivityIfPossible(Album album, View albumArtForTransition) {
|
||||
if (areParentActivitiesViewsEnabled()) {
|
||||
disableViews();
|
||||
disableParentActivitiesViews();
|
||||
|
||||
final Intent intent = new Intent(getActivity(), AlbumDetailActivity.class);
|
||||
intent.putExtra(AppKeys.E_ALBUM, album.id);
|
||||
|
||||
final ActivityOptionsCompat activityOptions;
|
||||
if (fab != null && albumArtForTransition != null) {
|
||||
activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(),
|
||||
Pair.create(albumArtForTransition, getString(R.string.transition_album_cover)),
|
||||
Pair.create((View) fab, getString(R.string.transition_fab))
|
||||
);
|
||||
} else {
|
||||
activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity());
|
||||
}
|
||||
ActivityCompat.startActivity(getActivity(), intent, activityOptions.toBundle());
|
||||
}
|
||||
}
|
||||
|
||||
private void disableParentActivitiesViews() {
|
||||
if (getParentActivity() instanceof KabViewsDisableAble) {
|
||||
((KabViewsDisableAble) getParentActivity()).disableViews();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areParentActivitiesViewsEnabled() {
|
||||
return !(getParentActivity() instanceof KabViewsDisableAble) || ((KabViewsDisableAble) getParentActivity()).areViewsEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
fab = (FloatingActionButton) getParentActivity().findViewById(R.id.fab);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package com.kabouzeid.gramophone.ui.fragments.artistviewpager;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Html;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.lastfm.artist.LastFMArtistBiographyLoader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ViewPagerTabArtistBioFragment extends AbsViewPagerTabArtistListFragment {
|
||||
|
||||
|
||||
@Override
|
||||
protected ListAdapter getAdapter() {
|
||||
final List<String> strings = new ArrayList<>();
|
||||
strings.add("loading");
|
||||
ListAdapter adapter = new SimpleTextAdapter(getParentActivity(), strings);
|
||||
setAdapter(adapter);
|
||||
|
||||
LastFMArtistBiographyLoader.loadArtistBio(getParentActivity(), getArtistName(), new LastFMArtistBiographyLoader.ArtistBioLoaderCallback() {
|
||||
@Override
|
||||
public void onArtistBioLoaded(String biography) {
|
||||
if (biography == null || biography.trim().equals("")) {
|
||||
try {
|
||||
biography = getResources().getString(R.string.biography_unavailable);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(TAG, "error while trying to access resources", e);
|
||||
biography = "Error";
|
||||
}
|
||||
}
|
||||
strings.clear();
|
||||
strings.add(biography);
|
||||
ListAdapter adapter = new SimpleTextAdapter(getParentActivity(), strings);
|
||||
setAdapter(adapter);
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class SimpleTextAdapter extends ArrayAdapter<String> {
|
||||
private Context context;
|
||||
|
||||
public SimpleTextAdapter(Context context, List<String> objects) {
|
||||
super(context, R.layout.item_artist_details_biography, objects);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
String string = getItem(position);
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(context).inflate(R.layout.item_artist_details_biography, parent, false);
|
||||
}
|
||||
TextView text = (TextView) convertView.findViewById(R.id.text);
|
||||
text.setText(Html.fromHtml(string));
|
||||
text.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
return convertView;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.kabouzeid.gramophone.ui.fragments.artistviewpager;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListAdapter;
|
||||
|
||||
import com.kabouzeid.gramophone.adapter.songadapter.SongAdapter;
|
||||
import com.kabouzeid.gramophone.comparator.SongAlphabeticComparator;
|
||||
import com.kabouzeid.gramophone.loader.ArtistSongLoader;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by karim on 04.01.15.
|
||||
*/
|
||||
public class ViewPagerTabArtistSongListFragment extends AbsViewPagerTabArtistListFragment {
|
||||
@Override
|
||||
protected ListAdapter getAdapter() {
|
||||
final List<Song> songs = ArtistSongLoader.getArtistSongList(getParentActivity(), getArtistId());
|
||||
Collections.sort(songs, new SongAlphabeticComparator());
|
||||
AbsBaseActivity absBaseActivity = null;
|
||||
if (getParentActivity() instanceof AbsBaseActivity) {
|
||||
absBaseActivity = (AbsBaseActivity) getParentActivity();
|
||||
}
|
||||
ListAdapter adapter = new SongAdapter(getParentActivity(), absBaseActivity, songs);
|
||||
setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
app.getMusicPlayerRemote().openQueue(songs, position, true);
|
||||
}
|
||||
});
|
||||
return adapter;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.adapter.AlbumViewGridAdapter;
|
||||
import com.kabouzeid.gramophone.comparator.AlbumAlphabeticComparator;
|
||||
import com.kabouzeid.gramophone.loader.AlbumLoader;
|
||||
import com.kabouzeid.gramophone.model.Album;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by karim on 22.11.14.
|
||||
*/
|
||||
public class AlbumViewFragment extends MainActivityFragment {
|
||||
public static final String TAG = AlbumViewFragment.class.getSimpleName();
|
||||
|
||||
private App app;
|
||||
private AbsListView absListView;
|
||||
private View fragmentRootView;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
app = (App) getActivity().getApplicationContext();
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_albumview, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
fragmentRootView = view;
|
||||
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
initViews();
|
||||
setUpViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
super.enableViews();
|
||||
absListView.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
super.disableViews();
|
||||
absListView.setEnabled(false);
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
absListView = (AbsListView) fragmentRootView.findViewById(R.id.absList);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
setUpAbsListView();
|
||||
}
|
||||
|
||||
private void setUpAbsListView() {
|
||||
List<Album> albums = AlbumLoader.getAllAlbums(getActivity());
|
||||
fillAbsListView(albums);
|
||||
}
|
||||
|
||||
private void fillAbsListView(List<Album> albums) {
|
||||
Collections.sort(albums, new AlbumAlphabeticComparator());
|
||||
AlbumViewGridAdapter albumViewGridAdapter = new AlbumViewGridAdapter(getActivity(), albums);
|
||||
absListView.setAdapter(albumViewGridAdapter);
|
||||
absListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
Album album = (Album) parent.getItemAtPosition(position);
|
||||
View albumArtView = view.findViewById(R.id.album_art);
|
||||
|
||||
openAlbumDetailsActivity(album, albumArtView);
|
||||
}
|
||||
});
|
||||
|
||||
absListView.setPadding(0, getTopPadding(app), 0, getBottomPadding(app));
|
||||
}
|
||||
|
||||
private void openAlbumDetailsActivity(Album album, View albumArtForTransition) {
|
||||
getMainActivity().goToAlbum(album.id, new Pair[]{
|
||||
Pair.create(albumArtForTransition, getString(R.string.transition_album_cover))
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void search(String query) {
|
||||
setUpAbsListView(query);
|
||||
}
|
||||
|
||||
private void setUpAbsListView(String query) {
|
||||
List<Album> albums = AlbumLoader.getAlbums(getActivity(), query);
|
||||
fillAbsListView(albums);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnToNonSearch() {
|
||||
setUpAbsListView();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
|
||||
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.adapter.ArtistViewListAdapter;
|
||||
import com.kabouzeid.gramophone.comparator.ArtistAlphabeticComparator;
|
||||
import com.kabouzeid.gramophone.loader.ArtistLoader;
|
||||
import com.kabouzeid.gramophone.misc.AppKeys;
|
||||
import com.kabouzeid.gramophone.model.Artist;
|
||||
import com.kabouzeid.gramophone.ui.activities.ArtistDetailActivity;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsFabActivity;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
*/
|
||||
public class ArtistViewFragment extends MainActivityFragment {
|
||||
public static final String TAG = ArtistViewFragment.class.getSimpleName();
|
||||
|
||||
private App app;
|
||||
private AbsListView absListView;
|
||||
private View fragmentRootView;
|
||||
private boolean areViewsEnabled;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
app = (App) getActivity().getApplicationContext();
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_artist_view, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
fragmentRootView = view;
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
initViews();
|
||||
setUpViews();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
super.enableViews();
|
||||
absListView.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
super.disableViews();
|
||||
absListView.setEnabled(false);
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
absListView = (AbsListView) fragmentRootView.findViewById(R.id.absList);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
setUpAbsListView();
|
||||
}
|
||||
|
||||
private void setUpAbsListView() {
|
||||
List<Artist> artists = ArtistLoader.getAllArtists(getActivity());
|
||||
fillAbsListView(artists);
|
||||
}
|
||||
|
||||
private void fillAbsListView(List<Artist> artists) {
|
||||
Collections.sort(artists, new ArtistAlphabeticComparator());
|
||||
ArtistViewListAdapter artistAdapter = new ArtistViewListAdapter(getActivity(), artists);
|
||||
absListView.setAdapter(artistAdapter);
|
||||
absListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
final Artist artist = (Artist) parent.getItemAtPosition(position);
|
||||
final View artistImageView = view.findViewById(R.id.artist_image);
|
||||
|
||||
if (getActivity() instanceof AbsFabActivity) {
|
||||
AbsFabActivity absFabActivity = (AbsFabActivity) getActivity();
|
||||
Pair[] sharedElements = {Pair.create(artistImageView, getString(R.string.transition_artist_image))};
|
||||
absFabActivity.goToArtist(artist.id, sharedElements);
|
||||
} else {
|
||||
Intent intent = new Intent(getActivity(), ArtistDetailActivity.class);
|
||||
intent.putExtra(AppKeys.E_ARTIST, artist.id);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
absListView.setPadding(0, getTopPadding(app), 0, getBottomPadding(app));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void search(String query) {
|
||||
setUpAbsListView(query);
|
||||
}
|
||||
|
||||
private void setUpAbsListView(String query) {
|
||||
List<Artist> artists = ArtistLoader.getArtists(getActivity(), query);
|
||||
fillAbsListView(artists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnToNonSearch() {
|
||||
setUpAbsListView();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Build;
|
||||
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.interfaces.KabSearchAbleFragment;
|
||||
import com.kabouzeid.gramophone.interfaces.KabViewsDisableAble;
|
||||
import com.kabouzeid.gramophone.ui.activities.MainActivity;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
|
||||
/**
|
||||
* Created by karim on 27.02.15.
|
||||
*/
|
||||
public abstract class MainActivityFragment extends Fragment implements KabViewsDisableAble, KabSearchAbleFragment {
|
||||
private boolean areViewsEnabled;
|
||||
|
||||
protected int getTopPadding(App app) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
if (app.isInPortraitMode() || app.isTablet()) {
|
||||
return Util.getActionBarSize(getActivity()) + getResources().getDimensionPixelSize(R.dimen.tab_height) + Util.getStatusBarHeight(getActivity());
|
||||
}
|
||||
return Util.getActionBarSize(getActivity()) + getResources().getDimensionPixelSize(R.dimen.tab_height) + Util.getStatusBarHeight(getActivity());
|
||||
}
|
||||
return Util.getActionBarSize(getActivity()) + getResources().getDimensionPixelSize(R.dimen.tab_height);
|
||||
}
|
||||
|
||||
protected int getBottomPadding(App app) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
if (app.isInPortraitMode() || app.isTablet()) {
|
||||
return Util.getNavigationBarHeight(getActivity());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
areViewsEnabled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
areViewsEnabled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areViewsEnabled() {
|
||||
return areViewsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
enableViews();
|
||||
}
|
||||
|
||||
protected MainActivity getMainActivity() {
|
||||
return (MainActivity) getActivity();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
package com.kabouzeid.gramophone.ui.fragments.mainactivityfragments;
|
||||
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import com.kabouzeid.gramophone.App;
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.adapter.songadapter.SongViewListAdapter;
|
||||
import com.kabouzeid.gramophone.comparator.SongAlphabeticComparator;
|
||||
import com.kabouzeid.gramophone.loader.SongLoader;
|
||||
import com.kabouzeid.gramophone.model.Song;
|
||||
import com.kabouzeid.gramophone.ui.activities.base.AbsBaseActivity;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by karim on 29.12.14.
|
||||
*/
|
||||
public class SongViewFragment extends MainActivityFragment {
|
||||
public static final String TAG = SongViewFragment.class.getSimpleName();
|
||||
|
||||
private App app;
|
||||
private AbsListView absListView;
|
||||
private View fragmentRootView;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
app = (App) getActivity().getApplicationContext();
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_songview, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
fragmentRootView = view;
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
initViews();
|
||||
setUpViews();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
absListView = (AbsListView) fragmentRootView.findViewById(R.id.absList);
|
||||
}
|
||||
|
||||
private void setUpViews() {
|
||||
setUpAbsListView();
|
||||
}
|
||||
|
||||
private void setUpAbsListView() {
|
||||
List<Song> songs = SongLoader.getAllSongs(getActivity());
|
||||
fillAbsListView(songs);
|
||||
}
|
||||
|
||||
private void fillAbsListView(final List<Song> songs) {
|
||||
Collections.sort(songs, new SongAlphabeticComparator());
|
||||
AbsBaseActivity absBaseActivity = null;
|
||||
if (getActivity() instanceof AbsBaseActivity) {
|
||||
absBaseActivity = (AbsBaseActivity) getActivity();
|
||||
}
|
||||
SongViewListAdapter songAdapter = new SongViewListAdapter(getActivity(), absBaseActivity, songs);
|
||||
absListView.setAdapter(songAdapter);
|
||||
absListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
app.getMusicPlayerRemote().openQueue(songs, position, true);
|
||||
}
|
||||
});
|
||||
|
||||
absListView.setPadding(0, getTopPadding(app), 0, getBottomPadding(app));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void search(String query) {
|
||||
setUpAbsListView(query);
|
||||
}
|
||||
|
||||
private void setUpAbsListView(String query) {
|
||||
List<Song> songs = SongLoader.getSongs(getActivity(), query);
|
||||
fillAbsListView(songs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnToNonSearch() {
|
||||
setUpAbsListView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableViews() {
|
||||
super.enableViews();
|
||||
absListView.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableViews() {
|
||||
super.disableViews();
|
||||
absListView.setEnabled(false);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue