Rotation animation is not spinning the asset in center point - android

I'm trying to rotate a round button when is pressed.My problem is the button doesn't rotate around it's own centre. Followed other examples but the outcome is the same. Here is my code:
rotate.xml:
?xml version="1.0" encoding="utf-8"?>
<rotate
android:duration="1500"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toDegrees="360" />
and in the class I'm using the animation:
Animation animRotate = AnimationUtils.loadAnimation(getContext(), R.animator.rotate);
#Override
public boolean onTouchEvent(MotionEvent event) {
Log.e(TAG, "event:::" + event.getAction());
if (event.getAction() == MotionEvent.ACTION_DOWN) {
view.startAnimation(animRotate);
view.setBackgroundResource(R.drawable.some_asset);
} else if (event.getAction() == MotionEvent.ACTION_UP ) {
view.clearAnimation();
view.setBackgroundResource(R.drawable.some_asset);
}
Thank you!

A simple way to rotate a View
Matrix matrix = new Matrix();
view.setScaleType(ScaleType.MATRIX); //required
matrix.postRotate((float) angle, pivX, pivY);
view.setImageMatrix(matrix);

Related

Applying shake animation while retaining the scale animation

I am applying a scale animation on RecyclerView. I am applying this animation on OnFocusChangeListener event. After this animation is applied, I also want to apply a shake animation to the same item while it retains the previous scale.
but in my case the item is scaled back to normal size before applying the shake animation.
Here is the problem I face.
scale animation zoom_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:fillEnabled="true"
android:interpolator="#android:anim/linear_interpolator"
android:zAdjustment="top">
<scale
android:duration="200"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.2"
android:toYScale="1.2" />
</set>
Shake animation shake.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="100"
android:fromXDelta="-5%"
android:repeatCount="3"
android:repeatMode="reverse"
android:toXDelta="5%" />
</set>
OnFocusChangeListener - This is where I scale the object
holder.channelCardView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus) {
Animation animZoomIn = AnimationUtils.loadAnimation(mContext, R.anim.zoom_in);
view.startAnimation(animZoomIn);
} else {
Animation animZoomOut = AnimationUtils.loadAnimation(mContext, R.anim.zoom_out);
view.startAnimation(animZoomOut);
}
}
});
OnKeyListener - This is where I apply shake animation.
holder.channelCardView.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT && getItemCount() == position + 1) {
if(getItemCount() == position + 1 && count[0] >= 2) {
Animation animShake = AnimationUtils.loadAnimation(mContext, R.anim.shake);
holder.channelCardView.startAnimation(animShake);
}
else {
count[0]++;
}
}
else {
count[0] = 0;
}
return false;
}
});
I want to apply the shake animation while the item is zoomed and I want to keep it zoomed until focus is changed.
Appreciate your help
After lot of reading I found the solution myself. by changing the shake.xml as below the problem is solved.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillEnabled="true"
android:fillAfter="true">
<scale
android:duration="200"
android:fromXScale="1.2"
android:fromYScale="1.2"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.2"
android:toYScale="1.2" />
<translate
android:duration="100"
android:fromXDelta="-3%"
android:repeatCount="3"
android:repeatMode="restart"
android:toXDelta="3%" />
</set>

Why image rotation animation only works correctly for the first time

I have this simple arrow image rotation animation which works as intended only for the first time. from second time onward It's still do the rotation but without slow animation.
Here's the code in anim xml files
Rotate 180
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1500"
android:fromDegrees="0"
android:toDegrees="180"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:fillAfter="true"
android:fillEnabled="true"/>
Rotate Revere
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1500"
android:fromDegrees="180"
android:toDegrees="0"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:fillAfter="true"
android:fillEnabled="true"
/>
The image view inside card view.
<ImageView
android:id="#+id/creadit_card_next_image"
android:layout_width="#dimen/next_image_size"
android:layout_height="#dimen/next_image_size"
android:layout_marginEnd="#dimen/static_menu_primary_margin"
android:layout_marginTop="16dp"
android:rotation="-90"
android:src="#drawable/ic_navigate_next"
android:tint="#color/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Java code to trigger Animation.
private Animation rotatePlus180;
private Animation rotateMinus180;
private boolean creditDebitCardViewExpanded = true;
rotatePlus180 = AnimationUtils.loadAnimation(this, R.anim.rotate_plus_180);
rotateMinus180 = AnimationUtils.loadAnimation(this, R.anim.rotate_minus_180);
private void onClickCreditDebitCardView() {
creditDebitCardPaymentMethod.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (creditDebitCardViewExpanded) {
expandAnimation(paymentRecyclerView);
creditDebitCardViewExpanded = false;
creditCardNextImage.setAnimation(rotatePlus180);
} else {
collapseAnimation(paymentRecyclerView);
creditDebitCardViewExpanded = true;
creditCardNextImage.setAnimation(rotateMinus180);
CreditDebitLayoutContainer.setPadding(0, 0, 0, padding);
}
}
});
}
Instead of setAnimation use startAnimation
creditCardNextImage.startAnimation(rotatePlus180);
creditCardNextImage.startAnimation(rotateMinus180);
setAnimation seems to be called once you attach the animation to the view/ or when the view is added.
StartAnimation will be called all the time even if the view has already been added.

How do I reverse a running animation?

When the Button is touched, it starts a zoom animation.
Animation zoomIn = AnimationUtils.loadAnimation(context, R.anim.zoomin);
view.startAnimation(zoomIn);
The zoomin.xml code:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillEnabled="true"
android:fillAfter="true">
<scale
android:fromXScale="1.0"
android:toXScale="1.3"
android:fromYScale="1.0"
android:toYScale="1.3"
android:pivotX="50%"
android:pivotY="50%"
android:duration="200"
android:interpolator="#android:anim/accelerate_interpolator"/>
</set>
But if the Button is released during this still running animation, it should reverse the animation from this point in time.
How can i achieve that?
You could use ViewPropertyAnimator to achieve something like this.
For example:
Button button = (Button) findViewById(R.id.yourButton);
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// adjust the scale and duration values according to your needs
if (event.getAction() == MotionEvent.ACTION_DOWN) {
v.animate().scaleX(2).scaleY(2).setDuration(2000);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
v.animate().scaleX(1).scaleY(1).setDuration(2000);
}
return false;
}
});

Zoomout animation on button press in android

When press a button,i need to animate that button....button will zoom out little on pressed and in orignal size on released..(very much like in tinder)
i use this :
<?xml version="1.0" encoding="utf-8"?>
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="0.9"
android:toYScale="0.9" >
</scale>
but it not work according to my need,,,i need that the button remain small till it is pressed. and become normal on released.
You can create a second animation for returning to unclicked state like this:
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fillAfter="true"
android:fromXScale="0.9"
android:fromYScale="0.9"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0" >
</scale>
and then :
yourButton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// start your first zoom out Animation here
break;
case MotionEvent.ACTION_UP:
// start zoom in animation which returns to original state
break;
}
return false;
}
});
Dont forget to set fillAfter in your Animations to true, otherwise it will snap back to the original state after the duration has ended.
Or in case you dont want a second animation you can call
yourButton.startAnimation(yourAnimation);
inside MotionEvent.ACTION_DOWN
and then call
yourButton.clearAnimation();
inside MotionEvent.ACTION_UP

how to manage OnClickListener on animated image?

I have an animated image of a bee.
I set an onClick Listener to the imageView, and it's working, but only in native position of the imageView, but not when its animating.
i also tried to use onTouchListener, but the result is the same.
How can i make onClick or onTouchListener work while the ImageView is animating?
animation:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:shareInterpolator="true">
<scale
android:repeatCount="infinite"
android:repeatMode="reverse"
android:duration="8000"
android:fromXScale="0.2"
android:toXScale="1.5"
android:fromYScale="0.2"
android:toYScale="1.5"
android:pivotY="0%"
android:pivotX="50%"/>
<translate
android:interpolator="#android:anim/bounce_interpolator"
android:fillBefore="true"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:duration="2000"
android:toXDelta="35"
android:toYDelta="85"/>
<rotate
android:pivotX="50%"
android:pivotY="0%"
android:fromDegrees="360"
android:toDegrees="0"
android:duration="6000"
android:repeatMode="reverse"
android:repeatCount="infinite"/>
onClick:
public static void onBTNClick_RidBee(Activity activity){
bee_icon = (ImageView)activity.findViewById(R.id.bee_icon);
bee_icon.clearAnimation();
}
}
onTouchListener:
bee_icon.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("myLogs", "clear anim bee");
bee_icon.clearAnimation();
}
return true;
}
});
Use android:fillAter="true". fillAfter controls whether the animation's ending value persists after it ends. By default, the state of the view after animation will be same as the state before the animation. for eg:suppose, before animation view's x position is 10, and you are translating x to 100, after animation the position will be still 10 not 100. But if you set fillAfter="true", after animation x will be 100

Categories

Resources