Implemented fix for movie and album shared element transitions
When shared element view is not visible on returning, the return shared element transition starts off screen. This looks odd and we now simply do not perform the shared element transition when the shared element is not visible.
This commit is contained in:
parent
fce521a9bb
commit
f84ccaf02a
|
@ -669,6 +669,18 @@ public class AlbumDetailsFragment extends Fragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the shared element if visible
|
||||||
|
* @return View if visible, null otherwise
|
||||||
|
*/
|
||||||
|
public View getSharedElement() {
|
||||||
|
if (UIUtils.isViewInBounds(mediaPanel, mediaPoster)) {
|
||||||
|
return mediaPoster;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Album details query parameters.
|
* Album details query parameters.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -201,7 +201,7 @@ public class MovieDetailsFragment extends AbstractDetailsFragment
|
||||||
// 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);
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,6 +628,18 @@ public class MovieDetailsFragment extends AbstractDetailsFragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the shared element if visible
|
||||||
|
* @return View if visible, null otherwise
|
||||||
|
*/
|
||||||
|
public View getSharedElement() {
|
||||||
|
if (UIUtils.isViewInBounds(mediaPanel, mediaPoster)) {
|
||||||
|
return mediaPoster;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Movie details query parameters.
|
* Movie details query parameters.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,12 +26,16 @@ 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;
|
||||||
|
import android.view.View;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
|
||||||
import org.xbmc.kore.R;
|
import org.xbmc.kore.R;
|
||||||
import org.xbmc.kore.utils.LogUtils;
|
import org.xbmc.kore.utils.LogUtils;
|
||||||
import org.xbmc.kore.utils.Utils;
|
import org.xbmc.kore.utils.Utils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the presentation of Movies information (list, details)
|
* Controls the presentation of Movies information (list, details)
|
||||||
* All the information is presented by specific fragments
|
* All the information is presented by specific fragments
|
||||||
|
@ -48,6 +52,8 @@ public class MoviesActivity extends BaseActivity
|
||||||
|
|
||||||
private NavigationDrawerFragment navigationDrawerFragment;
|
private NavigationDrawerFragment navigationDrawerFragment;
|
||||||
|
|
||||||
|
private boolean clearSharedElements;
|
||||||
|
|
||||||
@TargetApi(21)
|
@TargetApi(21)
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -76,6 +82,18 @@ public class MoviesActivity extends BaseActivity
|
||||||
movieListFragment.setReenterTransition(fade);
|
movieListFragment.setReenterTransition(fade);
|
||||||
movieListFragment.setSharedElementReturnTransition(TransitionInflater.from(
|
movieListFragment.setSharedElementReturnTransition(TransitionInflater.from(
|
||||||
this).inflateTransition(R.transition.change_image));
|
this).inflateTransition(R.transition.change_image));
|
||||||
|
|
||||||
|
android.support.v4.app.SharedElementCallback seCallback = new android.support.v4.app.SharedElementCallback() {
|
||||||
|
@Override
|
||||||
|
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
|
||||||
|
if (clearSharedElements) {
|
||||||
|
names.clear();
|
||||||
|
sharedElements.clear();
|
||||||
|
clearSharedElements = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
movieListFragment.setExitSharedElementCallback(seCallback);
|
||||||
}
|
}
|
||||||
getSupportFragmentManager()
|
getSupportFragmentManager()
|
||||||
.beginTransaction()
|
.beginTransaction()
|
||||||
|
@ -189,9 +207,27 @@ public class MoviesActivity extends BaseActivity
|
||||||
|
|
||||||
// Set up transitions
|
// Set up transitions
|
||||||
if (Utils.isLollipopOrLater()) {
|
if (Utils.isLollipopOrLater()) {
|
||||||
MovieDetailsFragment movieDetailsFragment = MovieDetailsFragment.newInstance(vh);
|
final MovieDetailsFragment movieDetailsFragment = MovieDetailsFragment.newInstance(vh);
|
||||||
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
|
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
|
||||||
|
|
||||||
|
android.support.v4.app.SharedElementCallback seCallback = new android.support.v4.app.SharedElementCallback() {
|
||||||
|
@Override
|
||||||
|
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
|
||||||
|
//On returning onMapSharedElements for the exiting fragment is called before the onMapSharedElements
|
||||||
|
// for the reentering fragment. We use this to determine if we are returning and if
|
||||||
|
// we should clear the shared element lists. Note that, clearing must be done in the reentering fragment
|
||||||
|
// as this is called last. Otherwise it the app will crash during transition setup. Not sure, but might
|
||||||
|
// be a v4 support package bug.
|
||||||
|
if (movieDetailsFragment.isVisible()) {
|
||||||
|
View sharedView = movieDetailsFragment.getSharedElement();
|
||||||
|
if (sharedView == null) { // shared element not visible
|
||||||
|
clearSharedElements = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
movieDetailsFragment.setEnterSharedElementCallback(seCallback);
|
||||||
|
|
||||||
movieDetailsFragment.setEnterTransition(TransitionInflater
|
movieDetailsFragment.setEnterTransition(TransitionInflater
|
||||||
.from(this)
|
.from(this)
|
||||||
.inflateTransition(R.transition.media_details));
|
.inflateTransition(R.transition.media_details));
|
||||||
|
|
|
@ -26,11 +26,15 @@ 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;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import org.xbmc.kore.R;
|
import org.xbmc.kore.R;
|
||||||
import org.xbmc.kore.utils.LogUtils;
|
import org.xbmc.kore.utils.LogUtils;
|
||||||
import org.xbmc.kore.utils.Utils;
|
import org.xbmc.kore.utils.Utils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the presentation of Music information (list, details)
|
* Controls the presentation of Music information (list, details)
|
||||||
* All the information is presented by specific fragments
|
* All the information is presented by specific fragments
|
||||||
|
@ -62,6 +66,8 @@ public class MusicActivity extends BaseActivity
|
||||||
|
|
||||||
private NavigationDrawerFragment navigationDrawerFragment;
|
private NavigationDrawerFragment navigationDrawerFragment;
|
||||||
|
|
||||||
|
private boolean clearSharedElements;
|
||||||
|
|
||||||
@TargetApi(21)
|
@TargetApi(21)
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -255,6 +261,18 @@ public class MusicActivity extends BaseActivity
|
||||||
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
|
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
|
||||||
// Setup animations
|
// Setup animations
|
||||||
if (Utils.isLollipopOrLater()) {
|
if (Utils.isLollipopOrLater()) {
|
||||||
|
android.support.v4.app.SharedElementCallback seCallback = new android.support.v4.app.SharedElementCallback() {
|
||||||
|
@Override
|
||||||
|
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
|
||||||
|
if (clearSharedElements) {
|
||||||
|
names.clear();
|
||||||
|
sharedElements.clear();
|
||||||
|
clearSharedElements = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
albumListFragment.setExitSharedElementCallback(seCallback);
|
||||||
|
|
||||||
//Fade added to prevent shared element from disappearing very shortly at the start of the transition.
|
//Fade added to prevent shared element from disappearing very shortly at the start of the transition.
|
||||||
Transition fade = TransitionInflater
|
Transition fade = TransitionInflater
|
||||||
.from(this)
|
.from(this)
|
||||||
|
@ -281,11 +299,29 @@ public class MusicActivity extends BaseActivity
|
||||||
selectedAlbumTitle = vh.albumTitle;
|
selectedAlbumTitle = vh.albumTitle;
|
||||||
|
|
||||||
// Replace list fragment
|
// Replace list fragment
|
||||||
AlbumDetailsFragment albumDetailsFragment = AlbumDetailsFragment.newInstance(vh);
|
final AlbumDetailsFragment albumDetailsFragment = AlbumDetailsFragment.newInstance(vh);
|
||||||
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
|
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
|
||||||
|
|
||||||
// Set up transitions
|
// Set up transitions
|
||||||
if (Utils.isLollipopOrLater()) {
|
if (Utils.isLollipopOrLater()) {
|
||||||
|
android.support.v4.app.SharedElementCallback seCallback = new android.support.v4.app.SharedElementCallback() {
|
||||||
|
@Override
|
||||||
|
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
|
||||||
|
//On returning onMapSharedElements for the exiting fragment is called before the onMapSharedElements
|
||||||
|
// for the reentering fragment. We use this to determine if we are returning and if
|
||||||
|
// we should clear the shared element lists. Note that, clearing must be done in the reentering fragment
|
||||||
|
// as this is called last. Otherwise it the app will crash during transition setup. Not sure, but might
|
||||||
|
// be a v4 support package bug.
|
||||||
|
if (albumDetailsFragment.isVisible()) {
|
||||||
|
View sharedView = albumDetailsFragment.getSharedElement();
|
||||||
|
if (sharedView == null) { // shared element not visible
|
||||||
|
clearSharedElements = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
albumDetailsFragment.setEnterSharedElementCallback(seCallback);
|
||||||
|
|
||||||
albumDetailsFragment.setEnterTransition(TransitionInflater
|
albumDetailsFragment.setEnterTransition(TransitionInflater
|
||||||
.from(this)
|
.from(this)
|
||||||
.inflateTransition(R.transition.media_details));
|
.inflateTransition(R.transition.media_details));
|
||||||
|
|
|
@ -122,16 +122,16 @@ public class UIUtils {
|
||||||
|
|
||||||
if ((imageWidth) > 0 && (imageHeight > 0)) {
|
if ((imageWidth) > 0 && (imageHeight > 0)) {
|
||||||
hostManager.getPicasso()
|
hostManager.getPicasso()
|
||||||
.load(hostManager.getHostInfo().getImageUrl(imageUrl))
|
.load(hostManager.getHostInfo().getImageUrl(imageUrl))
|
||||||
.resize(imageWidth, imageHeight)
|
.resize(imageWidth, imageHeight)
|
||||||
.centerCrop()
|
.centerCrop()
|
||||||
.into(imageView);
|
.into(imageView);
|
||||||
} else {
|
} else {
|
||||||
hostManager.getPicasso()
|
hostManager.getPicasso()
|
||||||
.load(hostManager.getHostInfo().getImageUrl(imageUrl))
|
.load(hostManager.getHostInfo().getImageUrl(imageUrl))
|
||||||
.fit()
|
.fit()
|
||||||
.centerCrop()
|
.centerCrop()
|
||||||
.into(imageView);
|
.into(imageView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,11 +191,11 @@ public class UIUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
char charAvatar = TextUtils.isEmpty(str) ?
|
char charAvatar = TextUtils.isEmpty(str) ?
|
||||||
' ' : str.charAt(0);
|
' ' : str.charAt(0);
|
||||||
avatarColorsIdx = TextUtils.isEmpty(str) ? 0 :
|
avatarColorsIdx = TextUtils.isEmpty(str) ? 0 :
|
||||||
Math.max(Character.getNumericValue(str.charAt(0)) +
|
Math.max(Character.getNumericValue(str.charAt(0)) +
|
||||||
Character.getNumericValue(str.charAt(str.length() - 1)) +
|
Character.getNumericValue(str.charAt(str.length() - 1)) +
|
||||||
str.length(), 0) % characterAvatarColors.length();
|
str.length(), 0) % characterAvatarColors.length();
|
||||||
int color = characterAvatarColors.getColor(avatarColorsIdx, 0xff000000);
|
int color = characterAvatarColors.getColor(avatarColorsIdx, 0xff000000);
|
||||||
// avatarColorsIdx = randomGenerator.nextInt(characterAvatarColors.length());
|
// avatarColorsIdx = randomGenerator.nextInt(characterAvatarColors.length());
|
||||||
return new CharacterDrawable(charAvatar, color);
|
return new CharacterDrawable(charAvatar, color);
|
||||||
|
@ -318,7 +318,7 @@ public class UIUtils {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
NetUtils.sendWolMagicPacket(hostInfo.getMacAddress(),
|
NetUtils.sendWolMagicPacket(hostInfo.getMacAddress(),
|
||||||
hostInfo.getAddress(), hostInfo.getWolPort());
|
hostInfo.getAddress(), hostInfo.getWolPort());
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
Toast.makeText(context, R.string.wol_sent, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, R.string.wol_sent, Toast.LENGTH_SHORT).show();
|
||||||
|
@ -423,7 +423,7 @@ public class UIUtils {
|
||||||
// Show the animation
|
// Show the animation
|
||||||
int endRadius = Math.max(exitTransitionView.getHeight(), exitTransitionView.getWidth());
|
int endRadius = Math.max(exitTransitionView.getHeight(), exitTransitionView.getWidth());
|
||||||
Animator exitAnim = ViewAnimationUtils.createCircularReveal(exitTransitionView,
|
Animator exitAnim = ViewAnimationUtils.createCircularReveal(exitTransitionView,
|
||||||
centerX, centerY, 0, endRadius);
|
centerX, centerY, 0, endRadius);
|
||||||
|
|
||||||
exitAnim.setDuration(200);
|
exitAnim.setDuration(200);
|
||||||
exitAnim.addListener(new Animator.AnimatorListener() {
|
exitAnim.addListener(new Animator.AnimatorListener() {
|
||||||
|
|
Loading…
Reference in New Issue