add Maven
allprojects {
repositories {
...
maven { url 'https://www.jitpack.io' }
}
}
add implementation
dependencies {
implementation 'com.github.yellowcath:YcShareElement:1.3.2'
//for androidx
implementation 'com.github.yellowcath:YcShareElement:1.3.2.x'
}
In demo,
Show the videos withGSYVideoPlayer
Show the images with Fresco and Glide
YcShareElement provides two demos, one is the contact demo above,another implements a complex ShareElement animation of images and video mixes,see image below
The key points here are as follows:
1、ShareElement animation of Glide pictures
In the animation, imageView will go through the default background color -> small thumbnail -> big picture three stages. How to achieve a seamless switch in these three stages
Reference:ChangeOnlineImageTransition
2、ShareElement animation of Fresco pictures
Fresco provides the built-in DraweeTransition, but if you set the thumbnail, the image will be distorted, and must provide animation-starting ScaleType information in the constructor, which isn't very nice in complex situations.
Reference:AdvancedDraweeTransition
3、ShareElement animation of videos
And this is actually pretty simple after we've done the first two points, we're actually animating the cover of video.
YcShareElement.enableContentTransition(getApplication());
The switch is turned on by default
private void gotoDetailActivity(){
Intent intent = new Intent(this, DetailActivity.class);
Bundle bundle = YcShareElement.buildOptionsBundle(ContactActivity.this, new IShareElements() {
@Override
public ShareElementInfo[] getShareElements() {
return new ShareElementInfo[]{new ShareElementInfo(mAvatarImg),
new ShareElementInfo(mNameTxt, new TextViewStateSaver())};
}
});
ActivityCompat.startActivity(ContactActivity.this, intent, bundle);
}
public class DetailActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
YcShareElement.setEnterTransition(this, new IShareElements() {
@Override
public ShareElementInfo[] getShareElements() {
return new ShareElementInfo[]{new ShareElementInfo(avatarImg),
new ShareElementInfo(nameTxt, new TextViewStateSaver())};
}
});
YcShareElement.startTransition(this);
}
}
YcShareElement.setEnterTransition() will suspend activity transtion animation by default,until the call of YcShareElement.startTransition(),in this simple page where you don't have to wait for ShareElement to load, you can pass the third parameter to false, without pausing ActivityB's transition animation
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
YcShareElement.setEnterTransition(this, new IShareElements() {
@Override
public ShareElementInfo[] getShareElements() {
return new ShareElementInfo[]{new ShareElementInfo(avatarImg),
new ShareElementInfo(nameTxt, new TextViewStateSaver())};
}
},false);
}
YcShareElement.enableContentTransition(getApplication());
Bundle options = YcShareElement.buildOptionsBundle(getActivity(), this);
startActivityForResult(intent, REQUEST_CONTENT, options);
protected void onCreate(@Nullable Bundle savedInstanceState) {
YcShareElement.setEnterTransition(this, this);
...
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
...加载数据...
YcShareElement.postStartTransition(getActivity());
}
The next step is to handle the return animation of the list page
@Override
public void finishAfterTransition() {
YcShareElement.finishAfterTransition(this, this);
super.finishAfterTransition();
}
@Override
public void onActivityReenter(int resultCode, Intent data) {
super.onActivityReenter(resultCode, data);
YcShareElement.onActivityReenter(this, resultCode, data, new IShareElementSelector() {
@Override
public void selectShareElements(List<ShareElementInfo> list) {
//Slide the list page to the location of the changed ShareElement
mFragment.selectShareElement(list.get(0));
}
});
}
Here is an example of how to extend Transition to support Fresco
First, the parameters required for the Transtion animation, namely the ActualImageScaleType, are determined for SimpleDraweeView
public class FrescoViewStateSaver extends ViewStateSaver {
@Override
protected void captureViewInfo(View view, Bundle bundle) {
if (view instanceof GenericDraweeView) {
int actualScaleTypeInt = scaleTypeToInt(((GenericDraweeView)view).getHierarchy().getActualImageScaleType())
bundle.putInt("scaleType",actualScaleTypeInt);
}
}
public ScalingUtils.ScaleType getScaleType(Bundle bundle) {
int scaleType = bundle.getInt("scaleType", 0);
return intToScaleType(scaleType);
}
}
public class AdvancedDraweeTransition extends Transition {
private ScalingUtils.ScaleType mFromScale;
private ScalingUtils.ScaleType mToScale;
public AdvancedDraweeTransition() {
addTarget(GenericDraweeView.class);
}
@Override
public void captureStartValues(TransitionValues transitionValues) {
...
ShareElementInfo shareElementInfo = ShareElementInfo.getFromView(transitionValues.view);
mFromScale = ((FrescoViewStateSaver) shareElementInfo.getViewStateSaver()).getScaleType(viewInfo);
...
}
@Override
public void captureEndValues(TransitionValues transitionValues) {
...
ShareElementInfo shareElementInfo = ShareElementInfo.getFromView(transitionValues.view);
mToScale = ((FrescoViewStateSaver) shareElementInfo.getViewStateSaver()).getScaleType(viewInfo);
...
}
@Override
public Animator createAnimator(
ViewGroup sceneRoot,
TransitionValues startValues,
TransitionValues endValues) {
..
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float fraction = (float) animation.getAnimatedValue();
scaleType.setValue(fraction);
if (draweeView.getHierarchy().getActualImageScaleType() != scaleType) {
draweeView.getHierarchy().setActualImageScaleType(scaleType);
}
}
});
...
return animator;
}
}
public class FrescoShareElementTransitionfactory extends DefaultShareElementTransitionFactory {
@Override
protected TransitionSet buildShareElementsTransition(List<View> shareViewList) {
TransitionSet transitionSet = super.buildShareElementsTransition(shareViewList);
transitionSet.addTransition(new AdvancedDraweeTransition());
return transitionSet;
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
...
YcShareElement.setShareElementTransitionFactory(new FrescoShareElementTransitionfactory());
...
}