I am having two activities,out which first activity contain a recycle view in fragment which is added on the first activity and second activity contain a toolbar in collapsing toolbar layout,i have created a shared element transition between this two activities when a user click on a any Recycle view item which contains a image which i want to use as shared element to the second activity's toolbar image.i have set the transition like this.
First Activity
ChangeBounds changebound=new ChangeBounds();
changebound.setDuration(500);
getWindow().setSharedElementExitTransition(changebound);
Second Activity
ChangeBounds changebound=new ChangeBounds();
changebound.setDuration(500);
getWindow().setSharedElementEnterTransition(changebound);
I am Staring Second Activity from Recycler view onItemClickof the first activity like this
Pair<View, String> imagePair=Pair.create(itemView.findViewById(R.id.imgChannelImage), activity.getResources().getString(R.string.channel_name));
Bundle mBundle = new Bundle();
mBundle.putInt("Position", getLayoutPosition());
mBundle.putString("ChannelName", "One Direction " +getLayoutPosition());
Intent i = new Intent(activity, ProChannelPageActivity.class);
i.putExtras(mBundle);
ActivityOptionsCompat options = ActivityOptionsCompat.
makeSceneTransitionAnimation(context,imagePair);
activity.startActivity(i, options.toBundle());
I am able to have shared element transition between this two.but the problem is having a background glitch i.e we able to see the first activity background for few fraction while image view moving from one activity to another.
I can understand your problem.
Basically what is happening is that, you are only sharing the 2 Views you have mentioned. But the Status Bar on the Top, the Navigation Bar on the Bottom (and maybe others, in your case)do not get shared. So it seems like a blink.
You can see this post, see if it helps.
https://stackoverflow.com/a/26748694/2346980
Related
I am pretty new to Android app development so it's difficult for me to keep all the relevant concepts straight in my head, but I will explain what I want as easily as I can.
My MainActivity loads a TopActionBar fragment (circled in red) that I have created. Within the TopActionBar fragment, I load my HomeFragment fragment I created into a FrameLayount within my TopActionBar fragment. The buttons (circled in green) each load a new Activity. Each of these new Activities loads the TopActionBar fragment just with different parameters to load the correct title for the action bar depending on the tab. The issue is that the MaterialToolbar has the Activity transition animation applied to it (currently just the default transition). I want the rest of the content loaded when changing the Activity to have a transition animation except for the actual MaterialToolbar at the top of the screen. Is there a way for this to be done, or is there a different design approach I should be considering.
Here is an sample image of my UI:
I'm attempting to implement a shared element transition where I share some text from one fragment to another. The actual shared element animation worked fine until I attempted to combine it with a Fade transition. Now the shared element is being hidden behind the other fading content and is only visible once the fade finishes.
I'm animating from fragment A to fragment B.
In fragment A, I'm setting the exitTransition property in onCreate like so:
exitTransition = Fade()
In fragment B, I'm setting the enterTransition property in onCreate as well:
enterTransition = Fade()
The actual shared element transition is being triggered in the containing activity:
supportFragmentManager.commit {
replace(R.id.fragmentContainer, FragmentB.newInstance())
addSharedElement(sharedView, "transition_name")
setReorderingAllowed(true)
addToBackStack(null)
}
The animation used for the shared element is being set in onCreate of fragment B:
TransitionSet set = new TransitionSet();
set.setOrdering(TransitionSet.ORDERING_TOGETHER);
Transition changeBounds = new ChangeBounds();
changeBounds.addTarget(R.id.logo);
changeBounds.addTarget("logo_transition_name");
set.addTransition(changeBounds);
ChangeTransform changeTransform = new ChangeTransform();
changeTransform.addTarget(R.id.logo);
changeTransform.addTarget("logo_transition_name");
set.addTransition(changeTransform);
Transition textSize = new TextSizeTransition();
textSize.addTarget(R.id.logo);
textSize.addTarget("logo_transition_name");
set.addTransition(textSize);
sharedElementEnterTransition = set;
What am I missing?
Here's a gif for reference:
Ultimately I managed to fix this issue by setting a scale on the logo TextView that was transitioning.
To elaborate, my understanding from previous stack overflow answers written by George Mount is that the ChangeTransform transition will (kind of magically) handle reparenting a shared element view such that it won't get drawn over by another view.
After debugging the ChangeTransform transition, I found that its createAnimator method was never being called. It looks like that's because the view being shared didn't have any scale or rotation changes between the fragment A and fragment B.
Setting a scale of 0.99 on the logo TextView in fragment A lead to the createAnimator method being called and the view properly transitioning over other views instead of under them.
I suspect that since people are normally sharing imageviews that theres normally a scale difference between the two images so this problem doesn't show up as much. I could be wrong about that.
I have two activities MainAcitity and DetailActivity. MainActivity is containing recyclerview inside the fragment of viewpager. When I click on item it will go to DetailActivity and show the detail info inside the fragment of viewpager in DetailAcitivty.
The Problems is:
I want to add transition when I click on recyclerview item in MainActivity and go to DetailActivity.
When I back from the DetailActivity to MainActivity I want its transition will come to the item that I swiped in viewpager.
How can I achieve this?
Note:
-MainAcitivty and DetailAcitivty both are containing viewpager.
Thanks!
You will need to tag both your views with a unique transitionName.
ViewCompat.setTransitionName(imageView, "some_unique_transitionName");
start the new activity with this new information
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, imageView, ViewCompat.getTransitionName(imageView));
activity.startActivity(intent, options.toBundle());
Now, on the new activity :
Depending on how you open your next activity and how complex is it's view hierarchy you'll might want to leverage supportPostponeEnterTransition(); during onCreate and supportStartPostponedEnterTransition();sometime later when it's set up. I'll let you read the documentation for it
Apart from that find the view on the new activity that needs to be animated and set the transition name on it
activityImage.setTransitionName(transitionName);
and let it rip.
few other things you might want to tinker with could be animation duration, interpolators etc.
getWindow().getSharedElementEnterTransition().setDuration(200);
getWindow().getSharedElementReturnTransition().setDuration(200)
.setInterpolator(new DecelerateInterpolator());
And, entry / exit transitions for your activities (you will need this)
Fade fade = new Fade();
fade.excludeTarget(android.R.id.statusBarBackground, true);
fade.excludeTarget(android.R.id.navigationBarBackground, true);
getWindow().setEnterTransition(fade);
getWindow().setExitTransition(fade);
Remember, the shared element transitions traverses the whole view hierarchy to find out the source and target views and only after the target activity is completely laid the framework reverse transitions to give you the illusion you want to achieve so yea, if the view hierarchies are complex or the activities take time to set up etc (Network dependent), you might need to tinker around a little bit more.
Lets say I have FragmentA and DetailActivity. FragmentA has a RecyclerViewAdapter. The items in that adapter all have an image. When a user clicks on an item I want to show a detail page where that same image is shown (in DetailActivity). So I made that image a shared element, so we get a nice transition when navigating to the DetailActivity. I've implemented this with this code:
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
(Activity) context,
recyclerViewHolder.img_bridge_icon,
ViewCompat.getTransitionName(recyclerViewHolder.img_bridge_icon));
ActivityCompat.startActivity(context, intent, options.toBundle());
This is working great! The image gets scaled and re-positioned. Now, when I return to FragmentA, the item in the adapter already has the image loaded while the shared element is still busy with its transition. This means that the shared element is shown twice until the transition animation is done.
I know that this happens because FragmentA has to create its view again when returning from DetailActivity. But how can I solve this? The adapter should somehow know not to show the shared ImageView when the transition is loading.
I've added a screenshot that was made in the middle of the transition from DetailActivity to FragmentA. The bottom image is the one from the DetailActivity, the top one is from the item in the adapter, which should not be there (the bottom one should be the only one, because that's the one in the transition).
I have a menu that is always visible, and the same for all activities. Is it possible to avoid that the menu slides out along with the rest of the layout when launching a new activity? You can compare it to the way the tabwidget works, where the tabs remain in place while the rest of the layout switches
Is it possible to avoid that the menu slides out along with the rest of the layout when launching a new activity?
No, it's not possible. Everything within the current Activity are about to close/hide/animate out when you are starting a new Activity.
Consider the use of a Tab Layout.
A couple of ways come to mind.
If you want to keep using activities, you could fake it by disabling their sliding animations. You would then have to manually do animations for the parts of the UI you want to slide in/out. I'm not sure how smooth this might look when going from one activity to the other.
Use Fragments and animate in/out the parts of the UI that are changing.
I would go the fragment route.
for reference sake:
if you use FLAG_ACTIVITY_REORDER_TO_FRONT, the FLAG_ACTIVITY_NO_ANIMATION will only work the first time the activity is created. Going to the activity back, will skip the onCreate where certainly the overridePendingTransition() method is called.
You should add "overridePendingTransition(0,0)" in your onResume and the animation will disappear for good.
public void launchSecondActivity(){
Intent i = new Intent(FirstActivity.this, SecondActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
//this flag will lead to problem the second time
i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(i);
}
//add this to your activities to fix it
#Override
public void onResume() {
super.onResume();
overridePendingTransition(0,0);
}