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();
Related
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.
In my Android app, I have a TextView with a white background. When it is clicked, its background will change to a .png picture of some icon by calling setBackgroundResource(R.drawable.icon) on the TextView. This works as intended, but the change is rather abrupt. I would like to make the icon appear more gradually; when the TextView is clicked, a tiny version of the icon should appear in the center of the TextView and then immediately expand and fill out the entire TextView. I believe the best way to do this would be by using an animation, which of the available animation types in Android are best for this task?
In case it is not clear what I mean, I drew a sketch to illustrate. The second sequence shows how the code works right now, the first shows how I would like it to be.
So, I managed to get the effect you want with an ImageView, using ScaleAnimation. Here's what you have to do:
First, our XML ImageView:
<ImageView
android:id="#+id/scale_anim"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="#android:color/white" />
It has fixed dimensions and a white background.
The animation will start with one click with this, inside your onCreate() method:
ImageView starImageView = (ImageView) findViewById(R.id.scale_anim);
starImageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ScaleAnimation starScaleAnimation =
new ScaleAnimation(0.3f, 1f, 0.3f, 1f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
starScaleAnimation.setDuration(500);
((ImageView) v).setImageResource(R.drawable.star);
ScaleAnimation scaleAnim = starScaleAnimation;
v.startAnimation(scaleAnim);
}
});
We are applying a scale animation on the ImageView that stars with 30% of the original size and scales to 100% of its size, from its center point. The duration of this animation is half a second. All these parameters can be changed.
Every time you click the ImageView, your drawable will be applied and the animation will start.
Try this way if it solve yours.
Create an ImageView (X) above your original ImageView (A) - same size and same place as (A)
Animate (X) with ObjectAnimator, listen for the onAnimationEnd call and set the (A)'s background. Then remove (X).
Hope this will help.
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.
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.
Is there a way to force an android view to redraw it's background?
I have set a drawable shape with a gradient as background which works fine but after changing the view's height you can see those ugly gradient steps.
What can I do?
I tried view.invalidate() and view.refreshDrawableState() without any visible difference.
Thank you!
//EDIT:
Here are some more details and my code:
After your answers I think the banding is a result of my probably bad code. Here is what I'm doing:
Scaling a view
setting its new width and height because the scaled view does not accept user input in other areas then the "old" one (see android weird (at least for me) behaviour of control after scaling / doesn't accept input in it's whole area )
trying to set the background again (which contains a gradient and a rectangle with rounded corners)
Here is my code:
public void onAnimationEnd(Animation animation)
{
MyView view = (MyView) ((ExtendedScaleAnimation) animation).getView();
view.getLayoutParams().width = toWidth;
view.getLayoutParams().height = toHeight;
view.clearAnimation();
view.requestLayout();
view.refreshBackground(); // background will be changed
}
On the device you can see that the background drawable is changed but there is a flickering which seems to me like the backround change is applied before the animation is over. Programatically it should be over! Or am I wrong?
Thank you again!
Can you try after resize:
v.setBackgroundResource(null);
v.setBackgroundResource(...my drawable...);