Attribute animation realizes the effect of rotating entrance

Property animation and hardware acceleration

Daily gossip
June 7th

First of all, I feel that this part of the content is really boring, and there is nothing novel about it. However, for the sake of the integrity of the blog, I still want to sort out the relevant knowledge and content.

As always, let’s talk about my daily life. I may be quite busy recently, so I may not have so much time to blog. I can only use that fragmented time to piece it together bit by bit. Although the lack of time does not affect my pursuit of watching movies, after all, this is my biggest hobby, and it is also my biggest way to relieve stress, relax and have fun. I do not deny or reject this.

Today, "The Children I Recommend", which has been suspended for a week, is finally updated again. I feel very, very happy. To be honest, the amazing ending of the previous chapter really shocked me. The instant scene changes, the character's aura and expressions The changes in the scene, the female voice actor can see Hoshino Ai's underage sexual experience just through the incoordination of her body. In summary, look forward to tonight’s drama update~

Someone once commented on my blog that my blog had too much nonsense, and then another person replied to him and said that he quite liked my way of blogging. Then that person got angry and said, "You know how to be ironic." To be honest, I'm quite surprised. I didn't expect that there is such a thing in the programmer circle. Are you not full of work? It’s better to study more if you are here to idle!


June 8th

As the intensity of work increases and the complexity of what needs to be written increases, the length of daily conversations may be divided into several parts. Who would be a serious person to keep a diary? Yes, I am the unserious person.

Preface

In fact, I feel that this part of the content is quite boring, but I will try to use more interesting cases to tell it. I have been thinking for a long time about how to tell the relevant content in a more interesting way, instead of just reading the lesson plan. This point actually confused me for a long time, a very long time, a very long time, about 10 minutes, I kept thinking about it. Then I decided to do a cool operation and create a relatively challenging effect: variable speed rotation to enter the game.

text

In fact, there are many ways to achieve the same animation effect. The only difference is whether the specific implementation is simple or difficult, and whether the performance is high or low.

First, we define a view and display a picture in the middle of the view.

Define the image information we need to display in our XML layout and display it in the center:

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_view"
    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=".CiruyMainActivity">
    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/targetView"
        android:layout_margin="30dp"
        android:src="@drawable/avatar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</androidx.appcompat.widget.LinearLayoutCompat>

Let’s first take a look at how to achieve variable speed rotation. Here are two methods to achieve the corresponding effect:

1. Use the official animation API
because the animation effect we need to achieve is actually very simple. Simply calling the official API is enough to achieve our needs.

In Activity we get the view displayed in the XML file and animate it:

val targetView = findViewById<FlipView>(R.id.targetView)
        //旋转缩放入场
        targetView.animate()
            .rotation(360f)//原地旋转360度
            .scaleXBy(-0.5f)//缩小到原来的一半大小
            .scaleYBy(-0.5f)//缩小到原来的一半大小
            .setDuration(1000)//设置动画的时长
            .setStartDelay(1500)//设置动画开始的等待时间
            .start()	

Through the above code, we can achieve the rotation and synchronous scaling effect of the view.

2. Achieve corresponding effects through custom attribute animation

This method may be slightly more complicated than the previous method, but the advantage is that this method is more flexible. Of course, it also has disadvantages, which will be mentioned later.

This method is mainly divided into the following steps:

  1. Define a custom view, define a parameter in the custom view, and then draw our view based on this parameter.

The overloaded operator in kotlin is used here to make the code clearer during subsequent progress calculations. No way, I have obsessive-compulsive disorder and don't like making code too complicated.

class ObjectAnimatorView(context: Context, attributeSet: AttributeSet) :
    View(context, attributeSet) {
    
    
    private val mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    var mViewParam = ViewParam(0f, 1f)
    set(value) {
    
    
        field = value
        invalidate()//在接收到属性更新的时候,让视图在下次刷新页面的时候刷新状态
    }
    override fun onDraw(canvas: Canvas) {
    
    
        super.onDraw(canvas)
        //获取到图片文件,根据具体的scale值来动态决定到底获取多大的视图信息
        val bitmap = R.drawable.avatar.getBitmap(context, (width*mViewParam.scale).toInt())
        val bWidth = bitmap.width//图片宽度
        val bHeight = bitmap.height//图片高度
        canvas.save()
        //旋转图片
        canvas.translate(width/2f,height/2f)
        canvas.rotate(mViewParam.rotate)
        canvas.translate(-width/2f,-height/2f)
        canvas.drawBitmap(bitmap, width / 2f - bWidth / 2, height / 2f - bHeight / 2, mPaint)
        canvas.restore()
    }

}
//自定属性存储bean,重载操作符
data class ViewParam(val rotate: Float, val scale: Float){
    
    
    operator fun plus(other: ViewParam) = ViewParam(rotate+other.rotate,scale+other.scale)
    operator fun minus(other: ViewParam) = ViewParam(rotate-other.rotate,scale-other.scale)
    operator fun times(time:Float) = ViewParam(rotate*time,scale*time)
}
  1. Get this view in Activity, customize an ObjectAnimator, and start the animation.
val targetView: ObjectAnimatorView = findViewById<ObjectAnimatorView>(R.id.targetView)
        ObjectAnimator.ofObject(
            targetView,
            "mViewParam",
            typeEvaluator,
            ViewParam(360f, 0.5f)//原地旋转360度,同时缩小宽高到原来的一半
        ).apply {
    
     startDelay = 1000
        duration = 1000}
            .start()
//自定义每一个时刻的动画播放进度
 val typeEvaluator:TypeEvaluator<ViewParam> =
        TypeEvaluator<ViewParam> {
    
     fraction, startValue, endValue -> startValue + (endValue-startValue)*fraction }

Let’s also talk about hardware acceleration. What is hardware acceleration? There is actually a good thing called GPU in the device, which is better at processing simple animation transformation effects than CPU. And hand over this part of the so-called simple animation effect to the GPU for processing,

How to enable view hardware acceleration: Add the following method to the view initialization code,

    init {
    
    
        setLayerType(LAYER_TYPE_HARDWARE, null)
    }

In addition, you need to add an off-screen cache in the animation method, that is, the withLayer method:

//旋转缩放入场
targetView.animate()
    .rotation(360f)
    .scaleXBy(-0.5f)
    .scaleYBy(-0.5f)
    .setDuration(1000)
    .setStartDelay(1500)
    .withLayer()
    .start()

Note: Android hardware acceleration only has a performance improvement effect on the simple effects officially defined above. Please refer to the official documentation for specific optimization effects. For custom animation effects, it will affect performance.

Guess you like

Origin blog.csdn.net/qq_31433709/article/details/131116390