Merge pull request #143 from poisdeux/sharedelementtransitions

Implemented shared element transitions for albums
This commit is contained in:
Synced Synapse 2015-12-09 18:53:05 +00:00
commit f0cea00730
4 changed files with 159 additions and 104 deletions

View File

@ -16,13 +16,15 @@
package org.xbmc.kore.ui; package org.xbmc.kore.ui;
import android.annotation.TargetApi;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.*; import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.provider.BaseColumns; import android.provider.BaseColumns;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
@ -46,6 +48,7 @@ import android.widget.Toast;
import com.melnykov.fab.FloatingActionButton; import com.melnykov.fab.FloatingActionButton;
import com.melnykov.fab.ObservableScrollView; import com.melnykov.fab.ObservableScrollView;
import org.xbmc.kore.R; import org.xbmc.kore.R;
import org.xbmc.kore.Settings; import org.xbmc.kore.Settings;
import org.xbmc.kore.host.HostInfo; import org.xbmc.kore.host.HostInfo;
@ -59,6 +62,7 @@ import org.xbmc.kore.provider.MediaContract;
import org.xbmc.kore.utils.FileDownloadHelper; import org.xbmc.kore.utils.FileDownloadHelper;
import org.xbmc.kore.utils.LogUtils; import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.UIUtils; import org.xbmc.kore.utils.UIUtils;
import org.xbmc.kore.utils.Utils;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -67,7 +71,6 @@ import java.util.List;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.InjectView; import butterknife.InjectView;
import butterknife.OnClick; import butterknife.OnClick;
import de.greenrobot.event.EventBus;
/** /**
* Presents movie details * Presents movie details
@ -76,7 +79,13 @@ public class AlbumDetailsFragment extends Fragment
implements LoaderManager.LoaderCallbacks<Cursor> { implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = LogUtils.makeLogTag(AlbumDetailsFragment.class); private static final String TAG = LogUtils.makeLogTag(AlbumDetailsFragment.class);
public static final String ALBUMID = "album_id"; public static final String BUNDLE_KEY_ALBUMID = "album_id";
public static final String POSTER_TRANS_NAME = "POSTER_TRANS_NAME";
public static final String BUNDLE_KEY_ALBUMARTIST = "album_artist";
public static final String BUNDLE_KEY_ALBUMTITLE = "album_title";
public static final String BUNDLE_KEY_ALBUMGENRE = "album_genre";
public static final String BUNDLE_KEY_ALBUMYEAR = "album_year";
public static final String BUNDLE_KEY_ALBUMRATING = "album_rating";
// Loader IDs // Loader IDs
private static final int LOADER_ALBUM = 0, private static final int LOADER_ALBUM = 0,
@ -84,7 +93,6 @@ public class AlbumDetailsFragment extends Fragment
private HostManager hostManager; private HostManager hostManager;
private HostInfo hostInfo; private HostInfo hostInfo;
private EventBus bus;
/** /**
* Handler on which to post RPC callbacks * Handler on which to post RPC callbacks
@ -128,11 +136,21 @@ public class AlbumDetailsFragment extends Fragment
/** /**
* Create a new instance of this, initialized to show the album albumId * Create a new instance of this, initialized to show the album albumId
*/ */
public static AlbumDetailsFragment newInstance(int albumId) { @TargetApi(21)
public static AlbumDetailsFragment newInstance(AlbumListFragment.ViewHolder vh) {
AlbumDetailsFragment fragment = new AlbumDetailsFragment(); AlbumDetailsFragment fragment = new AlbumDetailsFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putInt(ALBUMID, albumId); args.putInt(BUNDLE_KEY_ALBUMID, vh.albumId);
args.putString(BUNDLE_KEY_ALBUMTITLE, vh.albumTitle);
args.putString(BUNDLE_KEY_ALBUMARTIST, vh.albumArtist);
args.putString(BUNDLE_KEY_ALBUMGENRE, vh.albumGenre);
args.putInt(BUNDLE_KEY_ALBUMYEAR, vh.albumYear);
args.putDouble(BUNDLE_KEY_ALBUMRATING, vh.albumRating);
if( Utils.isLollipopOrLater()) {
args.putString(POSTER_TRANS_NAME, vh.artView.getTransitionName());
}
fragment.setArguments(args); fragment.setArguments(args);
return fragment; return fragment;
} }
@ -143,8 +161,9 @@ public class AlbumDetailsFragment extends Fragment
} }
@Override @Override
@TargetApi(21)
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
albumId = getArguments().getInt(ALBUMID, -1); albumId = getArguments().getInt(BUNDLE_KEY_ALBUMID, -1);
if ((container == null) || (albumId == -1)) { if ((container == null) || (albumId == -1)) {
// We're not being shown or there's nothing to show // We're not being shown or there's nothing to show
@ -154,7 +173,6 @@ public class AlbumDetailsFragment extends Fragment
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_album_details, container, false); ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_album_details, container, false);
ButterKnife.inject(this, root); ButterKnife.inject(this, root);
bus = EventBus.getDefault();
hostManager = HostManager.getInstance(getActivity()); hostManager = HostManager.getInstance(getActivity());
hostInfo = hostManager.getHostInfo(); hostInfo = hostManager.getHostInfo();
@ -173,6 +191,17 @@ public class AlbumDetailsFragment extends Fragment
FloatingActionButton fab = (FloatingActionButton)fabButton; FloatingActionButton fab = (FloatingActionButton)fabButton;
fab.attachToScrollView((ObservableScrollView) mediaPanel); fab.attachToScrollView((ObservableScrollView) mediaPanel);
Bundle bundle = getArguments();
if(Utils.isLollipopOrLater()) {
mediaPoster.setTransitionName(bundle.getString(POSTER_TRANS_NAME));
}
mediaTitle.setText(bundle.getString(BUNDLE_KEY_ALBUMTITLE));
mediaUndertitle.setText(bundle.getString(BUNDLE_KEY_ALBUMARTIST));
setMediaYear(bundle.getString(BUNDLE_KEY_ALBUMGENRE), bundle.getInt(BUNDLE_KEY_ALBUMYEAR));
setMediaRating(bundle.getDouble(BUNDLE_KEY_ALBUMRATING));
// Pad main content view to overlap with bottom system bar // Pad main content view to overlap with bottom system bar
// UIUtils.setPaddingForSystemBars(getActivity(), mediaPanel, false, false, true); // UIUtils.setPaddingForSystemBars(getActivity(), mediaPanel, false, false, true);
// mediaPanel.setClipToPadding(false); // mediaPanel.setClipToPadding(false);
@ -197,11 +226,6 @@ public class AlbumDetailsFragment extends Fragment
super.onResume(); super.onResume();
} }
@Override
public void onPause() {
super.onPause();
}
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
@ -281,7 +305,7 @@ public class AlbumDetailsFragment extends Fragment
if (!isAdded()) return; if (!isAdded()) return;
// Got an error, show toast // Got an error, show toast
Toast.makeText(getActivity(), R.string.unable_to_connect_to_xbmc, Toast.LENGTH_SHORT) Toast.makeText(getActivity(), R.string.unable_to_connect_to_xbmc, Toast.LENGTH_SHORT)
.show(); .show();
} }
}, callbackHandler); }, callbackHandler);
} }
@ -294,7 +318,7 @@ public class AlbumDetailsFragment extends Fragment
@OnClick(R.id.download) @OnClick(R.id.download)
public void onDownloadClicked(View v) { public void onDownloadClicked(View v) {
if ((albumTitle == null) || (albumDisplayArtist == null) || if ((albumTitle == null) || (albumDisplayArtist == null) ||
(songInfoList == null) || (songInfoList.size() == 0)) { (songInfoList == null) || (songInfoList.size() == 0)) {
// Nothing to download // Nothing to download
Toast.makeText(getActivity(), R.string.no_files_to_download, Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), R.string.no_files_to_download, Toast.LENGTH_SHORT).show();
return; return;
@ -311,16 +335,16 @@ public class AlbumDetailsFragment extends Fragment
if (file.exists()) { if (file.exists()) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.download) builder.setTitle(R.string.download)
.setMessage(R.string.download_dir_exists) .setMessage(R.string.download_dir_exists)
.setPositiveButton(R.string.overwrite, .setPositiveButton(R.string.overwrite,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
FileDownloadHelper.downloadFiles(getActivity(), hostInfo, FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
songInfoList, FileDownloadHelper.OVERWRITE_FILES, songInfoList, FileDownloadHelper.OVERWRITE_FILES,
callbackHandler); callbackHandler);
} }
}) })
.setNeutralButton(R.string.download_with_new_name, .setNeutralButton(R.string.download_with_new_name,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
@ -365,21 +389,13 @@ public class AlbumDetailsFragment extends Fragment
mediaTitle.setText(albumTitle); mediaTitle.setText(albumTitle);
mediaUndertitle.setText(albumDisplayArtist); mediaUndertitle.setText(albumDisplayArtist);
int year = cursor.getInt(AlbumDetailsQuery.YEAR); setMediaYear(cursor.getString(AlbumDetailsQuery.GENRE), cursor.getInt(AlbumDetailsQuery.YEAR));
String genres = cursor.getString(AlbumDetailsQuery.GENRE);
String label = (year > 0) ?
(!TextUtils.isEmpty(genres) ?
genres + " | " + String.valueOf(year) :
String.valueOf(year)) :
genres;
mediaYear.setText(label);
double rating = cursor.getDouble(AlbumDetailsQuery.RATING); double rating = cursor.getDouble(AlbumDetailsQuery.RATING);
if (rating > 0) { if (rating > 0) {
mediaRating.setVisibility(View.VISIBLE); mediaRating.setVisibility(View.VISIBLE);
mediaMaxRating.setVisibility(View.VISIBLE); mediaMaxRating.setVisibility(View.VISIBLE);
mediaRating.setText(String.format("%01.01f", rating)); setMediaRating(rating);
mediaMaxRating.setText(getString(R.string.max_rating_music));
} else { } else {
mediaRating.setVisibility(View.GONE); mediaRating.setVisibility(View.GONE);
mediaMaxRating.setVisibility(View.GONE); mediaMaxRating.setVisibility(View.GONE);
@ -427,32 +443,35 @@ public class AlbumDetailsFragment extends Fragment
int artHeight = resources.getDimensionPixelOffset(R.dimen.now_playing_art_height), int artHeight = resources.getDimensionPixelOffset(R.dimen.now_playing_art_height),
artWidth = displayMetrics.widthPixels; artWidth = displayMetrics.widthPixels;
int posterWidth = resources.getDimensionPixelOffset(R.dimen.albumdetail_poster_width);
int posterHeight = resources.getDimensionPixelOffset(R.dimen.albumdetail_poster_heigth);
UIUtils.loadImageWithCharacterAvatar(getActivity(), hostManager,
poster, albumTitle,
mediaPoster, posterWidth, posterHeight);
if (!TextUtils.isEmpty(fanart)) { if (!TextUtils.isEmpty(fanart)) {
int posterWidth = resources.getDimensionPixelOffset(R.dimen.albumdetail_poster_width);
int posterHeight = resources.getDimensionPixelOffset(R.dimen.albumdetail_poster_heigth);
mediaPoster.setVisibility(View.VISIBLE);
UIUtils.loadImageWithCharacterAvatar(getActivity(), hostManager,
poster, albumTitle,
mediaPoster, posterWidth, posterHeight);
UIUtils.loadImageIntoImageview(hostManager, UIUtils.loadImageIntoImageview(hostManager,
fanart, fanart,
mediaArt, artWidth, artHeight); mediaArt, artWidth, artHeight);
} else { } else {
// No fanart, just present the poster UIUtils.loadImageWithCharacterAvatar(getActivity(), hostManager,
mediaPoster.setVisibility(View.GONE); poster, albumTitle, mediaArt, artWidth, artHeight);
UIUtils.loadImageIntoImageview(hostManager,
poster,
mediaArt, artWidth, artHeight);
// Reset padding
int paddingLeft = mediaTitle.getPaddingRight(),
paddingRight = mediaTitle.getPaddingRight(),
paddingTop = mediaTitle.getPaddingTop(),
paddingBottom = mediaTitle.getPaddingBottom();
mediaTitle.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
mediaUndertitle.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
} }
} }
private void setMediaRating(double rating) {
mediaRating.setText(String.format("%01.01f", rating));
mediaMaxRating.setText(getString(R.string.max_rating_music));
}
private void setMediaYear(String genres, int year) {
String label = (year > 0) ?
(!TextUtils.isEmpty(genres) ?
genres + " | " + String.valueOf(year) :
String.valueOf(year)) :
genres;
mediaYear.setText(label);
}
/** /**
* Starts playing the song on XBMC * Starts playing the song on XBMC
* @param songId song to play * @param songId song to play
@ -501,7 +520,7 @@ public class AlbumDetailsFragment extends Fragment
if (!isAdded()) return; if (!isAdded()) return;
// Got an error, show toast // Got an error, show toast
Toast.makeText(getActivity(), R.string.item_added_to_playlist, Toast.LENGTH_SHORT) Toast.makeText(getActivity(), R.string.item_added_to_playlist, Toast.LENGTH_SHORT)
.show(); .show();
} }
@Override @Override
@ -509,12 +528,12 @@ public class AlbumDetailsFragment extends Fragment
if (!isAdded()) return; if (!isAdded()) return;
// Got an error, show toast // Got an error, show toast
Toast.makeText(getActivity(), R.string.unable_to_connect_to_xbmc, Toast.LENGTH_SHORT) Toast.makeText(getActivity(), R.string.unable_to_connect_to_xbmc, Toast.LENGTH_SHORT)
.show(); .show();
} }
}, callbackHandler); }, callbackHandler);
} else { } else {
Toast.makeText(getActivity(), R.string.no_suitable_playlist, Toast.LENGTH_SHORT) Toast.makeText(getActivity(), R.string.no_suitable_playlist, Toast.LENGTH_SHORT)
.show(); .show();
} }
} }
@ -523,7 +542,7 @@ public class AlbumDetailsFragment extends Fragment
if (!isAdded()) return; if (!isAdded()) return;
// Got an error, show toast // Got an error, show toast
Toast.makeText(getActivity(), R.string.unable_to_connect_to_xbmc, Toast.LENGTH_SHORT) Toast.makeText(getActivity(), R.string.unable_to_connect_to_xbmc, Toast.LENGTH_SHORT)
.show(); .show();
} }
}, callbackHandler); }, callbackHandler);
} }
@ -559,31 +578,31 @@ public class AlbumDetailsFragment extends Fragment
if (file.exists()) { if (file.exists()) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.download) builder.setTitle(R.string.download)
.setMessage(R.string.download_file_exists) .setMessage(R.string.download_file_exists)
.setPositiveButton(R.string.overwrite, .setPositiveButton(R.string.overwrite,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
FileDownloadHelper.downloadFiles(getActivity(), hostInfo, FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
songInfo, FileDownloadHelper.OVERWRITE_FILES, songInfo, FileDownloadHelper.OVERWRITE_FILES,
callbackHandler); callbackHandler);
} }
}) })
.setNeutralButton(R.string.download_with_new_name, .setNeutralButton(R.string.download_with_new_name,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
FileDownloadHelper.downloadFiles(getActivity(), hostInfo, FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
songInfo, FileDownloadHelper.DOWNLOAD_WITH_NEW_NAME, songInfo, FileDownloadHelper.DOWNLOAD_WITH_NEW_NAME,
callbackHandler); callbackHandler);
} }
}) })
.setNegativeButton(android.R.string.cancel, .setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { } public void onClick(DialogInterface dialog, int which) { }
}) })
.show(); .show();
} else { } else {
FileDownloadHelper.downloadFiles(getActivity(), hostInfo, FileDownloadHelper.downloadFiles(getActivity(), hostInfo,
songInfo, FileDownloadHelper.DOWNLOAD_WITH_NEW_NAME, songInfo, FileDownloadHelper.DOWNLOAD_WITH_NEW_NAME,
@ -608,7 +627,7 @@ public class AlbumDetailsFragment extends Fragment
songInfoList = new ArrayList<FileDownloadHelper.SongInfo>(cursor.getCount()); songInfoList = new ArrayList<FileDownloadHelper.SongInfo>(cursor.getCount());
do { do {
View songView = LayoutInflater.from(getActivity()) View songView = LayoutInflater.from(getActivity())
.inflate(R.layout.list_item_song, songListView, false); .inflate(R.layout.list_item_song, songListView, false);
TextView songTitle = (TextView)songView.findViewById(R.id.song_title); TextView songTitle = (TextView)songView.findViewById(R.id.song_title);
TextView trackNumber = (TextView)songView.findViewById(R.id.track_number); TextView trackNumber = (TextView)songView.findViewById(R.id.track_number);
TextView duration = (TextView)songView.findViewById(R.id.duration); TextView duration = (TextView)songView.findViewById(R.id.duration);
@ -637,7 +656,6 @@ public class AlbumDetailsFragment extends Fragment
} while (cursor.moveToNext()); } while (cursor.moveToNext());
if (songInfoList.size() > 0) { if (songInfoList.size() > 0) {
downloadButton.setVisibility(View.VISIBLE);
// Check if download dir exists // Check if download dir exists
FileDownloadHelper.SongInfo songInfo = new FileDownloadHelper.SongInfo FileDownloadHelper.SongInfo songInfo = new FileDownloadHelper.SongInfo
(albumDisplayArtist, albumTitle, 0, 0, null, null); (albumDisplayArtist, albumTitle, 0, 0, null, null);

View File

@ -15,6 +15,7 @@
*/ */
package org.xbmc.kore.ui; package org.xbmc.kore.ui;
import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
@ -48,6 +49,7 @@ import org.xbmc.kore.service.LibrarySyncService;
import org.xbmc.kore.utils.LogUtils; import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.MediaPlayerUtils; import org.xbmc.kore.utils.MediaPlayerUtils;
import org.xbmc.kore.utils.UIUtils; import org.xbmc.kore.utils.UIUtils;
import org.xbmc.kore.utils.Utils;
/** /**
* Fragment that presents the albums list * Fragment that presents the albums list
@ -56,7 +58,7 @@ public class AlbumListFragment extends AbstractListFragment {
private static final String TAG = LogUtils.makeLogTag(AlbumListFragment.class); private static final String TAG = LogUtils.makeLogTag(AlbumListFragment.class);
public interface OnAlbumSelectedListener { public interface OnAlbumSelectedListener {
public void onAlbumSelected(int albumId, String albumTitle); public void onAlbumSelected(ViewHolder vh);
} }
private static final String GENREID = "genreid", private static final String GENREID = "genreid",
@ -103,7 +105,7 @@ public class AlbumListFragment extends AbstractListFragment {
// Get the movie id from the tag // Get the movie id from the tag
ViewHolder tag = (ViewHolder) view.getTag(); ViewHolder tag = (ViewHolder) view.getTag();
// Notify the activity // Notify the activity
listenerActivity.onAlbumSelected(tag.albumId, tag.albumTitle); listenerActivity.onAlbumSelected(tag);
} }
}; };
} }
@ -194,6 +196,7 @@ public class AlbumListFragment extends AbstractListFragment {
MediaContract.Albums.GENRE, MediaContract.Albums.GENRE,
MediaContract.Albums.THUMBNAIL, MediaContract.Albums.THUMBNAIL,
MediaContract.Albums.YEAR, MediaContract.Albums.YEAR,
MediaContract.Albums.RATING,
}; };
String SORT = MediaDatabase.sortCommonTokens(MediaContract.Albums.TITLE) + " ASC"; String SORT = MediaDatabase.sortCommonTokens(MediaContract.Albums.TITLE) + " ASC";
@ -205,6 +208,7 @@ public class AlbumListFragment extends AbstractListFragment {
final int GENRE = 4; final int GENRE = 4;
final int THUMBNAIL = 5; final int THUMBNAIL = 5;
final int YEAR = 6; final int YEAR = 6;
final int RATING = 7;
} }
private class AlbumsAdapter extends CursorAdapter { private class AlbumsAdapter extends CursorAdapter {
@ -220,10 +224,8 @@ public class AlbumListFragment extends AbstractListFragment {
// Use the same dimensions as in the details fragment, so that it hits Picasso's cache when // Use the same dimensions as in the details fragment, so that it hits Picasso's cache when
// the user transitions to that fragment, avoiding another call and imediatelly showing the image // the user transitions to that fragment, avoiding another call and imediatelly showing the image
Resources resources = context.getResources(); Resources resources = context.getResources();
artWidth = (int)(resources.getDimension(R.dimen.albumdetail_poster_width) / artWidth = (int) resources.getDimensionPixelOffset(R.dimen.albumdetail_poster_width);
UIUtils.IMAGE_RESIZE_FACTOR); artHeight = (int) resources.getDimensionPixelOffset(R.dimen.albumdetail_poster_heigth);
artHeight = (int)(resources.getDimension(R.dimen.albumdetail_poster_heigth) /
UIUtils.IMAGE_RESIZE_FACTOR);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@ -244,12 +246,17 @@ public class AlbumListFragment extends AbstractListFragment {
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@TargetApi(21)
@Override @Override
public void bindView(View view, Context context, Cursor cursor) { public void bindView(View view, Context context, Cursor cursor) {
final ViewHolder viewHolder = (ViewHolder)view.getTag(); final ViewHolder viewHolder = (ViewHolder)view.getTag();
viewHolder.albumId = cursor.getInt(AlbumListQuery.ALBUMID); viewHolder.albumId = cursor.getInt(AlbumListQuery.ALBUMID);
viewHolder.albumTitle = cursor.getString(AlbumListQuery.TITLE); viewHolder.albumTitle = cursor.getString(AlbumListQuery.TITLE);
viewHolder.albumArtist = cursor.getString(AlbumListQuery.DISPLAYARTIST);
viewHolder.albumGenre = cursor.getString(AlbumListQuery.GENRE);
viewHolder.albumYear = cursor.getInt(AlbumListQuery.YEAR);
viewHolder.albumRating = cursor.getDouble(AlbumListQuery.RATING);
viewHolder.titleView.setText(viewHolder.albumTitle); viewHolder.titleView.setText(viewHolder.albumTitle);
viewHolder.artistView.setText(cursor.getString(AlbumListQuery.DISPLAYARTIST)); viewHolder.artistView.setText(cursor.getString(AlbumListQuery.DISPLAYARTIST));
@ -269,13 +276,17 @@ public class AlbumListFragment extends AbstractListFragment {
ImageView contextMenu = (ImageView)view.findViewById(R.id.list_context_menu); ImageView contextMenu = (ImageView)view.findViewById(R.id.list_context_menu);
contextMenu.setTag(viewHolder); contextMenu.setTag(viewHolder);
contextMenu.setOnClickListener(albumlistItemMenuClickListener); contextMenu.setOnClickListener(albumlistItemMenuClickListener);
if(Utils.isLollipopOrLater()) {
viewHolder.artView.setTransitionName("a"+viewHolder.albumId);
}
} }
} }
/** /**
* View holder pattern * View holder pattern
*/ */
private static class ViewHolder { public static class ViewHolder {
TextView titleView; TextView titleView;
TextView artistView; TextView artistView;
TextView genresView; TextView genresView;
@ -283,6 +294,10 @@ public class AlbumListFragment extends AbstractListFragment {
int albumId; int albumId;
String albumTitle; String albumTitle;
String albumArtist;
int albumYear;
String albumGenre;
double albumRating;
} }
private View.OnClickListener albumlistItemMenuClickListener = new View.OnClickListener() { private View.OnClickListener albumlistItemMenuClickListener = new View.OnClickListener() {

View File

@ -22,6 +22,7 @@ import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.transition.Transition;
import android.transition.TransitionInflater; import android.transition.TransitionInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@ -243,29 +244,44 @@ public class MusicActivity extends BaseActivity
} }
@TargetApi(21)
public void onArtistSelected(int artistId, String artistName) { public void onArtistSelected(int artistId, String artistName) {
selectedArtistId = artistId; selectedArtistId = artistId;
selectedArtistName = artistName; selectedArtistName = artistName;
// Replace list fragment // Replace list fragment
AlbumListFragment albumListFragment = AlbumListFragment.newInstanceForArtist(artistId); AlbumListFragment albumListFragment = AlbumListFragment.newInstanceForArtist(artistId);
getSupportFragmentManager()
.beginTransaction() FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
.setCustomAnimations(R.anim.fragment_details_enter, 0, R.anim.fragment_list_popenter, 0) // Setup animations
.replace(R.id.fragment_container, albumListFragment) if (Utils.isLollipopOrLater()) {
//Fade added to prevent shared element from disappearing very shortly at the start of the transition.
Transition fade = TransitionInflater
.from(this)
.inflateTransition(android.R.transition.fade);
albumListFragment.setExitTransition(fade);
albumListFragment.setReenterTransition(fade);
albumListFragment.setSharedElementReturnTransition(TransitionInflater.from(
this).inflateTransition(R.transition.change_image));
} else {
fragTrans.setCustomAnimations(R.anim.fragment_details_enter, 0, R.anim.fragment_list_popenter, 0);
}
fragTrans.replace(R.id.fragment_container, albumListFragment)
.addToBackStack(null) .addToBackStack(null)
.commit(); .commit();
navigationDrawerFragment.animateDrawerToggle(true); navigationDrawerFragment.animateDrawerToggle(true);
setupActionBar(null, artistName, null, null); setupActionBar(null, artistName, null, null);
} }
@TargetApi(21) @TargetApi(21)
public void onAlbumSelected(int albumId, String albumTitle) { public void onAlbumSelected(AlbumListFragment.ViewHolder vh) {
selectedAlbumId = albumId; selectedAlbumId = vh.albumId;
selectedAlbumTitle = albumTitle; selectedAlbumTitle = vh.albumTitle;
// Replace list fragment // Replace list fragment
AlbumDetailsFragment albumDetailsFragment = AlbumDetailsFragment.newInstance(albumId); AlbumDetailsFragment albumDetailsFragment = AlbumDetailsFragment.newInstance(vh);
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction(); FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
// Set up transitions // Set up transitions
@ -274,15 +290,22 @@ public class MusicActivity extends BaseActivity
.from(this) .from(this)
.inflateTransition(R.transition.media_details)); .inflateTransition(R.transition.media_details));
albumDetailsFragment.setReturnTransition(null); albumDetailsFragment.setReturnTransition(null);
Transition changeImageTransition = TransitionInflater.from(
this).inflateTransition(R.transition.change_image);
albumDetailsFragment.setSharedElementReturnTransition(changeImageTransition);
albumDetailsFragment.setSharedElementEnterTransition(changeImageTransition);
fragTrans.addSharedElement(vh.artView, vh.artView.getTransitionName());
} else { } else {
fragTrans.setCustomAnimations(R.anim.fragment_details_enter, 0, fragTrans.setCustomAnimations(R.anim.fragment_details_enter, 0,
R.anim.fragment_list_popenter, 0); R.anim.fragment_list_popenter, 0);
} }
fragTrans.replace(R.id.fragment_container, albumDetailsFragment) fragTrans.replace(R.id.fragment_container, albumDetailsFragment)
.addToBackStack(null) .addToBackStack(null)
.commit(); .commit();
setupActionBar(albumTitle, null, null, null); setupActionBar(selectedAlbumTitle, null, null, null);
} }
public void onAudioGenreSelected(int genreId, String genreTitle) { public void onAudioGenreSelected(int genreId, String genreTitle) {
@ -321,7 +344,7 @@ public class MusicActivity extends BaseActivity
} }
fragTrans.replace(R.id.fragment_container, detailsFragment) fragTrans.replace(R.id.fragment_container, detailsFragment)
.addToBackStack(null) .addToBackStack(null)
.commit(); .commit();
setupActionBar(null, null, null, musicVideoTitle); setupActionBar(null, null, null, musicVideoTitle);
} }

View File

@ -110,8 +110,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
style="@style/Widget.Button.Borderless" style="@style/Widget.Button.Borderless"
android:src="?attr/iconDownload" android:src="?attr/iconDownload"
android:contentDescription="@string/download" android:contentDescription="@string/download"/>
android:visibility="gone"/>
</LinearLayout> </LinearLayout>
<RelativeLayout <RelativeLayout