I want to rotate a View to 90 degree and update its content and again rotate it to 90 degree, and so far I tried below code.
ObjectAnimator anim1 = (ObjectAnimator) AnimatorInflater.loadAnimator(getActivity().getApplicationContext(), R.animator.flip_animator);
anim1.setTarget(v);
anim1.setDuration(1000);
anim1.start();
ImageView box = (ImageView) v.findViewById(R.id.box);
Bitmap bg = BoxUtils.getBoxBg(boxSize, boxMargin, Color.RED);
box.setImageBitmap(bg);
anim1.setTarget(v);
anim1.setDuration(1000);
anim1.start();
xml:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0" android:valueTo="90" android:propertyName="rotationY" >
</objectAnimator>
However its working but its changing its color before it rotates next 90 degree, even i had written updation code before than next rotation code.
Any help ?
The problem is that your object rotates asynchronously from your code. You have designed it so that the code sits there while the cube does the first rotation, then changes the color. What happens is that the code starts the animation, then keeps running as the cube rotates, which is why it changes color early.
The following method of animating your view will add an end action, which will be changing color then rotating the last 90:
View v;
v.animate()
.rotationY(90)
.setDuration(1000)
.withEndAction(new Runnable() {
#Override
public void run() {
ImageView box = (ImageView) v.findViewById(R.id.box);
Bitmap bg = BoxUtils.getBoxBg(boxSize, boxMargin, Color.RED);
box.setImageBitmap(bg);
v.animate().rotationY(90).setDuration(1000).start();
}
}).start();
Related
I want to make an animation for ImageView which runs from left to right on screen and when it reached to 50% of screen, it comes back. My XML:
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="x"
android:repeatMode="reverse"
android:repeatCount="1"
android:valueFrom="0"
android:valueTo="250" >
</objectAnimator>
My application ran well on my phone but when it ran on a smaller or bigger phone, it didn't run well.
I want to use ObjectAnimator and my application min SDK API is 13. Who can help me? Thanks in advance.
For better structure, a dynamic approach is recommended which uses display screen width
First calculate the screen width to measure the half of the screen
Display display = getWindowManager().getDefaultDisplay();
Point point=new Point();
display.getSize(point);
final int width = point.x; // screen width
final float halfW = width/2.0f; // half the width or to any value required,global to class
ObjectAnimator lftToRgt,rgtToLft; // global to class
// initialize the view in onCreate
imageView = (ImageView) findViewById(R.id.imageButtontest);
// set the click listener
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
anim();// call to animate
}
});
Add the below function to your class and enjoy.
void anim(){
// translationX to move object along x axis
// next values are position value
lftToRgt = ObjectAnimator.ofFloat( imageView,"translationX",0f,halfW )
.setDuration(700); // to animate left to right
rgtToLft = ObjectAnimator.ofFloat( imageView,"translationX",halfW,0f )
.setDuration(700); // to animate right to left
AnimatorSet s = new AnimatorSet();//required to set the sequence
s.play( lftToRgt ).before( rgtToLft ); // manage sequence
s.start(); // play the animation
}
Check out the complete Code Snippet
I have sliding up panel and in the titlebar of that panel I have ImageView as in the picture. How to rotate to 180* by clockwise that ImageView when user slide panel up and anti-clockwise when slide down.
For sliding that panel I have method:
#Override
public void onPanelSlide(View panel, float slideOffset) {
Log.i(TAG, "onPanelSlide, offset " + slideOffset);
//Animation here
}
Thanks for any help!
If you want to rotate a view without animation:
view.setRotation(float) sets the degrees that the view is
rotated around the pivot point. Increasing values result in clockwise
rotation.
view.setRotationX(float) sets the degrees that the view is
rotated around the horizontal axis through the pivot point.
Increasing values result in clockwise rotation from the viewpoint of
looking down the x axis. When rotating large views, it is recommended to adjust the camera distance accordingly.
view.setRotationY(float) sets the degrees that the view is
rotated around the vertical axis through the pivot point. Increasing
values result in counter-clockwise rotation from the viewpoint of
looking down the y axis. When rotating large views, it is recommended to adjust the camera distance accordingly.
If you want to use animation:
https://github.com/daimajia/AndroidViewAnimations (recommended)
https://github.com/castorflex/FlipImageView
https://github.com/florent37/ViewAnimator
https://github.com/alexvasilkov/GestureViews
https://gist.github.com/simon-heinen/9795036
https://gist.github.com/methodin/5678214
https://www.google.com/ :D
I didn't want to mark this as an answer but I can't leave comments yet, I was able to get Apurva's solution working correctly but I had to use this instead of getApplicationContext(), I had to use this because of where I was setting the animation from, the code in my application where I am attaching the animation looks like this...
ImageView billysArm = (ImageView) findViewById(R.id.imageView6);
Animation rotate = AnimationUtils.loadAnimation(this, R.anim.rotate);
billysArm.startAnimation(rotate);
hope this helps
You should try this out, setting an animation for your e.g. ImageView
#Override
public void onPanelSlide(View panel, float slideOffset) {
Log.i(TAG, "onPanelSlide, offset " + slideOffset);
// Locate view
ImageView iv= (ImageView) findViewById(R.id.iv);
// Create an animation instance
Animation an = new RotateAnimation(0.0f, 180.0f, pivotX, pivotY);
// Set the animation's parameters
an.setDuration(10000); // duration in ms
an.setRepeatCount(0); // -1 = infinite repeated
an.setRepeatMode(Animation.REVERSE); // reverses each repeat
an.setFillAfter(true); // keep rotation after animation
// Aply animation to image view
iv.setAnimation(an);
}
I'm having a recyclerView with several views and one is the animation view which has an animation applied to it. Once the view is out of the screen the animation is no longer active, even though the animation still exists.
The data:
rotate_around_center_point.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<rotate
android:duration="2500"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toDegrees="360" />
</set>
Applying animation:
animation = AnimationUtils.loadAnimation(this.getContext(),
R.anim.rotate_around_center_point);
loadingRotatingCircleIV.startAnimation(animation);
I could not find any way to catch an event when the animation is interrupted so I'm able to restart the animation once it was out of the screen.
RecyclerView is incorrectly stopping animation on the view when view goes out from screen only if you apply View Animation to that view. If you will use Property Animation everything works properly. So the following solution will work:
ObjectAnimator animator = ObjectAnimator.ofFloat(loadingRotatingCircleIV, "rotation", 0.0f, 360.0f);
animator.setDuration(1000L);
animator.setRepeatCount(ObjectAnimator.INFINITE);
animator.setInterpolator(new LinearInterpolator());
animator.start();
If you want to use a ViewAnimation for a RecyclerView item, you have to restore animation in overriden method of RecyclerView - onViewAttachedToWindow(ItemViewHolder holder), like:
#Override
public void onViewAttachedToWindow(ItemViewHolder holder) {
super.onViewAttachedToWindow(holder);
if (holder.animated)
{
Animation anim = new ScaleAnimation(0.8f, 1.2f,
0.8f, 1.2f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
anim.setFillAfter(true);
anim.setInterpolator(new BounceInterpolator());
anim.setDuration(1100);
anim.setRepeatCount(Animation.INFINITE);
anim.setRepeatMode(Animation.REVERSE);
holder.animatedView.startAnimation(anim);
}
}
I'm doing the exact same thing right now, and having the exact same problem. So the question is how to restart the animation once the view is back on screen.
I got the problem 99% resolved just by calling "loadingRotatingCircleIV.startAnimation(animation);" inside onBindViewHolder every time it gets called for my animated view's position.
But there's just a tiny little problem left. If you scroll down by just a little, so the view gets off screen, but it's view holder doesn't get recycled, when you scroll back up, onBindViewHolder is obviously not called again, but the animation is stopped.. So I'm still trying to fix that one..
So, my current solution:
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
...
if (position=="animated_view_position") view.startAnimation(animation);
...
}
If somebody has a better solution, please help.
create **HashMap<Integer, Boolean>** for saving each items animation loaded status
construct (){
for(int c = 0; c < adapterDataList.size(); c++){
//Here is create default status of animation loaded status used Boolean to saving
}
}
//Call Start Animation with onViewAttachedToWindow
#Override
public void onViewAttachedToWindow(ItemViewHolder holder) {
super.onViewAttachedToWindow(holder);
// get HashMap of each items Animation status like this
if(!HashMap.get(position)){ //FALSE means animation not loaded yet
//Here should call start Animation method;
} else {
//Here call no animation method, like setImageDrawable etc...
}
//create an AnimationListener for each item, when an animation is End, Listener should call a method to change HashMap above which you just created, like this **HashMap.put(position, Boolean.valueOf(true))** //TRUE means animation loaded
}
//to get position value as Integer use holder.getLayoutPosition()
i want to rotate the image of imageView, i have scaled the image using matrix but having problem in rotation, i'm using the code...
int previousDegrees = 0;
int degrees = 90;
RotateAnimation animation = new RotateAnimation(previousDegrees,degrees,160,160);
ImageView imageView = (ImageView)findViewById(R.id.imageView);
animation.setDuration(1000);//Set the duration of the animation to 1 sec.
imageView.startAnimation(animation);
it rotates the image for a second and setback to original position.. is there any way that image could rotate onclick continuosly.. like on (0,90.180.270,360)degrees...
Any Help please!!!
Set these parameters like so:
animation.setFillEnabled(true);
animation.setFillAfter(true);
From Android Developers Reference:
If fillAfter is true, the transformation that this animation performed will persist when it is finished.
I want to rotate an imageview from 30 degrees on each click on a button.
On the first clic, i can set the animation properly but i can't succeed to update the imageview position after the animation. When i clicked again on the button, the animation start from the original position of the imageview and not from the final position after the first animation.
Here is my code :
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
turnImg = (ImageView) findViewById(R.id.imageViewturnImg );
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.imgTurn);
// Getting width & height of the given image.
int w = bmp.getWidth();
int h = bmp.getHeight();
turnImg .setImageBitmap(bmp);
Button buttonok = (Button) findViewById(R.id.buttonok);
buttonok.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
turn();
}
});
}
public void turn()
{
float degrees = 30;
RotateAnimation anim = new RotateAnimation(0, degrees,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
anim.setInterpolator(new LinearInterpolator());
anim.setDuration(300);
anim.setFillEnabled(true);
anim.setFillAfter(true);
anim.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationEnd(Animation arg0) {
Matrix mat = turnImg.getImageMatrix();
mat.postRotate(30,turnImg.getWidth()/2, turnImg.getHeight()/2);
turnImg.setScaleType(ScaleType.MATRIX);
turnImg.setImageMatrix(mat);
}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationStart(Animation animation) {}
});
turnImg.startAnimation(anim);
}
I think the problem came from the way i actualize the position in the onAnimationEnd().
ps : sorry for my bad english...
The problem is that your animation is not affecting the same object as your matrix rotation. That is, you are animating the rotation of the ImageView object, but then you are setting the rotation of the image that is within that ImageView object. So, for example, the first time you rotate it, the ImageView rotates from 0 to 30 degrees, and then remains at a rotation of 30 degrees due to the call to setFillAfter(true). Then the onAnimationEnd() handler runs, which rotates the internal image by 30 degrees. This effectively jumps the image to a rotation of 60 degrees, as seen by the user (30 for the View, 30 for the bitmap). Then the next time the animation runs, it rotates the view from 0 to 30 degrees, with the internal image still at its rotation of 30 degrees. This makes it look to the user like it's rotating from 30 to 60 degrees. Then you apply another rotation on the internal image when that animation finishes, ending up with the image rotated to 60 degrees and the view rotated (again) to 30 degrees, so the image is now visually rotated to 90 degrees.
And so on.
There are different ways to handle this problem, but one simple way is to avoid affecting the two different objects - just work with the ImageView. Instead of rotating from 0 to 30 each time, rotate from whatever the current rotation is to that value plus 30 degrees. You can remove the onAnimationEnd() handler, because you will no longer need to rotate the image inside the view.
The resulting code for turn() is much simpler:
public void turn()
{
RotateAnimation anim = new RotateAnimation(currentRotation, currentRotation + 30,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
currentRotation = (currentRotation + 30) % 360;
anim.setInterpolator(new LinearInterpolator());
anim.setDuration(1000);
anim.setFillEnabled(true);
anim.setFillAfter(true);
turnImg.startAnimation(anim);
}
This code assumes an instance variable of currentRotation, which is used to track the last degrees the view was rotated to.
Its a bit more involved if you allow the user to click mid-animation, but not too difficult.
By the way, this is much simpler in the animation system in 3.0; there is now a 'rotation' property on View, and you can run an animation on that property and it can track its own current value. But the approach above should work for older releases.