Android Fragment Transitions with GLSurfaceView - android

I have a GLSurfaceView in a fragment, with this being my main fragment. When I do the transition from the fragment with my GLSurfaceView to another fragment without a GLSurfaceView, the GLSurfaceView moves up a little bit before the transition starts.
I have tried setting the GLSurfaceView.setZOrderOnTop(true), it doesn't work, and it actually does more harm then good in this situation since my ads and navigation drawer becomes obscured.
I have tried hiding the Fragment hosting the GLSurfaceView, still has no effect.
I tried pausing the fragment hosting the GLSurfaceView , thus pausing the GLSurfaceView at the same time, has no effect.
When the GLSurfaceView moves up then the screen is black where the GLSurfaceView is suppose to be. It seems like the black area on the screen is specific to the fragment transitions, since if I remove the transition and simple do the replace with the fragment transaction then the glsurfaceview movement is gone. This isn't a solution though because I want the transitions in my app from one fragment to another.
Lastly, I realize that ondestroyview is being called on the fragment with the GLSurfaceView, thus destroying the view before animating the transition to the next fragment, and I think this may be the problem.
Here is some code...
Adding fragment with glsurfaceview
//clear all fragments from the back stack if there are any
getSupportFragmentManager()
.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
//start a new deploy fragment
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container, new DeployFragment(), "Main Fragment")
.commit();
replacing glsurfaceview fragment with the preference list fragment
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left,
R.anim.enter_from_left, R.anim.exit_to_right)
.replace(R.id.container, new SettingsFragment(), "Settings Fragment")
.addToBackStack(null)
.commit();
When transitioning from the DeployFragment (glsurfaceview fragment) to the SettingsFragment (regular list fragment) the GLSurfaceView moves up a little, maybe about the size of the height of 2 actionbars stacked on top of each other. The glsurfaceview moving up also displays a black area on the screen where the GLSurfaceView is suppose to be, but it is not.
Any ideas how to fix this issue?
VIDEO OF PROBLEM
http://youtu.be/RUSNBd9iuXs
right after choosing an option you see GLSurfaceView move up, revealing black space

The only way to animate transition for SurfaceView is to draw before content to bitmap and set it as source of imageview on top of the layout with surface. But note, because it is big bitmap if it is full screen layout for android 2.x this approach can crash your app due to lack of native heap(not java) so I recommend doing this only for ics+

I think I figured it out. I wrapped my head around this for hours, so I will post what I believe to be a fix, but maybe not the BEST answer. What I found out is that if I use support fragments with the glsurfaceview, and try to animate transition to another fragment then I get the weird problem I describe above in the question and shown on the video.
If I use non support fragments, then this problem doesn't exist there. Using non support fragments comes with a whole lot of other problems so if anyone comes up with a fix to this problem while using support fragments then I am all ears.
problems with using non support fragments
i must at least target api 11 (honeycomb) or higher, as time goes on this will become less of a problem
i am using nested fragments, so I have a choice of mixing support with non support fragments which is nasty, or targeting api 19 or higher to use getChildFragmentManager() with non support fragments, which is also nasty.
i am using the view pager, so looks like I have to again mix support with non support or import fragmentpageradapter for v13, which is compatible for api 13 and up.
Thanks!

Related

GLSurfaceView turns black during fragment transition

In one fragment in my app, I use a GLSurfaceView to render a 3d model. When this Fragment is visible, the user can navigate to another Fragment from it. While that Fragment transition happens, the whole GLSurfaceView turns black.
I started having this problem when I changed from setZOrderOnTop(true) to false. I understand the difference this makes, but It's not possible for me to use setZOrderOnTop(true) (I Have other Views and animations that needs to overlay the GLSurfaceView).
I have tried everything I could think of and everything related from Google searches, such as using backgrounds, hiding the view, replacing it with dummy view during transition etc. without any luck.
Does anyone have an idea how I can solve this?
Notes:
I must not use setZOrderOnTop(true)
I use Support Fragments
I'm currently testing this on a Sony xperia z3, running 6.0 marshmallow
The only time I have this issue is when transitioning from the fragment with the GLSurfaceView, not when I transition to it.
My Renderer uses glClear(..) to color render the whole view in a white color. My issue is not in the GL Code

Placing Fragment Above ActionBar

I have a Parent FragmentActivity with a main view where I do FragmentTransactions and periodically switch views. But one particular view (a Fragment) is animated and slide in from right side of screen. I would like the view to be above (or on top of) the ActionBar.
The best example is taken from the app WunderList. Here is a screenshot.
Their app ALSO slides in and animates and this is exact functionality I am trying to duplicate. Can you do this with a Fragment? Or is this probably a new Activity?
You can't put fragment over ActionBar, but you can play with hide/show ActionBar.
On your new Fragment (on method onCrate) call:
your_activity.getSupportActionBar().setShowHideAnimationEnabled(false);
your_activity.getSupportActionBar().hide();
Then, when you want to came back to your previous screen, show ActionBar, call on method onPause:
your_activity.getSupportActionBar().setShowHideAnimationEnabled(false);
your_activity.getSupportActionBar().show();
You can do it the way you want (with or without Fragments). As answered in the other post, we've released a library that makes the sliding layer work for you (just drop it in your xml as a normal container and put whatever you need inside).
That said, the remaining issue is more related to the ActionBar being at the top or bottom layer and that has more to do with the place that it takes in your app. In the end you'll have to play around with the indices of your views and the ActionBar within their container.
For instance we did our own ActionBar which made it easier to play around and decide who goes on top and underneath, but as said it shouldn't be too much of a big deal even with the native one or Sherlock ones.
Can you post a picture of what you want to achieve?
I was able to Achieve the above effect using Fragments. Use :
fragmentTransaction.add(android.R.id.content, fragment_instance);
where android.R.id.content is always the root element of a View since api level 1 .

Full managing of fragments flow in Android

I have a special flow of fragments in my app, so I need to be able to switch to any fragment, while keeping fragments in memory whenever possible (so if it's tight on memory, it's ok that the fragment will be released).
So far, I've succeeded doing a replace of the current fragment, but the thing is that the previous fragment is always being destroyed, so if I go back to it (using the action bar, for example), it's re-created and that takes some time.
The reason I use fragments instead of activities is the nice usage of the action bar, the ability to put multiple fragments inside the same container, the non-flexible activities-intents usage, etc...
The reason why I don't use the "Back" stack is that I wish to go to any fragment from any fragment, since the flow can change.
Here's a snippet of my code:
Fragment fragment=... ; //get the fragment from cache or create if not available yet...
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.mainActivity_fragmentContainer, fragment).commit();
I have also tried to use ViewPager, but since I don't want to have the sliding effect (which allows you to slide to other fragments) and since one of the fragments already include a viewPager, it's an obstacle. Disabling the sliding effect on the main viewPager somehow disables it on the other one.
BTW, I'm using the android support library for the fragments and not the native API.
my question is:
how can i achieve full control of which fragment to go to , while maximizing speed and avoiding too much memory being used for fragments ?
EDIT:
for now , i use the next workaround :
for the onDestroyView , i take the parent of the created view and remove the created view from there .
for the onCreateView , if i already have the created view from before , i return it .
however , i think it's a very risky thing to do , since i'm not sure of how fragments managing work , so it might cause weird problems . plus ,i'm not sure what will happen if android decides that it has low memory - will it destroy unused fragments (which is good) or will it cause out-of-memory exceptions (which is bad) .
I agree with your comment regarding "it's very risky". Since the consequences of your approach are not really clear, I would not recommend using this.
To better understand your issue and to give you some indications:
what do you consider to be slow? I keep switching fragments "like crazy" too, and it works OK on a tablet, however on some low-end phones it takes much longer - but is still acceptable
How much work do your fragments need to be created? ie what kind of underlying data needs to be preapared each time? (again, I have several list fragments with more than 1k entries, they get prepared each time, and it's quite fast)
how do you exaclty replace fragments? In particular do you call getFragmentManager().executePendingTransactions();
One way to accomplish your goal is to use FragmentTransaction.show and FragmentTransaction.hide. You can use Fragment.isAdded to determine whether to show or to call FragmentTranscation.add the first time. The downside is that you won't get Pause/Resume events when fragments are shown and hidden; you will need to override onHiddenChanged. You will also have to manage your own stack if you want to support back navigation.

android fragment animation using compatibility package

How can I use animation for transitions between fragments ? I tried
FragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
FragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left,
android.R.anim.slide_out_right);
changing the animation to different kind of animations, but it always seems to animate like fading-in while pushing fragment and fading out while popping fragment.
I know this question is very old, but I stumbled upon it while looking for an answer to this myself.
I'm currently using animations in my compatibility package, fragment based app, and it's actually quite simple.
Add this before actually adding / replacing the fragments:
FragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left,
android.R.anim.slide_out_right, android.R.anim.slide_in_left,
android.R.anim.slide_out_right);
Your new fragment will slide in from the left on push, and slide out to the right on pop.
Of course this also works for other default animations, or custom animations.

Animating fragments and the back stack

I am having trouble using or understanding how popping
FragmentTransactions off of the back stack handles the custom
animations. Specifically, I expect it to call the "out" animation, but
it doesn't seem to.
I have a simple method to handle a fragment transaction
(FragmentTransaction) where I add a fragment and apply a custom
transition so that it will fade-in/fade-out. I am also adding this to
the back stack so that the user can undo that transaction with the
back button, essentially navigating to the state before the fragment
was added.
protected void changeFragment() {
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
ft.add(R.id.fragment_container, new TestFragment());
ft.addToBackStack(null);
ft.commit();
}
Everything works great moving forward, but when the user clicks the
back button, the transition animations do not reverse. What I expected
was that when the fragment got removed, it would use the fade out
animation. Instead it seems to pop out (without animation) and then
the container seems to fade in. I'm not sure that this is exactly what
is happening, but the fragment is definitely not fading out.
My application uses the compatibility library to add fragment support,
but I assume this to be applicable to Honeycomb (android-11) as well.
Does anyone know if I am just doing something wrong here or if I am
just expecting too much? Ideally, I would like to animate the
fragments similarly to how Gmail (on the Xoom) does in regards to
moving forward by clicking a message and then back by using the back
button. Preferably not having to override the back button
functionality and keep up with my own fragment state since I could
have several "transactions" that I would want to back out of and I am
not a fan of re-inventing wheels.
Also asked on the Android Developers Group: http://groups.google.com/group/android-developers/browse_thread/thread/1136a3a70fa0b6e9
I use this:
ft.setCustomAnimations(R.anim.slide_in, R.anim.hyperspace_out, R.anim.hyperspace_in, R.anim.slide_out);
and the transitions work in reverse when the back button is presses.
The bug was fixed in the 3.2 release with the addition of the following new api:
http://developer.android.com/reference/android/app/FragmentTransaction.html#setCustomAnimations(int, int, int, int)
It's to be noted that it has not yet been back-ported to the compatibility library (as mentioned in the bug report).
It's a bug, look at bug report 15623. One of the Android project members commented that the fix was too late for release 3.1 but it should make it into the next release.
The same member goes on to say that...
The problem is that the same
animations are run on a pop operation
as were run to put the fragments in
their current places. For example, in
the sliding example above, on a
forward operation (pushing the old
fragment onto the stack and moving the
new fragment into view), we slide the
old fragment out from the center to
the left and slide the new fragment in
from the right to the center. When the
stack is popped, these same animations
are run: the most recent fragment is
animated 'out' by sliding it in from
the right to the center (after which
it disappears, since it's being
removed). The old fragment is popped
off the stack and animated from teh
center to the left ... right off the
screen.

Categories

Resources