I am working in android 2.3 and I have an issue which is a bit of a pain.
I have 2 layouts on top of each other in a FrameLayout. The top layout is moved partly off-screen during an animation, and the .layout() method is called in the animation end. This works great and the ui is moved correctly and the buttons of the toplayout is still clickable.
After the animation the second layout is visible as the toplayout is moved off-screen. This layout contains a list which is clickable and each cell has an ImageView which is updated when clicked. However my problem is, when the table cell is clicked and the ImageView is updated, the entire view is reset, ignorering the animation and new location of the toplayout. It just sets the toplayout back on top as the animation never happend.
I use an TranslateAnimation and the set fillafter is set to true as well.
Do you guys have any suggestions to what I might be missing.
I guess your problem is placing objects inside FrameLayout. As described in this answer you cannot place a view inside a FrameLayout by setting its location.
It's true that with FrameLayout all children are pegged to the top
left of the screen, but you still have some control with setting their
padding. If you set different padding values to different children,
they will show up at different places in the FrameLayout.
Use padding instead to "move" the view off-screen.
Related
I am trying to animate layout changes for a LinearLayout contained in a HorizontalScrollView with fillViewport=true. The idea is that I have a dynamic bar of buttons that should distribute to fill the available space, but if there are too many buttons you can start to scroll left/right to see them all.
This all works great, and using animateLayoutChanges=true on the LinearLayout works smoothly if the HorizontalScrollView has fillViewport=false, but as soon as it is set to true, jerky motions start to happen:
You will notice that the settings button jumps straight to its new position, while the right two buttons initially jump, but then animate a little to their final positions.
For me it seems relatively clear that the problem is that the extra x-offsets introduced by fillViewport=true are applied instantaneously, while the remaining shifting of the buttons is animated as normal.
Is there any way to get the animation to consider the effects of fillViewport=true as well?
Details only in case it matters: My HorizontalScrollView contains a LinearLayout that for each button contains a FrameLayout containing a Button (required in order not to stretch the button clickable area). I have tried applying animateLayoutChanges to the scroll view, to the frames, to the buttons, etc as well, but no combination seemed to make a difference.
I have a RelativeLayout (A), inside which I have 2 children:
- LinearLayout (B) (with some stuff)
- below it I have another RelativeLayout (C)
I wanted to add an overlay on top of it. So all I did was added a View with match_parent as it's width and height, and transparent background. All works great, as long as I do not add views dynamically to the nested RelativeLayout (C).
When I do that my overlay stops at the last element that was not added dynamically to the RelativeLayout (C). So the height of the overlay does not match_parent anymore.
I tried to go around it, and add the overlay after I add those dynamically added views to (C), but that also didn't do the trick.
What does the trick is if I set height explicitaly to the overlay after all views are created by getting getHeight of the main root of the view. That is however not the solution I want, as I want a clean solution, that I explained above.
Currently what I did to bypass it for the moment, is I added an overlay with a humongous height(like 2000dip) and set it's bottom alignment to RelativeLayout(C). That does the trick perfectly (the effect of it), however I still would preffer to know the reason why adding dynamicaly those views does not update the height of the overlay (also if I add it dynamically after previous views).
Just to mention, I tried to do requestLayout(), invalidate(), and postInvalidate() on the main container after all views were added. No change.
ps. Might be important piece of information: this root RelativeLayout stated in the beginning is inside a LinearLayout, which is a single child of a ScrollView
Background:
I have an Activity that comprises four buttons that each take up a quarter of the screen.
It contains a horizontal LinearLayout that is divided in half by two vertical LinearLayouts as shown in the image below:
http://i.stack.imgur.com/P7Wd3.jpg
Desired Effect:
When I touch a button, I would like it to animate and fill up the entire screen.
Issue:
I have accomplished the animation aspect by changing X and Y scales from 1 to 2 onClick.
The problem is, however, that the animated button will not show when it leaves its parent LinearLayout.
Thoughts
I have tried making the non-animated buttons invisible, but the animated button will only show in its parent LinearLayout.
I know this problem would be solved if I had used a single LinearLayout, but I was unable to use the "layout:weight" feature to make each button take up half of both width and length.
So... How should I approach this issue?
I would appreciate any help :)
Try using a single RelativeLayout. Check this post for a nice example. You may have to setVisibility(View.INVISIBLE) for the other buttons.
Alternative:
Construct a RelativeLayout as above but put that as the only child
of a FrameLayout.
When animating a button, remove it from the RelativeLayout and add it to the FrameLayout specifying the gravity in the LayoutParams appropriately. This way the rest of the buttons will also be seen in the background during the animation.
Let me explain the scenario that I want to achieve:-
Consider the below as the Layout I have inside a Parent_Linearlayout:
[Linear Layout] (Fill_Parent, Wrap_Content)
[ScrollView]
Activity's setContentView is set to the Parent_Linearlayout
In the application, when a condition is met, I want the Scrollview to be removed from the screen and instead put another View in its place.
I've been able to do this, & when I remove the ScrollView, I'm applying translate Animation to it so that it seems as if the View has gone to the top -before removing it.
But when the animation occurs, the ScrollView translates OVER the Linear layout present above it.
How do I restrict it, so that the scrollview does not go over the linear layout, but disappears at the base of the Linearlayout. I want the linearlayout to always stay visible..
I've been trying to do this from quite some time, but I've not been able to get desired results..
Could someone kindly help me out here??
I don't quite understand your description of your layout, but the Android view system is drawn based on the ordering of the views in the hierarchy. Views added later to a parent are drawn after those added earlier. So if you always want the LinearLayout to be drawn on top of the ScrollView if/when they overlap, then declare or add the ScrollView object to its parent before the LinearLayout object.
In thinking more about this, I suppose the ordering here is important because you want the ScrollView to be placed below the LinearLayout in the parent of both of these views. Putting the ScrollView first (and thus having it painted first) would then put it above the other LinearLayout, which isn't what you want.
There are various ways to achieve what you want. For example, you could use a RelativeLayout as the parent of the views, then the ordering is not important.
Alternatively, you could place the ScrollView inside another LinearLayout (and that LinearLayout would be the second child of the overall parent layout). Then when you animate the ScrollView, it would be clipped by its immediate parent, which I believe would give you the effect you're looking for (make sure that setClipChildren() is set to true on this new intermediate LinearLayout, which it is by default, otherwise it won't clip the ScrollView as it animates out of it). Note that this approach would necessitate different animation values, since you are now animating the view outside of its parent (the new LinearLayout).
I've got an absolute layout. In that layout is a custom view that takes up the left 3rd of the screen. I put a button in the layout that I want to cause the custom view to slide on and off of the screen. I've tried using animation resources (translates... "slidein" and "slideout") and the function startAnimation on the custom view, but I can't get the behavior I am looking for.
OK... I start with the custom view visible and in onCreate I find the view and animate it off screen using my slideout animation. That works fine. I figured out that I need to set "fillAfter" in the animation so that the custom view stays off screen.
Now, when I press my button I want to cause the custom view to slide back on the screen, so I trigger my slidein animation using startAnimation again but with slidein. BUT... that causes the view to first jump back to its original position AND THEN slide to the right... causing it to finish in the middle of the screen.
How do I get the animation to use the view's current position as the animation starting position, not its original position?
Thanks
I also experienced the flicker described in this question. My solution was to use the improved Honeycomb animation APIs. There is a convenient library that ports these all the way back to Android 1.0:
http://nineoldandroids.com/
For more on Honeycomb Animation APIs see:
http://android-developers.blogspot.com/2011/02/animation-in-honeycomb.html
In my case I had 2 overlapped LinearLayouts inside a RelativeLayout. I wanted to slide the top LinearLayout off the screen and reveal the bottom LinearLayout below. Then I wanted to slide to top LinearLayout back on screen to its original position so the top layout covered the bottom layout again. Using the old animation APIs I was seeing a flicker before the second animation (offscreen -> onscreen) was starting.
With the new APIs this task turned out to be trivial:
// Slide out (add to button handler)
ObjectAnimator.ofFloat(mTopLayout, "translationY", mTopLayout.getHeight()).start();
// Slide back in (add to button handler)
ObjectAnimator.ofFloat(mTopLayout, "translationY", 0).start();
The Honeycomb Animation APIs actually move objects around on the screen (rather than pretending to move them like the older animation APIs), so there is no need to fool around with filleAfter, fillBefore, etc.
Look into setting the fillAfter property to keep the end animation state