I want to implement a scale animation to View (or ImageView) when it gets focus. Here is my current implementation:
public class ScaleFocusImageView extends ImageView {
private Context mContext;
public ScaleFocusImageView(Context context, AttributeSet attr) {
super(context, attr);
mContext = context;
}
#Override
protected void onFocusChanged (boolean gainFocus, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
if(gainFocus) {
Animation a = AnimationUtils.loadAnimation(mContext, R.anim.scale_up);
this.startAnimation(a);
}
}
}
And here is my animation xml 'scale_up.xml':
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0"
android:toXScale="1.5"
android:fromYScale="1.0"
android:toYScale="1.5"
android:pivotX="50%p"
android:pivotY="50%p"
android:duration="175"/>
</set>
I can't get the scale effect when got focus in the end, I just see it scale quickly and shrink to original as normal. Why does this implementation not work how I expect, and how can I fix it?
Ok now try this updated code:--
this is the class for imageview:--
public class ScaleFocusImageView extends ImageView {
private Context mContext;
boolean flag;
public ScaleFocusImageView(Context context, AttributeSet attr) {
super(context, attr);
mContext = context;
}
#Override
protected void onFocusChanged(boolean gainFocus, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
if (gainFocus) {
zoom(1f, 1f, new PointF(getWidth() / 2, getHeight() / 2));
} else {
zoom(2f, 2f, new PointF(getWidth() / 2, getHeight() / 2));
}
}
/** zooming is done from here */
#SuppressLint("NewApi")
public void zoom(Float scaleX, Float scaleY, PointF pivot) {
setPivotX(pivot.x);
setPivotY(pivot.y);
setScaleX(scaleX);
setScaleY(scaleY);
}
}
Add this to your XML animation:
android:repeatMode="reverse"
By reversing the animation, the image won't be loaded shrinked but the animation will follow the reverse scale.
The xml animation file will be like this now:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0"
android:toXScale="1.5"
android:fromYScale="1.0"
android:toYScale="1.5"
android:pivotX="50%p"
android:pivotY="50%p"
android:duration="3000"
android:repeatMode="reverse"
android:repeatCount="infinite"/>
Related
I want to have a button feedback like Spotify form my Buttons. That means when I click the button the button should be a bit smaller and it should get a light gray ton. That's easy I know but I don't know how to make that with an animation.
Thats the Sample-Button:<Button id="SpotifyButton"/>
I'm looking forward to getting a answer! :)
The hole answer based on the answer from Android Geek.
view_press.xml (in anim res folder)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillAfter="true" android:fillBefore="true">
<scale
android:duration="100"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="70%"
android:pivotY="70%"
android:toXScale="0.95"
android:toYScale="0.95" >
</scale>
</set>
view_release.xml (in anim res folder)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator"
android:fillAfter="true" android:fillBefore="true">
<scale
android:duration="100"
android:fromXScale="0.95"
android:fromYScale="0.95"
android:pivotX="70%"
android:pivotY="70%"
android:toXScale="1"
android:toYScale="1">
</scale>
</set>
CustomView
public class SpotifyButton extends AppCompatTextView {
int backgroundColor = ((ColorDrawable) getBackground()).getColor();
GradientDrawable gradientDrawable = getBackgroundShape(backgroundColor);
ValueAnimator defaultAnimator = getDefaultBackgroundAnimator(this);
public SpotifyButton (Context context) {
super(context);
setOnTouchListener();
setBackground(gradientDrawable);
}
public SpotifyButton (Context context, AttributeSet attrs) {
super(context, attrs);
setOnTouchListener();
setBackground(gradientDrawable);
}
public SpotifyButton (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOnTouchListener();
setBackground(gradientDrawable);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
#Override
public boolean performClick() {
super.performClick();
return true;
}
public static int manipulateColor(int color, float factor) {
int a = Color.alpha(color);
int r = Math.round(Color.red(color) * factor);
int g = Math.round(Color.green(color) * factor);
int b = Math.round(Color.blue(color) * factor);
return Color.argb(a,
Math.min(r, 255),
Math.min(g, 255),
Math.min(b, 255));
}
public ValueAnimator getDefaultBackgroundAnimator(final View view) {
final float[] from = new float[3],
to = new float[3];
Color.colorToHSV(backgroundColor, from);
Color.colorToHSV(manipulateColor(backgroundColor, 0.7f), to);
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
anim.setDuration(200);
final float[] hsv = new float[3];
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
// Transition along each axis of HSV (hue, saturation, value)
hsv[0] = from[0] + (to[0] - from[0]) * animation.getAnimatedFraction();
hsv[1] = from[1] + (to[1] - from[1]) * animation.getAnimatedFraction();
hsv[2] = from[2] + (to[2] - from[2]) * animation.getAnimatedFraction();
gradientDrawable.setColor(Color.HSVToColor(hsv));
view.setBackground(gradientDrawable);
}
});
return anim;
}
public GradientDrawable getBackgroundShape(int color) {
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
gradientDrawable.setCornerRadius(100);
gradientDrawable.setColor(color);
return gradientDrawable;
}
public void setOnTouchListener() {
this.setOnTouchListener(new OnTouchListener() {
#SuppressLint("ClickableViewAccessibility")
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Animation onclick_effect_press = AnimationUtils.loadAnimation(getContext(), R.anim.ui_view_feedback_press);
defaultAnimator.start();
v.startAnimation(onclick_effect_press);
return true;
case MotionEvent.ACTION_UP:
Animation onclick_effect_release = AnimationUtils.loadAnimation(getContext(), R.anim.ui_view_feedback_release);
defaultAnimator.reverse();
v.startAnimation(onclick_effect_release);
if (isMotionEventInsideView(v, event)) {
performClick();
}
return true;
}
return false;
}
});
}
private boolean isMotionEventInsideView(View view, MotionEvent event) {
Rect viewRect = new Rect(
view.getLeft(),
view.getTop(),
view.getRight(),
view.getBottom()
);
return viewRect.contains(
view.getLeft() + (int) event.getX(),
view.getTop() + (int) event.getY()
);
}
}
Resault
Happy coding!!
XML file
<LinearLayout
android:id="#+id/ll_done"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/bg_rect"
android:paddingStart="60dp"
android:paddingEnd="60dp"
android:paddingTop="20dp"
android:paddingBottom="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Done"
android:textColor="#android:color/white"/>
</LinearLayout>
set background to your layout of button. here background is bg_rect
drawable -- bg_rect is
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/colorPrimaryDark">
<item android:id="#android:id/mask">
<shape
android:shape="rectangle">
<solid android:color="#android:color/holo_green_light"/>
<corners android:radius="30dp"/>
</shape>
</item>
<item android:id="#android:id/background">
<shape
android:shape="rectangle">
<solid android:color="#5DA19C"/>
<corners android:radius="30dp"/>
</shape>
</item>
</ripple>
change solid android:color according to your need.
Create anim directory in res file then add animation file in anim folder:
Animation file -- onclick_effect.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromXScale="0.9"
android:fromYScale="0.9"
android:pivotX="70%"
android:pivotY="70%"
android:toXScale="1"
android:toYScale="1" >
</scale>
</set>
Add click on button in java class:
llDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Animation onclick_effect = AnimationUtils.loadAnimation(this, R.anim.onclick_effect);
llDone.startAnimation(onclick_effect);
}
});
Change color,animation time according to your need.
I hope its work for you.
I want creat aniamtion rotation before it rotaion from 0 to -30 and after from -30 to 0 so I created two file animation
xoay.xml
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="-30"
android:pivotX="50%"
android:duration="6000"
android:repeatCount="infinite"
android:fillAfter="true" />
xoay2.xml
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="-30"
android:toDegrees="0"
android:pivotX="50%"
android:duration="6000"
android:repeatCount="infinite"
android:fillAfter="true" />
and in activity I start animation with code
final RotateAnimation rotate= (RotateAnimation) AnimationUtils.loadAnimation(this,R.anim.xoay);
final RotateAnimation rotate2= (RotateAnimation) AnimationUtils.loadAnimation(this,R.anim.xoay_2);
and when I set
myView.startAnimation(rotate); or myView.startAnimation(rotate2);
it run. Now I want when myView finish animation xoay.xml it will run xoay2.xml and when xoay2.xml finish it run xoay.xml...
I tried with code :
AnimationSet s = new AnimationSet(false);
s.addAnimation(rotate);
s.addAnimation(rotate2);
myView.startAnimation(s)
but it not run.
How I can do it? Thank you very much !
You can achieve that with RotateAnimation
Animation an = new RotateAnimation(0.0f, 30.0f);
// Set the animation's parameters
an.setDuration(6000); // duration in ms
an.setRepeatCount(-1); // -1 = infinite repeated
an.setRepeatMode(Animation.REVERSE); // reverses each repeat
an.setFillAfter(true); // keep rotation after animation
// Aply animation to image view
myView.setAnimation(an);
I will create for you Just copy it and apply on your project
Step-1: Create Animation xml files
rotate_1.xml
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:duration="1200" />
rotate_2.xml
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="360"
android:toDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="0"
android:duration="1200" />
activity_main.xml
<TextView
android:id="#+id/tvDemo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:background="#color/colorAccent"
android:layout_gravity="center"
/>
MainActivity.java
TextView tvDemo;
boolean isFirstTime;
RotateAnimation rotate;
RotateAnimation rotate2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvDemo = (TextView) findViewById(R.id.tvDemo);
rotate = (RotateAnimation) AnimationUtils.loadAnimation(this, R.anim.rotate_up);
rotate2 = (RotateAnimation) AnimationUtils.loadAnimation(this, R.anim.rotate_down);
tvDemo.startAnimation(rotate);
rotate.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
tvDemo.startAnimation(rotate2);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
rotate2.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
tvDemo.startAnimation(rotate);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
isFirstTime = false;
tvDemo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
isFirstTime = true;
}
});
}
I Hope this code will work for you
Thank you
Better you user Animators instead
AccelerateInterpolator ACCELERATE_INTERPOLATOR = new AccelerateInterpolator();
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator rotationAnim = ObjectAnimator.ofFloat(((StoryHolder) holder).ivLike, "rotation", 0f, -30f);
rotationAnim.setRepeatCount(ValueAnimator.INFINITE);
rotationAnim.setDuration(300);
rotationAnim.setInterpolator(ACCELERATE_INTERPOLATOR);
ObjectAnimator rotationAnim2 = ObjectAnimator.ofFloat(((StoryHolder) holder).ivLike, "rotation", 0f, -30f);
rotationAnim2.setRepeatCount(ValueAnimator.INFINITE);
rotationAnim2.setDuration(300);
rotationAnim2.setInterpolator(ACCELERATE_INTERPOLATOR);
animatorSet.play(rotationAnim).before(rotationAnim2);
animatorSet.start();
//ROTATION
ObjectAnimator.ofFloat(yourView, View.ROTATION, 0f, 180f).setDuration(300).start();
//ROTATION Back
ObjectAnimator.ofFloat(yourView, View.ROTATION, 180f, 0F ).setDuration(300).start();
I used the following code to fade in only the Button Text. but it gives fadein for whole Button.
Animation animationFadeIn = AnimationUtils.loadAnimation(this, R.anim.fade_in);
//register btn listener
m_btn_register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
m_btn_register.startAnimation(animationFadeIn);
}
});
fade_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<alpha
android:fromAlpha="0.1"
android:toAlpha="1.0"
android:duration="2000"
/>
</set>
what is the correct way to acheive this?
Note : Having custom spans for button does not work on lollipop and above. So have this
<Button
android:textAllCaps="false"
My CustomSpan
public class CustomSpan extends CharacterStyle implements UpdateAppearance {
private int alpha;
public int getAlpha() {
return alpha;
}
public void setAlpha(int alpha) {
this.alpha = alpha;
}
public CustomSpan() {
}
#Override
public void updateDrawState(TextPaint paint) {
paint.setAlpha(alpha);
}
}
Custom Property
private static final Property<CustomSpan, Integer> FADE_INT_PROPERTY
= new Property<CustomSpan, Integer>(Integer.class, "FADE_INT_PROPERTY") {
#Override
public void set(CustomSpan span, Integer value) {
span.setAlpha(value);
}
#Override
public Integer get(CustomSpan object) {
return object.getAlpha();
}
};
Then
String text = button.getText().toString();
final CustomSpan span = new CustomSpan();
final SpannableString spannableString = new SpannableString(text);
int start = 0;
int end = text.length();
spannableString.setSpan(span, start, end, 0);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ObjectAnimator objectAnimator = ObjectAnimator.ofInt(
span, FADE_INT_PROPERTY, 0, 255);
objectAnimator.setEvaluator(new IntEvaluator());
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
button.setText(spannableString);
}
});
objectAnimator.setDuration(10000);
objectAnimator.start();
}
});
Gif
Change your code to this way
<?xml version="1.0" encoding="UTF-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale android:duration="#android:integer/config_shortAnimTime"
android:pivotX="50.0%"
android:pivotY="50.0%"
android:fromXScale="1.0"
android:toXScale="0.9"
android:fromYScale="1.0"
android:toYScale="0.9"/>
<alpha android:duration="#android:integer/config_shortAnimTime"
android:fromAlpha="1.0"
android:toAlpha="0.7"/>
</set>
and one more thing declare Animation gloabal.
I don't think there is a solution using animation API because it works on the view and doesn't take care of the content of it.
So, I think you should create container view for the button and add your button background for the new container.
then set the button background to be transparent.
After that make the animation for the button only.
I wanted to rotate an imageview on center point with a duration(ex: 5 sec).
is it possible ? how ?
like this picture :
public class RotateImageView extends ImageView {
private Animation mRotation;
public bool isAnimating = false;
public RotateImageView(Context context) {
super(context);
Init(null);
}
public RotateImageView(Context context, AttributeSet attrs) {
super(context, attrs);
Init(attrs);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public RotateImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
Init(attrs);
}
private void Init(AttributeSet attrs) {
startAnimation();
}
public void startAnimation() {
if (mRotation == null) {
mRotation = AnimationUtils.loadAnimation(getContext(), R.anim.rotate);
mRotation.setRepeatCount(Animation.INFINITE);
}
this.startAnimation(mRotation);
isAnimating = true;
}
public void stopAnimation() {
if (mRotation != null)
clearAnimation();
isAnimating = false;
}
#Override
public void setVisibility(int visibility) {
if (visibility == GONE || visibility == INVISIBLE) {
clearAnimation();
} else if (visibility == VISIBLE) {
startAnimation(mRotation);
}
super.setVisibility(visibility);
}
}
rotate.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:fromDegrees="0"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="0"
android:toDegrees="360" />
EDITED
RotateImageView image = new RotateImageView(Context);
image.addOnClickListener(new View.OnClickListener(){
if(image.isAnimating)
image.stopAnimating();
else
image.startAnimating();
}
Use this animation.xml:
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="5000" />
In android how to make a image grow from one point using animation?
I mean to say is...i have a button ..and i want is when i click on that button my image must grow(ascending order) to grow bigger and bigger from that point ...and when again i click on that button again it must collapse gowing smaller and smaller to end at that point
Can any anybody help me in doing this using android animation?
i'm new to android
This can be achieved using View Animation utility. This scales the image from 100% to 140% for 1 sec
Place the following file in res/anim/scale.xml
<?xml version="1.0" encoding="utf-8"?>
<set android:shareInterpolator="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="1.4"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="1000" />
</set>
Java code
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final View view = findViewById(R.id.imageView1);
final Animation anim = AnimationUtils.loadAnimation(this, R.anim.scale);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
view.startAnimation(anim);
}
});
}
I would suggest you look at this SO post:
Android: Expand/collapse animation
public class DropDownAnim extends Animation {
int targetHeight;
View view;
boolean down;
public DropDownAnim(View view, int targetHeight, boolean down) {
this.view = view;
this.targetHeight = targetHeight;
this.down = down;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newHeight;
if (down) {
newHeight = (int) (targetHeight * interpolatedTime);
} else {
newHeight = (int) (targetHeight * (1 - interpolatedTime));
}
view.getLayoutParams().height = newHeight;
view.requestLayout();
}
#Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
#Override
public boolean willChangeBounds() {
return true;
}
}
You would have to use that as an example as you want to apply it to your button.
Starting with Android 3.0, the preferred way of animating views is to
use the android.animation package APIs.These Animator-based classes change actual properties of the View object, ....
Or you can use a ViewPropertyAnimator for simple things - an image button that grows over a period of 1000ms to 1.4 x its size:
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imageButton.animate().
scaleX(1.4f).
scaleY(1.4f).
setDuration(1000).start();
}
});