I have an ImageButton with TranslateX Animation Right to Left like Merquee, So it animated right to left. Now when i click on that nothing happened. Actually click is not perform and click only perform on real position of imagebutton.
what to do any suggestion? greatly appriciate... Thanks
Use ObjectAnimator(For later version then Honeycomb) for Animatinfg Your Objects, You can use follwing code for references:
RelativeLayout layout = (RelativeLayout) findViewById(R.id.relativeLayout1);
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
ObjectAnimator mover = ObjectAnimator.ofFloat(layout, "translationX",
width, -width);
mover.setDuration(10000);
mover.setRepeatMode(Animation.INFINITE);
mover.setRepeatCount(Animation.INFINITE);
mover.start();
If you Are Using Api lower Then the HoneyComb(Like Gingerbread) then Use this Library: http://nineoldandroids.com/
It will Working As its Working in my devices.
As of now, the Animations which alter a View's matrix Only change the co-ordinates where the view is drawn, and not the actual location of View in Layout. So, its just a canvas transform when onDraw() of that View is being called.
So, you can setTranslationX(100) and view will be drawn a 100 pixels to right. But, the click area (getHitRect()) is still on the same place which was assigned to view on layout pass.
Or, you can actually place the view where it should be after animation, and run the animation in reverse.
If you want to actually alter the layout, you will have to alter that view's LayoutParams and change width/height/margin on it. Then you will have to requestLayout() on each frame of animation.
Example : This will animate left margin of a view inside a FrameLayout:
//---assuming animated view is a child of Framelayout---
FrameLayout parent;
View animatedChild;
ValueAnimator animator = new ValueAnimator();
animator.setFloatValues(0,parent.getWidth()); //--slide out to right--
animator.setDuration(1000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
FrameLayout.LayoutParams params = animatedChild.getLayoutParams();
Float margin = (Float) valueAnimator.getAnimatedValue();
params.leftMargin = margin.intValue();
animatedChild.requestLayout();
}
});
animator.start();
I run into similar problems before when developing my android app. And I found when animation is running, it is actually making the image layer is flowing around. So you need to click on the original position of the button, which means you may need to click on a black space if the button has started moving.
Related
I am trying to create a screen, on some operation it is required to slide a layout from bottom to the height to match it's length, with a translation animation kind of slide.
Have a look at the screen example:
As you can see the initial screen layout, the new view 5 slides in from bottom, pushing the entire layout upwards with an animation.
I have tried this: https://stackoverflow.com/a/19766034/1085742
Using the above link, the new view is visible with animation but screen is not sliding down to show the new view 5.
Any idea how to do this!!
Thanks in advance.
I also tested this. Apparently an animation with translateY or Y does not change the layout bounds. In other words, the other views do not move up. Neither when using an Animation nor an Animator.
One solution is to animate the margins, if the animated view is in a layout that supports margins. In Kotlin:
val collapse = ValueAnimator.ofInt(0, -someLayoutAndViews1.height)
collapse.addUpdateListener {
val params = someLayoutAndViews1.layoutParams as ViewGroup.MarginLayoutParams
params.topMargin = it.animatedValue as Int
someLayoutAndViews1.layoutParams = params
}
collapse.start()
I am a beginner in android animation. I have few views inside a RelativeLayout and i wish to change view position. What are the options i have and how they differ?
I have tried following:
view.animate()
.translationX(toX)
.setDuration(duration);
and
RelativeLayout.MarginLayoutParams params = (RelativeLayout.MarginLayoutParams) view.getLayoutParams();
ValueAnimator animator = ValueAnimator.ofInt(params.rightMargin, 100);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
params5.rightMargin = (Integer) valueAnimator.getAnimatedValue();
}
});
Both changes the position of the view. Can anyone explain me the difference in these two method. What other options i have and which is the preferred option.
view.animate()
.translationX(toX)
.setDuration(duration);
I think it's preferred one, because it doesn't call measure() and layout() on each update as the second one would.
And in general:
- translationX is meant to regulate the position of a child within its parent
- perform animation through changing margin parameter isn't a good idea (it's meant to be set once and to be changed rarely if ever)
The first one is the best solution. It's specifically created for animations, so it's the most optimized version.
You have to keep in mind that if you animate a view then the whole layout will be recalculated with each movement (obviously for the translation, but not for an alpha for example), so you have to keep the layout tree as flat as possible. If it's possible try to avoid the RelativeLayouts, since they are measured twice at each frame (https://youtu.be/HXQhu6qfTVU).
You can check out a lot of cool videos here about the performance issues: https://www.youtube.com/watch?v=ORgucLTtTDI&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE
I need to scroll a TextView to the bottom till it's gone by preforming an animation like translate animation in xml. I tried to create an animation file and used translate attributes in the xml, but what it will do is that it will go down by a specific distance that I set in the xml. I don't know how to let it translate to the bottom till it's gone and disappeared from the screen. One more thing is that I also want something like a listener that will perform some action when that TextView is gone and disappeared from the screen when the animation ends.
Any suggestions will be greatly appreciated. Thanks.
You can calculate the distance you want your view to travel, but if you don't want to be exact, you can just use the screen height:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int screenHeight = size.y;
And then just animate the view as needed, but add a listener to do what you want at the end:
textView.animate().translationY(screenHeight).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
textView.setVisibility(View.GONE);
}
});
You still need to make the view visibility GONE at the end in the listener, just to make sure you don't see it anymore.
You can also try and use getBottom() for the distance.
Sorry for the vague title. I really cannot present this question is few words. OK, let me describe what I want to achieve.
First, I have a vertical LinearLayout including two views. View A is visible and as big as possible(match parent). For View BI set it VIEW.GONE be default.
Then, triggered by something, View A will be scaled into half of its size. And View B will be shown by setting VIEW.VISIBLE. In order to make View A and View B have the same height, I assigned equal weight to them in xml. The following figures illustrate what I want to implement.
figure
To scale View A, I make use of View.ScaleX(0.5f) and View.ScaleY(0.5f). Actually I implement the scale function in the animation way and set View B visibility in EndAnimation Callback.
But View A and View B cannot be shown properly. Half of each view is masked by unknown 'white block'.
And I also check the height-width of View A, before and after scaling, it does not change at all.
So is it possible to implement such feature?
Thanks so much.
You want to add a scaleY animation on View A before displaying View B right? It is absolutely possible. I'm not sure what is the 'white-block' you're referring to. You should give some of your code if you want help debugging.
Otherwise, you should use an ObjectAnimator like this one :
ObjectAnimator animator = ObjectAnimator.ofFloat(viewA, "scaleY", 1f, 0.5f);
animator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
viewB.setVisibility(View.VISIBLE);
// You can display the view b with an animation
ObjectAnimator.ofFloat(viewB, "alpha", 0f, 1f).start();
// Remember to reset the scale factor since there will be a re-layout
viewA.setScaleY(1.0f);
}
});
animator.start();
I need this for a project pre API11.
Im looking for a way to add a view in from right, that will cause the current full screen view to move out to left as to allow the new view to be visibe in the screen.
the new view is about 1/3 of the screen width so thats the distance the current fusll screen view should move out of the screen.
i have tired various solutions with TranslateAnimation(), although im happy with the animation, i'm having issues with all the clickable areas in the original view not being where they are supposed to be.
so i started playing with the layout to position it correctly with negative margin, but after a couple of seconds when a new layout request comes the view is popped back into place. also this solution had a choppy effect when moving the view on the animation end listener.
what would be the most simple solution that has good animation when the new view is entering or exiting and that puts the view in the correct place in terms of layout.
Since you're using API11, use the Animator API. All views have properties now with corresponding setters and getters. To shift a view to the left out of scope, get the width of the screen then do:
View viewToShiftOut = getOutView();
ObjectAnimator outAnim = ObjectAnimator.ofFloat(viewToShiftOut, "x", 0, -widthOfScreen);
outAnim.setDuration(1000);
outAnim.start();
This will shift the view and it's contents entirely out of the screen for a duration of 1 second (1000 miliseconds). To shift one in it's place do this:
View viewToShiftIn = getInView();
ObjectAnimator inAnim = ObjectAnimator.ofFloat(viewToShiftIn, "x", widthOfScreen, 0);
inAnim.setDuration(1000);
inAnim.start();
All the properties, clickable areas, etc. will follow the view so you'll be done when the animations finish. You can animate them together like so:
View viewToShiftOut = getOutView();
View viewToShiftIn = getInView();
ObjectAnimator outAnim = ObjectAnimator.ofFloat(viewToShiftOut, "x", 0, -widthOfScreen);
ObjectAnimator inAnim = ObjectAnimator.ofFloat(viewToShiftOut, "x", widthOfScreen, 0);
outAnim.setDuration(1000);
inAnim.setDuration(1000);
outAnim.start();
inAnim.start();
Blog post
EDIT: I noticed you wanted to only shift the view by a 1/3rd, so you can get the amount of pixels to shift each by widthOfScreen/3.
EDIT 2: Another advantage is you can use it with hardware acceleration without trouble which most 3.0+ tablets have.
Instead of using fillAfter and fillEnabled, as you're probably doing, you will need to programmatically alter your layout in the onAnimationEnd of an AnimationListener to match your desired final positioning.
To remove the flicker, call clearAnimation() on the View you are animating, also in onAnimationEnd.