kotlin的自定义动画
程序员文章站
2022-03-09 17:22:14
AnroidStudio中使用kotlin语言的自定义动画第一个练习,后面还会更新第二练习1.动画效果:开始点击start后,小球开始进入大球的嘴里,点击stop后,停止动画(还不知道哪个软件录制gif好,下去再搜, 现在只能口述了)2.主题思路分析:/*拆分为多个部分寻找关系每个部分的绘制寻找动画因子创建动画*/详细:拆分为多个部分: 嘴巴和小球寻找关系:大小 间距 位置,可以根据自己的要求设置每个部分的绘制:onDraw方法画笔paint 画布 canva...
AnroidStudio中使用kotlin语言的自定义动画
第一个练习,后面还会更新第二练习
1.动画效果:
开始
点击start后,小球开始进入大球的嘴里,
点击stop后,停止动画
(还不知道哪个软件录制gif好,下去再搜, 现在只能口述了)
2.主题思路分析:
/*
拆分为多个部分
寻找关系
每个部分的绘制
寻找动画因子
创建动画
*/
详细:
拆分为多个部分: 嘴巴和小球
寻找关系:大小 间距 位置,可以根据自己的要求设置
每个部分的绘制:
onDraw方法
画笔paint 画布 canvas 使用canvas.draw
寻找动画因子:
观察这个动画中什么在变
嘴的动画因子是开始的度数和最后度数的变化
小球的动画因子是圆心的x坐标
创建动画:
使用的是,ValueAnimator.ofFloat ,得到变化的一系列值
设置动画属性: duration repeat
监听值的变化,得到回调,同时使用invalidate,调用onDraw
动画调用的效果, 以及动画的播放、暂停、取消
3.代码:
3.1 先画出图形
自己定义的kotln的class代码
class MouseAnim: View {
// 定义画笔, 只有在需要使用的时候才定义,使用懒加载
// 懒加载使用的是val 不可变变量定义:val 关键字,只能赋值一次的变量(类似Java中final修饰的变量)
private val mPaint: Paint by lazy {
Paint().apply {
color = Color.BLUE
style = Paint.Style.FILL
}
}
// 定义小球的半径
private var bollRadius = 0f
// 定义嘴巴的半径
private var mouseRadius = 0f
// 两者之间的距离
private var span = 0f
// 嘴巴的x坐标
private var cx = 0f
// 嘴巴的y坐标
private var cy = 0f
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
if (width >= height){
bollRadius = height/6f
if (bollRadius*8.5f > width){
bollRadius = width/8.5f
}
}else{
bollRadius = width/8.5f
}
mouseRadius = bollRadius*3f
span = 0.5f*bollRadius
cx = (width-bollRadius*8.5f)+mouseRadius
cy = height/2f
}
// 两种构造方法
// 代码
constructor(context: Context) :super(context){}
// xml
constructor(context: Context, attributeSet: AttributeSet): super(context, attributeSet){}
override fun onDraw(canvas: Canvas?) {
canvas?.drawArc(cx-mouseRadius, cy-mouseRadius, cx+mouseRadius, cy+mouseRadius, 45f, 270f, true,mPaint)
canvas?.drawCircle(cx+4.5f*bollRadius, height/2f, bollRadius, mPaint)
}
}
对应的xml
<?xml version="1.0" encoding="utf-8"?>
<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.android.mymouselodinganimationauto1.MouseAnim
android:id="@+id/mouseView"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
运行结果:
3.2在上述代码中添加动画
kotlin代码
class MouseAnim: View {
// 定义画笔, 只有在需要使用的时候才定义,使用懒加载
// 懒加载使用的是val 不可变变量定义:val 关键字,只能赋值一次的变量(类似Java中final修饰的变量)
private val mPaint: Paint by lazy {
Paint().apply {
color = Color.BLUE
style = Paint.Style.FILL
}
}
// 定义小球的半径
private var bollRadius = 0f
// 定义嘴巴的半径
private var mouseRadius = 0f
// 两者之间的距离
private var span = 0f
// 嘴巴的x坐标
private var cx = 0f
// 嘴巴的y坐标
private var cy = 0f
// 嘴巴的动画
private var mouseMoveView: ValueAnimator? = null
// 小球的动画
private var bollMoveView: ValueAnimator? = null
// 两个动画需要同时动, 因此需要一个集合
private var allAnim = AnimatorSet()
// 找出动画因子
// 嘴的动画因子
private var mouseAngle = 0f
// 小球的动画因子
private var bollTransX = 0f
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
if (width >= height){
bollRadius = height/6f
if (bollRadius*8.5f > width){
bollRadius = width/8.5f
}
}else{
bollRadius = width/8.5f
}
mouseRadius = bollRadius*3f
span = 0.5f*bollRadius
cx = (width-bollRadius*8.5f)/2f+mouseRadius
cy = height/2f
}
// 两种构造方法
// 代码
constructor(context: Context) :super(context){}
// xml
constructor(context: Context, attributeSet: AttributeSet): super(context, attributeSet){}
override fun onDraw(canvas: Canvas?) {
canvas?.drawArc(cx-mouseRadius, cy-mouseRadius, cx+mouseRadius, cy+mouseRadius, mouseAngle, 360f-2f*mouseAngle, true,mPaint)
canvas?.drawCircle(cx+4.5f*bollRadius-bollTransX, height/2f, bollRadius, mPaint)
}
private fun createView(){
if (mouseMoveView == null) {
mouseMoveView = ValueAnimator.ofFloat(0f, 45f, 0f).apply {
duration = 680
repeatCount = ValueAnimator.INFINITE
addUpdateListener {
mouseAngle = it.animatedValue as Float
invalidate()
}
}
}
if (bollMoveView == null) {
bollMoveView = ValueAnimator.ofFloat(0f, 4.5f * bollRadius, 0f).apply {
duration = 680
repeatCount = ValueAnimator.INFINITE
addUpdateListener {
bollTransX = it.animatedValue as Float
invalidate()
}
}
}
allAnim.apply {
playTogether(mouseMoveView, bollMoveView)
}
}
fun startAnim(){
createView()
if (allAnim.isPaused){
allAnim.resume()
}else{
allAnim.start()
}
}
fun stopAnim(){
allAnim.pause()
}
}
对应的xml代码,添加了两个button
<?xml version="1.0" encoding="utf-8"?>
<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"
android:background="@color/colorAccent"
tools:context=".MainActivity">
<com.android.mymouselodinganimationauto1.MouseAnim
android:id="@+id/mouseView"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/mStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/mStart"
app:layout_constraintTop_toTopOf="@+id/mStart" />
<Button
android:id="@+id/mStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:text="start"
app:layout_constraintEnd_toStartOf="@+id/mStop"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/mouseView" />
</androidx.constraintlayout.widget.ConstraintLayout>
在MainActivity里面的代码,按钮监听事件
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// view是指自己创建的类的id值
mStart.setOnClickListener {
mouseView.startAnim()
}
mStop.setOnClickListener {
mouseView.stopAnim()
}
}
}
4.最后的运行
5.整体的结构目录
本文地址:https://blog.csdn.net/weixin_44614751/article/details/108701795