Shared element transition from recyclerview in fragment - android

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).

Related

Shared Element Transition from a recyclerView Item to another activity's recyclerView Item?

I am not sure, if this is possible or not but I have RecyclerView in Activity A. On clicking any of the item, it should open a new Activity (let's say Activity B), which is again containing a RecyclerView.
So, I want to achieve a Shared Element Transition relationship from Activity A's any item to Activity B's first item, which is always the item clicked in my previous Activity A. And then on scrolling in Activity B, we should be able to see all the other elements, which is fetched from different API source.

Share element transition between recyclerview item inside viewpager fragment to viewpager fragment

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.

how to make vertical scrolling list in sync with view pager

I have vertical scrolling list in Activity 'A' and view pager in Activity 'B'. When a user clicks on an item in Activity 'A' it goes to Activity 'B' for detail. Now user can swipe left or right to view details of next item inside list directly from Activity 'B'.
List in Activity 'A' is endless scrolling, when it reaches to end it loads more items automatically.
I am using fragment which represents one page inside view pager in Activity 'B' which takes the same object as a parameter as in RecyclerView item in Activity 'A'.
This pattern is commonly used for reading articles.
Now my question has two parts:
First is how to use the same data list for both activities? I want to keep data at one place as both activities using same data, only representation and navigation is different, one inside RecyclerView and other is inside ViewPager and data list is already loaded for RecyclerView in Activity A. Moreover data is also large so i don't want to duplicate data in memory for each activity.
Second is when i swipe next from view pager and go to next item's detail in activity 'B' the recycler view in Activity 'A' should also scroll to next item synchronously, although it's not visible to user. so that RecyclerView can load more items when reaches till end and ViewPager can also behave endless swipe like endless scrolling list. Is there any way to achieve this behavior?
Thanks in advance.
You can use Local Database for this purpose. So both activity will access data from DB. Only pass index of item to second activity and onPageScroll listener you can change that index and get data from DB according to page swipe(left/right).

Background Glitch while using shared elements

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

Shared elements animating between fragments

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

Categories

Resources