1. Introduction
Before the introduction of property animation, Android already had a Tween Animation. The new Animator was introduced because of the limitations of tween animations. Classification of tween animation:
AlphaAnimation
ScaleAnimation
TranslateAnimation
RotateAnimation
AnimationSet
Limitations of tween animation:
- The number of objects you can animate is limited
- The display area and clickable area may differ
ValueAnimator and ObjectAnimator are introduced on Android3 to complement and address the above shortcomings of tween animation.
2. Property animation
2.1 Formation structure of attribute animation
The serial number | The name of the class | instructions |
---|---|---|
1 | Animator | The parent class of all Animators, used primarily to define generic interfaces |
2 | AnimatorSet | Multiple property animation combinations |
3 | ValueAnimator | Mainly used to generate animation based on starting and ending values, only responsible for generating values between starting and ending values |
4 | ObjectAnimator | It is mainly used to generate an animation based on the start and end values and to set the resulting values on the target object |
5 | TimeAnimator | Provides a simple callback mechanism, through TimeAnimator. TimeListener, notify you at each frame of animation. (Not covered in this article) |
Inheritance structure:
2.2 Define property animation methods
As with tween animations, you can create animations using Xml and Code.
Create an XML animation file in the Animation folder. (If there is no animation folder, create it manually.)
<objectAnimator
android:duration="int"
android:interpolator="@[package:]anim/interpolator_resource"
android:propertyName="string"
android:valueType=["intType"|"floatType"]
android:valueFrom="float | int | color"
android:valueTo="float | int | color"
android:startOffset="int"
android:repeatCount="int"
android:repeatMode=["repeat"|"reverse"/ >
Copy the code
attribute | meaning | Value range |
---|---|---|
duration | Animation execution time | Integer, needs to be greater than 0. |
interpolator | A differentiator that changes the rate at which the animation or value changes | Android comes with it, custom |
propertyName | Animate the property of the target object to change | String, fill in the property name |
valueType | Value types | Point type, floating point type. Can be omitted when the type of the property animation value is color value |
valueFrom | The starting value of the animation value | Floating-point, integer, or color values. When is a color value, it must conform to the way the color is defined (# + six hexadecimal numbers) |
valueTo | The end value of the animation value | Floating-point, integer, or color values. When is a color value, it must conform to the way the color is defined (# + six hexadecimal numbers) |
startOffset | The animation starts to offset time | An integer. The default value is 0. When negative, the effect is the same as the default value |
repeatCount | The number of times the animation repeats | An integer number. The default value is 0. When it is negative, it indicates an infinite loop |
repeatMode | How the next animation executes | Default: Restart playback. And pour on |
The sample
//1. Create an XML file in the animation folder<? xml version="1.0" encoding="utf-8"? > <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:propertyName="rotation"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="360"
android:startOffset="0"
android:repeatCount="infinite"
android:repeatMode="reverse"
/>
//2. Import the animation XML in your code
val objectAnimator = AnimatorInflater.loadAnimator(this, R.animator.object_animator) as ObjectAnimator
objectAnimator.setTarget(target)
objectAnimator.start()
Copy the code
How the code is created is described below.
3. ValueAnimator
ValueAnimator is, as its name suggests, a computational animation of numbers. Instead of interacting directly with the View, ValueAnimator#addUpdateListener sets the animation effect. For example, a ValueAnimator can be used to display values from 0 to 50 on a TextView.
3.1 Creating ValueAnimator
Create ValueAnimator in your code.
// Create the Animator, passing in a range of values
val animator = ValueAnimator.ofFloat(0F, 5000F)
// Set the differentiator, where the linear differentiator is selected
animator.interpolator = LinearInterpolator()
// Set the animation execution time
animator.setDuration(2000)
Copy the code
If you don’t set the interpolator, the default is used AccelerateDecelerateInterpolator (). If set to NULL, the LinearInterpolator() is used by default.
3.2 add UpdateListener
The onAnimationUpdate interface is called when there is a value change in ValueAnimator. So we need to implement this Listener.
animator.addUpdateListener {
// Update text in TextView
binding.textView.text = ((it.animatedValue as Float).toInt() / 100).toString()
// The value is passed into the custom Bessel View to animate it
binding.bezierView.setValue(it.animatedValue as Float)}Copy the code
Custom Bessel View source as follows. For Bessel curves, see another article of mine.
class BezierView : View {
private var path: Path = Path()
private lateinit var paint: Paint = Paint()
private var h: Int = 0
private var w: Int = 0
private var controlPoint1: PointF = PointF()
private var controlPoint2: PointF = PointF()
constructor(context: Context) : this(context, null)
constructor(context: Context, attributeSet: AttributeSet?) : super(context, attributeSet)
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
// Set the height and width of the current view
this.h = h
this.w = w
controlPoint1 = PointF(this.w.toFloat() / 4.0F)
controlPoint2 = PointF(this.w.toFloat() / 4 * 3.this.h.toFloat())
}
fun setValue(degree: Float) {
val controlY = degree / 5000 * h
controlPoint1 = PointF(this.w.toFloat() / 4, controlY)
controlPoint2 = PointF(this.w.toFloat() / 4 * 3.this.h.toFloat() - controlY)
invalidate()
}
override fun onDraw(canvas: Canvas?). {
super.onDraw(canvas)
// Reset path to prevent repeated Bezier curves from leaving multiple curves on the canvas
path.reset()
// Configure the brush paint
paint.color = context.getColor(R.color.colorAccent)
paint.strokeWidth = 2F
paint.style = Paint.Style.STROKE
// Set the left and right reference points
val pointLeft = PointF(0F, h / 2.toFloat())
val pointRight = PointF(w.toFloat(), h / 2.toFloat())
// Draw the left and right reference pointscanvas? .drawPoint(pointLeft.x, pointLeft.y, paint) canvas? .drawPoint(pointRight.x, pointRight.y, paint) paint.color = context.getColor(R.color.colorPrimaryDark)// To draw the Bezier curve, move to one of the reference points
path.moveTo(pointLeft.x, pointLeft.y)
// Draw bezier curves according to datum and control points
path.cubicTo(
controlPoint1.x,
controlPoint1.y,
controlPoint2.x,
controlPoint2.y,
pointRight.x,
pointRight.y
)
// Draw path on the canvascanvas? .drawPath(path, paint) } }Copy the code
3.3 Playing Animations
Finally, you need to start playing the animation at the appropriate node.
// Play the animation
animator.start()
// Animation is tentative
animator.pause()
// End of playback
animator.end()
Copy the code
4. ObjectAnimator
ObjectAnimator is created in the same way as ValueAnimator.
// Create animation,
val objectAnimator = ObjectAnimator.ofFloat(binding.imageView, "rotation".0F, 360F, 0F)
// Set the animation execution time
objectAnimator.setDuration(2000)
// Start playing
objectAnimator.start()
Copy the code
The first argument to create an animation is the View object being animated, the second is properyName, and the third is the starting value of the variable length argument.
There are the following types of propertyName:
The name of the | role |
---|---|
alpha | transparent |
rotation | rotating |
rotationX | It’s rotating around the X-axis |
rotationY | It’s rotating on the Y axis |
translationX | It’s shifted in the X-axis |
translationY | It’s shifted in the Y axis |
scaleX | It’s stretched in the X-axis |
scaleY | It’s stretched in the Y-axis |
5. Property animation Listener
There are three types of listeners for property animations.
AnimatorListener
AnimatorPauseListener
AnimatorUpdateListener
5.1 AnimatorListener
The AnimatorListener listener listens for the start, end, cancel, and repeat of the property animation.
public static interface AnimatorListener{
void onAnimationStart(Animator animation, boolean isReverse) {}
void onAnimationEnd(Animator animation, boolean isReverse) {}
void onAnimationCancel(Animator animation, boolean isReverse) {}
void onAnimationRepeat(Animator animation, boolean isReverse) {}}Copy the code
5.2 AnimatorPauseListener
The AnimatorPauseListener listener listens for the paused and resumed state of the property animation.
public static interface AnimatorPauseListener {
void onAnimationPause(Animator animation);
void onAnimationResume(Animator animation);
}
Copy the code
5.3 AnimatorUpdateListener
The AnimatorUpdateListener listener listens primarily for changes in the value of the property animation.
public static interface AnimatorUpdateListener {
void onAnimationUpdate(ValueAnimator animation);
}
Copy the code
Interpolator 6. Interpolator
6.1 Interpolator types
Interpolator for attribute animation is the same as Interpolator for tween animation. There are several types of interpolators:
The name of the | role |
---|---|
AccelerateDecelerateInterpolator | Speed up first, then slow down |
AccelerateInterpolator | Has been accelerated |
AnticipateInterpolator | Detour, speed up |
OvershootInterpolator | Accelerate over and return to the end |
AnticipateOvershootInterpolator | Detour, accelerate beyond, return to the end |
BounceInterpolator | Spring effect |
CycleInterpolator | Sine curve |
DecelerateInterpolator | Has been slow |
LinearInterpolator | Linear speed |
6.2 Custom interpolators
If the above interpolator does not meet the requirements, you can define a new interpolator. BaseInterpolator inherits when you define an interpolator. Rewrite public float getInterpolation(float Input).
The linear interpolator is the following code and can be used as a reference.
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
public LinearInterpolator(a) {}public LinearInterpolator(Context context, AttributeSet attrs) {}public float getInterpolation(float input) {
return input;
}
/ * *@hide* /
@Override
public long createNativeInterpolator(a) {
returnNativeInterpolatorFactoryHelper.createLinearInterpolator(); }}Copy the code
7. Custom TypeEvaluator
The estimator is used to calculate numerical changes in ValueAnimator. The default ValueAnimator is linear. Public T evaluate(float Fraction, T startValue, T endValue); .
The following is an example:
class CustomTypeEvaluator : TypeEvaluator<Float> {
override fun evaluate(fraction: Float, startValue: Float? , endValue:Float?).: Float {
returnfraction * abs(endValue ? :0F - startValue!!) }}Copy the code
8. Github
Examples of this article: github.com/HyejeanMOON…
Other tutorials: Using Google’s MergeAdapter: juejin.cn/post/684490… Paging in Android: juejin.cn/post/684490… Android UI testing Espresso: juejin.cn/post/684490… Android ConstraintLayout: juejin.cn/post/684490… In RecyclerView can cope with multiple ViewType libraries -Groupie: juejin.cn/post/684490…