how to apply shared element animation in ViewPager fragments? - android

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

Related

Android ViewPager with all fragments of same class without transaction

I know this question has been asked many times before but I couldn't find an explanatory answer.
I want to have a single MyFragment.java and display it for all 3 pages of ViewPager.
But when I try to create a fragment with this method:
new MyFragment()
and add it to the ViewPager I get this error:
java.lang.IllegalStateException: Fragment already added
at androidx.fragment.app.Fragment.setInitialSavedState(Fragment.java:679)
at androidx.viewpager2.adapter.FragmentStateAdapter.ensureFragment(FragmentStateAdapter.java:269)
at androidx.viewpager2.adapter.FragmentStateAdapter.onBindViewHolder(FragmentStateAdapter.java:175)
at androidx.viewpager2.adapter.FragmentStateAdapter.onBindViewHolder(FragmentStateAdapter.java:67)
at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
I'd like to know if there is any possibility to add the same fragment to ViewPager.
Possible applications of it include
A web browser having WebView fragments in Viewpager
Why exactly do we need to use singleton fragment?
Why can't we treat fragments as recycler items which can be multiple instantiated?
Even the viewpager2 is becoming more like RecyclerView.
If it is impossible to instantiate fragments repeatedly and add them
to the same ViewPager then are there any other ways except replacing
fragments in ViewPager adapter with normal inflated views? Would that
be a tolerable solution?
You get this error because when you add the fragment you don't put a distinct tag on it, so it checks whether the fragment is already added by its class. And the viewpager stores some pages in memory, so the previous fragment even though is no longer in view, is still in the memory.
When you add the fragment, give it a distinct tag

ViewPager or RecyclerView with fragments?

I am a little bit confused on how should I approach this particular case of doing some swipes between fragments.
So yea, I asked ViewPager or RecyclerView, because these 2 are my only options, if anyone can come up with a better idea, it is really welcome.
The flow is the following, I have a Main Timeline(ListView), each item of it opens a fragment with details about it. What I would actually want to do is to swipe between these full screen fragments without going back to MTL and open another item of the list.
You would ask me what I tried, well:
RecyclerView - HORIZONTALLY oriented as a root of the fragment, and each item of this RV had the details of each event. The problem with this is that it gets really buggy because I have a huge logic inside each item(like, another RV - horizontally , a PagerView also horizontally to swipe between images (or a youtube frame that is being played if is the case. Plus a lot of other stuff in this, so the logic of parent RV inside the onBindViewHolder() is really tricky.
Would be better to use a PagerView with fragments(since I have the DetailsFragment kind of ready) ? The problem here is that I need a certain number of swipes, right ?
Go with viewpager.
Because creating fragments inside recyclerview causes recyclerview performs to slow down.Also to create fragments in onBindViewHolder() dynamically every time you need different unique id of frame layout to load which will be tough to generate.
For more information on why recycler view is bad idea to load fragments check this.
Fragment replacing in RecyclerView item
Also try to use the ViewPager with an implementation of FragmentStatePagerAdapter. The adapter will optimize the memory usage by destroying fragments that are not visible at a given moment.
Check the documentation for details and code sample.
https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html

How to launch new viewPager on reaching last page of current ViewPager

I am making a book reading application. Each chapter is an entry in drawer list. I have multiple view pagers, each corresponding to an item in drawer list. How to launch next view pager (next chapter) on reaching to end of previous one.
Post some code to understand the context.
But as a general solution, we can add a page dynamically to viewpager while swiping, instead of adding a new viewpager.
This seems to be ugly but you can try changing the visibility of the viewpager when required.
When you finish the first viewpager i.e. viewpager1,set:
viewpager1.setVisibility(View.GONE);
viewpager2.setVisibility(View.VISIBLE);
P.S.: Initially set all viewpagers .setVisibility(View.GONE); except the first one.

Have a ViewPager scan through the same instance of a Fragment

I have seen lots of examples of how to use a ViewPager to scan through multiple instances of the same Fragment. I don't want to do that. I want to have a single instance of a Fragment that runs off the edge of a screen and use a ViewPager (or at least the nice clean ViewPager swiping effect) to scan through the different sections of the single fragment. Is this possible?
Is this possible?
You can:
Use nested fragments for the pages in ViewPager, or
Use views for the pages in ViewPager, such as in this sample app, or
Use HorizontalScrollView instead of ViewPager to wrap around a single wide view

Mixing layout values each other when use same layout for different fragments in ViewPager

In my Android application there are two fragments called FragmentA and FragmentB. I added both fragments to a ViewPager using a FragmentAdapter So when I run the application I'm getting a unexpected layout (both fragment layouts are mixed together). Whenever I tried changing the currentItem of ViewPager by swiping for each time the layout is mixing each other.
My question: Is there any problem if we use same layout to different fragments in a ViewPager?
I found the answer.
There is no problem if you use getView() function of Fragment to refer the current root view of a fragment. So that you can get exact views in the Fragment. You can use like this(getView().findViewByid(...);
But there is a problem if you use activity reference to refer views in the fragment. Because all views in each fragment which is using same layout xml has same id. So if you change the value of a view in a fragment that will reflect in other fragments which are using the same layout in ViewPager. One more thing, think like this, when the activity created, all the fragments in the ViewPager of that activity will also be created and runs in background. So if you change the value of a view, android will return 1st view which is having the same id. Android knows only id of views. So always refer views of fragment using it root view (getView()).

Categories

Resources