Android - Animate fragment entrance after it's drawn? - android

I'm using the Support Library and replacing a fragment with a custom slide-in animation.
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(enterIn, enterFragmentOut);
transaction.replace(R.id.content_frame, contentFragment);
transaction.commit();
The problem I'm experiencing is that the animation starts concurrently with the drawing of the fragment's views, and since the fragment has a rather complex layout (ListViews, &c) the animation is very stuttery (only a handful of frames are shown).
I've tried splitting the operation into two parts (with transaction1 = {add_new, hide}, transaction2 = {remove_old, show}) and firing the second transaction after onCreateView() has executed on the new fragment, but I didn't get much improvement at all.
What I'm looking for is a way to start the animation after the new fragment is fully drawn, if that's at all possible. Or any other tips that you may have on this issue...
Any ideas? Thanks a lot.

Related

Android: Hide viewPager tabs when launching a fragment from one of the viewPager tab fragment

I have a viewPager in my app which has several tabs. In some of the tabs, on clicking an item a new fragment is shown. I want this fragment to cover the tabs. Doing this is possible but the approaches don't look good to me.
1.) one way is that I add the newly created fragment to the activity using getSupportFragmentManager(). This solves the problem but doesn't look like a good idea as it will create problems when using back button etc.
2.) Other way is to hide the tabs manually using Visibilty.GONE but problem with this approach is that this hiding of the tabs is visible, I mean the animation could be seen and looks bad.
Is there a better approach to do this problem?
This is my code. "sub_fragment_container" is present in the activity xml, so I get an error java.lang.IllegalArgumentException: No view found for id 0x7f0e00ff (com.my.app:id/sub_fragment_container) for fragment DetailFragment{
FragmentTransaction fragmentTransaction = getChildFragmentManager()
.beginTransaction();
Fragment profileFragment = new DetailFragment();
profileFragment.setArguments(bundle);
fragmentTransaction
.add(R.id.sub_fragment_container, profileFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Use android:animateLayoutChanges="true"
Or, to fine tune it further, here's a tested method that I've personally used in my app Newslet to solve the exact same problem.
Wrap your Toolbar and TabLayout within an AppBarLayout. This should be easy if you're aware of the Design Support Library. If not, this should get you started.
Add this piece of code in your onCreate():
LayoutTransition layoutTransition = new LayoutTransition();
layoutTransition.setDuration(200);
layoutTransition.setStartDelay(LayoutTransition.CHANGE_APPEARING, 0);
layoutTransition.setStartDelay(LayoutTransition.APPEARING, 0);
layoutTransition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
layoutTransition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
appBarLayout.setLayoutTransition(layoutTransition);
After this, when you remove the Tabs or add it back, the layout change will animate smoothly.
Hope this helped you!

programmatically adding custom animation to fragment using objectAnimator

I currently add custom animation to my fragments using the following code.
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.animator.slide_in, R.animator.slide_in, R.animator.slide_out, R.animator.slide_out );
ft.add(R.id.container, new Doze1Fragment());
ft.addToBackStack(null);
ft.commit();
Now I'm playing around with adding a few different fragments on top of each other in a span of 3 to 5 seconds and then pop all of them out of the back stack to get a "fanning" animation out of all fragments. In order to do so I either add a delay in between each popBackStack() call (I think this is a horrible solution), or make a custom XML animator resource for each fragment. I was wondering if anyone has any idea of how to do this programmatically right before calling ft.add(R.id.container, new Doze1Fragment()). I know that normally I could use the following code to animate a view and I was looking for something similar
ObjectAnimator oa = ObjectAnimator.ofFloat(R.id.container, "x", 0, 1000f);
oa.setDuration(300);
oa.start();
Thanks in advance.

Android: Alternative to fragments (Performance issues)

I'm using tabs to switch pages in a container view. This works smoothly until I fill these pages with different kind of layouts or objects. The performance drops and it gets lower frames per second (no project butter here at all :D).
Can I use something else than fragments for this? Also if I want to keep the information (lets say I input my name on page 1) even when I have switched to another page?
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE );
transaction.replace( R.id.container, new FirstFragment() );
transaction.commit();
Each button in my tabsholder has its own fragment to change to.
What is making my performance drop? Is it not removing views? What should I use instead?
This is a rather wide question but I wouldn't know where to turn.

transition speed across fragments

I am using fragment and i have setTransition for the fragment. fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
How to increase the speed of the transition for the fragments?
setTransition is for selecting the standard transition animation for the transaction. You can check setCustomAnimations if thats what you need. I have never used that though.

Swapping Fragments in a Single Activity?

On the tablet we have two fragments (two different views of the same data) that sit next to each other. On mobile devices we'd like to switch between these two fragments at the push of a button. The mobile layout looks something like this:
<RelativeLayout>
<fragment id="container" name="fragA"/>
<ImageButton onClick="swapFragments" />
</RelativeLayout>
In the activity's swapFragments(View) method, I'm attempting to use the FragmentManager to replace fragA with fragB:
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, new FragB());
fragmentTransaction.commit();
...but I can always see fragA through the transparent parts of fragB, leading me to believe that it's just putting fragB on top of fragA, not replacing it.
I'm starting down the path of using hide(Fragment) and similar methods in the transaction, but that doesn't look like the right way to do it.
Any tips on how to swap these fragments the right way?
Edit: I saw the answer to this question. This confuses me, though, as I need to be able to specify a different layout for tablet and phone. If I have to programmatically add fragments, how do I avoid code specific to each layout in the activity (i.e.
if(TABLET) {
addFragmentA();
addFragmentB();
} else {
addFragmentA();
}
Don't mix Fragments created in XML and in Code - bad things will happen. Keep a container view in the layout, then add / replace fragments into it (don't have the first fragment inside it).
Looks OK to me, I'm doing something similar albeit I'm adding my initial fragment from the activity using add rather than having it loaded by referencing it in the layout. There might be a bug there. FYI I'm using the compatibility library.
Might be worth trying:
1) Add the transaction to the back stack to see if that makes a difference, it seems like you may want that functionality anyway.
2) Give your fragment in the layout an id or tag, then use that to perform a remove and add fragB instead.
3) Try loading your fragA from code instead and see if that makes a difference.
well, first of all you can try using the newInstance() factory method for instantiating the fragment B and not just new FragB().
However, I think this is not the problem.
Can you just try not to use in you XML layout the fragment tag?
Just do something like this:
<RelativeLayout>
<Linear/FrameLayout id="container" name="fragA"/>
<ImageButton onClick="swapFragments" />
</RelativeLayout>
So use like a Frame or LinearLayout as container for you fragment and inflate it in the onCreateView callback from the Fragment. Maybe it helps, let me know.
Cheers!
As far as I can see you are not hiding / detaching the previous fragment so both will be displayed. You can implement something like this:
if (mFragment != null) {
ft = mActivity.getSupportFragmentManager().beginTransaction();
ft.hide(mFragment);
ft.detach(mFragment);
ft.commitAllowingStateLoss();
}

Categories

Resources