1. A brief introduction
Android has three kinds of animation, which are view animation, property animation and frame animation.
Among them, the frame animation has been abandoned because of insufficient resources, poor performance, memory overflow and so on.
Attribute animation is the most commonly used animation scheme on Android, with the following advantages:
- Animation effects include but are not limited to translation, rotation, scaling, transparency;
- Objects include but are not limited to View;
- Under the same conditions, property animation performance & resource consumption is better than view animation.
- Highly customizable
Principle 2.
The ValueAnimator class animates objects in real time by controlling changes in values
The ObjectAnimator class animates the object directly by changing its property values
3. Use ValueAnimator
ValueAnimator has three animator constructor methods :(int values), ofFloat (float values), ofObject (int values)
The difference between the three methods can be understood as the use of different estimators, the principle is the process of value change.
Property animation is recommended to obtain animation objects in Java dynamic code, which is convenient and flexible to set values.
3.1 ofFloat
Use floating-point evaluator, FloatEvaluator, to change the initial value to the end value as a float
public static Animator startValueAnim(float. changeArr ,){
// ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); // Smooth transition from 0 to 1
ValueAnimator anim = ValueAnimator.ofFloat(changeArr);// passing several is a continuous transition to each value until the last value, such as 0,1,0.8, 1
anim.setDuration(300);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {}});return anim;
}
Copy the code
3.2 ofInt
In the same way ofFloat is used, ofInt uses an integer valuator to change an initial value from an int value to an end value
public static Animator startValueAnim(int. changeArr ,){
// ValueAnimator anim = ValueAnimator.ofFloat(0, 100); // Smooth transition from 0 to 100
ValueAnimator anim = ValueAnimator.ofInt(changeArr);// passing several is a continuous transition to each value until the last value, such as 0,100,20,100
anim.setDuration(300);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {}});return anim;
}
Copy the code
3.3 ofObject
TypeEvaluator class ofObject is a core member of ValueAnimator. The ofObject class implements TypeEvaluator.
public class FloatOutEvaluator implements TypeEvaluator {
/ * * * *@paramFraction Indicates the progress value *@paramStartValue startValue *@paramEndValue endValue *@return* /
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
float startFloat = ((Number) startValue).floatValue();
float cf = fraction;
if (fraction<0.3 f){
cf = fraction*2;// Top 30% progress - Double progress
}else if (fraction <0.6 f){
cf = 0.6 f;// Pause for a moment
}
returnstartFloat + cf* (((Number) endValue).floatValue() - startFloat); }}Copy the code
use
ValueAnimator animator = ValueAnimator.ofObject(new FloatOutEvaluator() , 0f.1f);
animator.setDuration(3000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// Use change values, assign values, refresh, animateview.setAlpha((Float) valueAnimator.getAnimatedValue()); }});Copy the code
4. ObjectAnimator
ObjectAnimator is one of the most used animations in Android development. You can create several animations and combinations of animations directly
4.1 Java code mode
Animation: Transparent gradient twice
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha".1f.0f.1f.0f);
animator.setDuration(3000);
animator.start();
Copy the code
In the same way:
- Rotate the rotation
- TranslationX, translationY
- Scale scaleX, scaleY
- Transparent change alpha
XML 4.2 way
The directory of the property animation XML resource file is res/animator, not the same as the resource directory res/anim for view animation
For example,
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="1.0"
android:valueType="floatType"
android:propertyName="alpha"/>
Copy the code
Loading use animation
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_alpha);
animator.setTarget(view);
animator.start();
Copy the code
Same with other animations rotateion, scale, translate..
4.3 ObjectAnimator extension & Custom TypeEvaluator
Expand the “color” animation
1. Define a View that contains the setColor() method
class ColorTextView extends TextView {
public void setColor(String color){
setTextColor(Color.parseColor(color));
}
public ColorTextView(Context context) {
super(context);
}
public ColorTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs); }}Copy the code
2. Layout use
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.cupster.animation.ColorTextView
android:id="@+id/anim_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test color animation text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code
3. Write ColorEvaluator to control the rule that the color changes with the progress value
package com.cupster.animation;
import android.animation.TypeEvaluator;
Evaluator: public void setColor; invalidate() */ Evaluator: public void setColor
public class ColorEvaluator implements TypeEvaluator {
private int mCurrentRed = -1;
private int mCurrentGreen = -1;
private int mCurrentBlue = -1;
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
String startColor = (String) startValue;
String endColor = (String) endValue;
int startRed = Integer.parseInt(startColor.substring(1.3), 16);
int startGreen = Integer.parseInt(startColor.substring(3.5), 16);
int startBlue = Integer.parseInt(startColor.substring(5.7), 16);
int endRed = Integer.parseInt(endColor.substring(1.3), 16);
int endGreen = Integer.parseInt(endColor.substring(3.5), 16);
int endBlue = Integer.parseInt(endColor.substring(5.7), 16);
// Initialize the value of the color
if (mCurrentRed == -1) {
mCurrentRed = startRed;
}
if (mCurrentGreen == -1) {
mCurrentGreen = startGreen;
}
if (mCurrentBlue == -1) {
mCurrentBlue = startBlue;
}
// Calculate the difference between the start and end colors
int redDiff = Math.abs(startRed - endRed);
int greenDiff = Math.abs(startGreen - endGreen);
int blueDiff = Math.abs(startBlue - endBlue);
int colorDiff = redDiff + greenDiff + blueDiff;
if(mCurrentRed ! = endRed) { mCurrentRed = getCurrentColor(startRed, endRed, colorDiff,0,
fraction);
} else if(mCurrentGreen ! = endGreen) { mCurrentGreen = getCurrentColor(startGreen, endGreen, colorDiff, redDiff, fraction); }else if(mCurrentBlue ! = endBlue) { mCurrentBlue = getCurrentColor(startBlue, endBlue, colorDiff, redDiff + greenDiff, fraction); }// Return the calculated values of the current color
String currentColor = "#" + getHexString(mCurrentRed)
+ getHexString(mCurrentGreen) + getHexString(mCurrentBlue);
return currentColor;
}
/** * Calculates the current color based on the fraction value. * /
private int getCurrentColor(int startColor, int endColor, int colorDiff,
int offset, float fraction) {
int currentColor;
if (startColor > endColor) {
currentColor = (int) (startColor - (fraction * colorDiff - offset));
if(currentColor < endColor) { currentColor = endColor; }}else {
currentColor = (int) (startColor + (fraction * colorDiff - offset));
if(currentColor > endColor) { currentColor = endColor; }}return currentColor;
}
/** * converts a decimal color value to a hexadecimal value. * /
private String getHexString(int value) {
String hexString = Integer.toHexString(value);
if (hexString.length() == 1) {
hexString = "0" + hexString;
}
returnhexString; }}Copy the code
4. Encapsulate common methods
public static void propColorAnimator(ColorTextView target , String startColor , String endColor){
ObjectAnimator animator = ObjectAnimator.ofObject(target ,"color".new ColorEvaluator() ,startColor,endColor);
animator.setDuration(3000);
animator.start();
}
Copy the code
5. Use
tv = findViewById(R.id.anim_view);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PropAnimatorHelper.propColorAnimator((ColorTextView) view,"#a7dbf7" ,"#ff8696"); }});Copy the code