Animation between different instances of one fragment - android

I'm trying to add animation to my android app, and knew a lot about transition animation between activities, and about fragments. So I have MainActivity with some view (image), and SecondActivity which is empty itself, but contains fragments, which then needs to be used to display some detail information about this image. I've read about postponeentertransition() and it worked. But the problem is, that this fragment in second activity have links(or transitions) to the same kind of fragment.
Let's say in main activity I have set of images of cars, then I click one, second activity is starting and waiting for fragment loading, and then shows animation. And then, in this fragment I have "similar cars" recycler, and choose one of them, and wants, to show its details the same way, but with adding this fragment to the backstack (not replacing). So the problem is that transition name of the view in main activity and big image of fragment are the same (which is obvious), and transition name in fragment's recycler and big image of the next fragment have to be the same too(otherwise app doesn't know how to make the animation). On the other side, fragment (which was added) has to be the same class, but its different instance.
I just want to set up animation without crashing the existing architecture.:) If you have any solutions or advices how to make animation between different instances of one fragment, please help.)

Use setCustomAnimations on the Fragment transaction (see below). It doesn't matter if the instances are from the same class.
FragmentTransaction transaction = mActivity.getSupportFragmentManager().beginTransaction();
// To animate the fragment
// NOTE: Must be before replace/add otherwise it doesn't work
transaction
.setCustomAnimations(enter, exit, popEnter, popExit)
.replace(R.id.frame_container, fragment, null)
.commit();

Related

How to avoid reloading of child fragment inside parent fragment on BackPressed in Android

My main fragment has too many views to load because the lines of code in the file are increasing. To avoid this I decide to separate views using a child fragment. So now upper views are in the child fragment and the remaining bottom views are in the main fragment. Till this ok.
Now I am opening a new fragment by clicking one view from the main fragment. When I came back to the main fragment it is reloading the child fragment because of that I am getting NullPointerException and the app crashed.
Following is the way I am adding child fragments.
childFragmentManager.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commitAllowingStateLoss()
For more understanding.
I am using Navigation with BottomNavigationBar.
How to avoid this?
In some cases, fragment views are flickering when back to that fragment. How to avoid that?
For your first question you want to avoid putting the fragment in the backstack.
childFragmentManager.beginTransaction()
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)//<-- Here
.commitAllowingStateLoss()
For your second question Fragments are destroyed to conserve memory,typically happens when you can't see it. As such the recreation process could take some time, depending on how heavy the view is, thus the blinking.
The only way to stop it from blinking is to make sure the Fragment isn't doing so much that it can't seamlessly load back in.
You could do this by lazy loading your more heavy views, like lists, videos, and large images.
You could also look into Fragment transitions. These could visually smooth out the process of loading.
Here is a great source for some standard animations.
Fragment transaction animation: slide in and slide out

Show nested fragment on screen rotation without showing parent fragment

When rotating the screen my nested fragment is shown but for some brief moments, the parent fragment is also shown.
I have my MainActivity that has a FrameLayout with ID activity_base_container.
I'm doing this when my activity starts:
Fragment initialFragment = getInitialFragment();
mFragmentManager.beginTransaction()
.add(R.id.activity_base_container, initialFragment, initialFragment.getClass().getSimpleName())
.commit();
That initialFragment initial fragment is responsible to check some conditions and depending them will launch one of two possible fragments:
fragmentManager.beginTransaction().replace(R.id.activity_base_container, fragment, fragment.getClass().getSimpleName()).commit();
Lets assume it launches FragmentF (whit a root FrameLayout with id fragment_f_root). This fragments layout has a set of options. When the user clicks one of those options, the corresponding fragment is created and is launched like this:
//The example here is an option that displays a google map.
fragment = FragmentMapMultipleActivity.newInstance();
fragmentManager.beginTransaction()
.replace(R.id.fragment_f_root, fragment)
.addToBackStack(fragment.getClass().getSimpleName())
.commit();
At this point all is working as expected. The problem is when I rotate the screen. FragmentF appears briefly and then immediately FragmentMapMultipleActivity, the nested fragment, appears.
Is it possible after rotating the screen show only the nested fragment or I should change my "architecture" to something else?
should change my "architecture" to something else?
Probably, you should.
The brightest Android-minds from Square are even advocating to avoid simple fragments everywhere it's possible: Advocating Against Android Fragments
Nested fragemnts, in its turn, increase complexity exponentially. The only good pattern of using them I've seen so far is ViewPager with it's FragmentPagerAdapter. In majority of other cases, consider using Custom Views instead.
It keeps your app's lifecycle cleaner and more predictable.
I don't think you can do much with this blinking you see, apart from:
setRetainInstance(true) and avoid full re-creation of the Fragment in Activity, so you keep you fragment's data during change of the configuration (and then pass same retained fragment to the fragment manager)
keeping layouts as lightweight as possible
avoid re-creation of already initialized variables
keep onViewCreate() as lightweight as possible
Good luck!

How to prepare a fragment before I add it to the view

I have an app that initially displays one fragment, when a button is clicked it transitions to the next fragment. However inside the 2nd fragment there's a ViewPager that holds images from a URL. It can take some time to process all the images. And it is processing the images as the button is clicked which then slows down the speed the fragment gets set up, which takes a lot of time. I want the fragment to be there and prepared instantly.
I can fetch the images in the mainActivity. I however cannot set them to the ViewPager before the fragmentTransaction is committed because the ViewPager doesn't exist until the onCreateView method occurs in the fragment which is only called when the transaction is committed. Is there any way to have the fragment set up in the activity before I commit the transaction.
So the user can easily switch between the two fragments without having to wait for them to process. Or should I have rather used tabs. The thing is I don't want a tabs bar to appear at the top of the screen. I want the tabs to change when by button is clicked.
It sounds like you're processing the images in the main thread? I think it would be best if, instead, you just pass the URL to your second fragment and have it use a Loader to process those images in the background, with placeholders for each image as it's getting loaded.
If you insist on doing the loading in the first fragment, you should just be able to set up and add your second fragment without any images, but have it be hidden. Then, once your loading is complete, you will still have access to your ViewPager from your first fragment and can use another transaction to show the second fragment when ready.
P.S. it would be easier to read/understand your question if it was laid out more logically and not a huge paragraph.

Android fragmentTransaction add() and fragment's onPause

I've implemented navigation in my Android app as one Activity and many Fragments.
When I open new child Fragment, I call this:
FragmentTransaction tx = getSupportFragmentManager().beginTransaction() .addToBackStack(null).replace(R.id.fragment_container, f)
.setBreadCrumbTitle(f.getClass().getSimpleName());
tx.commit()
This works quite well, as old fragment isn't destroyed, so when I go back in the back stack, the old fragment retains the scroll position and everything entered on it.
The problem is, in one Fragment I actually need to pause something when I add another fragment above it. I've thought that onPause() will be called, but it doesn't - I suppose that all other fragments live beneath the ones on top of them.
On the side note, I also think that my app gradually slows down as the user navigates deeper. Shouldn't I be replacing the fragment in the transaction instead, so only one is on the top?

FragmentStatePagerAdapter fails to load the fragments again when I get back to old instance of the parent Fragment

Scenario:
I have a fragment which has a ViewPager which contains 5 instances(different) of a single Fragment with different values, each having a listivew that contains some sort of items.
Problem:
The flow goes smooth when I click an item of listView(say on page1) but the moment I come back from there on pressing back (overridden OnBackPressed in the main_activity (will discuss later)), the viewPager fails to load the subFragments.
But when I switch to the 2nd or 3rd page, it gets displayed, and on going back to 1st page, it now gets displayed.
OnBackPressed():
I am maintaining a manual stack here. When I click on an item of ListView, the current Fragment Instance (of the parent Fragment ofcourse) goes into stack. And when user comes back , that instance gets popped off the stack and I replaces it on the activities FrameLayout container.
References:
Fragments not getting recreated by FragmentStatePagerAdapter after coming back to the main Fragment instance
Guys, I am really pissed off here, please help me out.
Frankly, I haven't worked much with fragments.
But it seems like the page is being thrown off the memory every time you switch to other pages. I am not sure but if there is a way for android to manage this and keep the page in its memory persistently, it might solve the problem
Finally I am able to get a workaround for this issue, which included two things:
while replacing the fragment make a call to
ft.replace(R.id.content_frame, frag).addToBackStack(null);
while initiating the ViewPager, the fragment manager to be used is :
mAdapter = new myAdapter(getChildFragmentManager());
Actually the problem is that, android fails to recognise and load the older instance of the fragment unless you explicitly add that instance to the backstack. So after adding it to BackStack, there is practically no need to maintain your own manual Stack, but you still can do that.

Categories

Resources