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.
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:
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 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
I want to animate a view with SharedElement transition from one Fragment to another fragment in ViewPager.
I've 3 fragments in a ViewPager, each fragment is having a single TextView with same transition name in XML file.
Now, when ViewPager slides another Fragment, I want to see SharedElement in action.
I’ve had the same issue. Standard shared element transitions are not working between ViewPager pages.
So I wrote a Shared Element View Pager library. It works both for transitions caused by onClick() events (such as viewPager.setCurrentItem(x) ) and page slides caused by user. The animation is bound to finger movement.
It's not an android transition so there could be some obstacles. Take a look though.
SharedElementPageTransformer demo
Usage
Add all fragments from your ViewPager to the List in the same order.
ArrayList<Fragment> fragments = new ArrayList<>();
fragments.add(hello_fragment);
fragments.add(small_picture_fragment);
Create SharedElementPageTransformer presumably in Activity.onCreate().
this refers to activity:
SharedElementPageTransformer transformer =
new SharedElementPageTransformer(this, fragments);
Add shared transition by passing pairs of view ids, that need to be linked together
transformer.addSharedTransition(R.id.smallPic_image_cat, R.id.bigPic_image_cat);
Set our transformer to ViewPager's pageTransformer AND onPageChangeListener.
viewPager.setPageTransformer(false, transformer);
viewPager.addOnPageChangeListener(transformer);
it's been maybe a too long time but could be helpful though.
It's totally possible to have shared elements transitions between 2 viewPagers since i already did it myself.
I think the thing you are maybe missing is that transition name has to be unique !
So it has to be set programmatically and not in XML ! It's very important in ViewPager since same view could be inflated many times.
imageView.setTransitionName("unique_name");
This way the transition knows on what element it should be played;)
I'm trying to animate 2 simple Views from a selected item in a RecyclerView to a new fragment. I've looked at a lot of examples of animating shared elements from one Activity to another Activity, but very few examples of animating a shared element from one Fragment to another Fragment within the same Activity. It almost works.
Here is my structure.
Activity
-- Full screen Fragment1 with RecyclerView
-- Full screen Fragment2 with details
When the user selects an item in the RecyclerView in Fragment1, I replace Fragment1 with Fragment2 that has a View with the shared elements in it in different positions and sizes.
There's a bit of a trick to get it to work, you have to make sure your transitionName is unique for each item in your list, and of course that transitionName must match the transitionName of the element in Fragment2 for the animation to play. I have this part working, when I select an item, the 2 shared Views do animate, just not exactly how you would expect when doing it between 2 Activities.
If I select an item near the bottom of the screen, it draws the View for Fragment2 and animates the 2 shared Views as if they were in the item at the top of the screen. Hard to explain. Here are some pictures
Fragment1
Fragment2
In both fragments I'm setting the following
setSharedElementEnterTransition(new ChangeBounds());
setSharedElementReturnTransition(new ChangeBounds());
setAllowEnterTransitionOverlap(true);
setAllowReturnTransitionOverlap(true);
Also in their parent Activity in onCreate() I've set
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
Any idea why my shared element animations are starting at the top of my screen even when the they were starting in the selected item at the bottom of my screen?
Finally solved this problem! As it turns out because the view I'm sharing between 2 fragments is a child of another view (RelativeLayout) in the 2nd fragment, you need to add the ChangeTransform transition to your TransitionSet. Apparently ChangeTransform tells the system to remember the views original position in the 1st fragment before animating to the new position in the 2nd fragment. Here is my updated transitionSet. I'll also clean up my test project code a bit and make a final push to bitbucket in case it will help others after me. Thanks for all the help with this one Alex and thank you to #George-mount for answering someones similar question that dropped the hint to me for this solution.
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeTransform/>
<changeBounds/>
</transitionSet>
https://bitbucket.org/brockoli/fragmentsharedelements