步骤 1: 创建心形Drawable资源
首先,我们需要创建一个心形的Drawable
资源。这可以通过在res/drawable
目录下创建一个XML
文件来完成。
<!-- res/drawable/heart_shape.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="100dp"
android:height="100dp"
android:viewportWidth="100"
android:viewportHeight="100">
<path
android:fillColor="#FF0000"
android:pathData="M50,10 C30,70 20,80 50,90 C80,80 70,70 50,10 Z" />
</vector>
步骤 2: 创建自定义View
接下来,我们需要创建一个自定义View
来绘制心形,并实现动态效果。
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
class HeartTree @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val paint = Paint().apply {
color = ContextCompat.getColor(context, R.color.heart_color)
isAntiAlias = true
}
private val heartDrawable: VectorDrawableCompat
private var heartSize = 50f
private var heartX = 0f
private var heartY = 0f
private var heartAlpha = 255
init {
heartDrawable = VectorDrawableCompat.create(resources, R.drawable.heart_shape, context.theme)!!
heartDrawable.setBounds(0, 0, heartSize.toInt(), heartSize.toInt())
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
heartDrawable.alpha = heartAlpha
heartDrawable.draw(canvas)
}
fun startAnimation() {
val xAnimator = ObjectAnimator.ofFloat(this, "heartX", 0f, width.toFloat())
val yAnimator = ObjectAnimator.ofFloat(this, "heartY", 0f, height.toFloat())
val alphaAnimator = ObjectAnimator.ofInt(this, "heartAlpha", 0, 255).apply {
addUpdateListener { animation ->
heartAlpha = animation.animatedValue as Int
invalidate()
}
}
val animatorSet = AnimatorSet().apply {
playTogether(xAnimator, yAnimator, alphaAnimator)
duration = 5000
repeatCount = ObjectAnimator.INFINITE
repeatMode = ObjectAnimator.REVERSE
}
animatorSet.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
// 动画结束后重新开始
animatorSet.start()
}
})
animatorSet.start()
}
fun setHeartX(value: Float) {
heartX = value
invalidate()
}
fun setHeartY(value: Float) {
heartY = value
invalidate()
}
fun setHeartAlpha(value: Int) {
heartAlpha = value
invalidate()
}
}
步骤 3: 创建布局
接下来,我们需要创建一个布局文件来放置自定义View
。
<!-- res/layout/activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="16dp">
<com.example.yourapp.HeartTree
android:id="@+id/heart_tree"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
步骤 4: 实现逻辑
在MainActivity
中,我们需要初始化自定义View
,并启动动画。
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.yourapp.HeartTree
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private lateinit var heartTree: HeartTree
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
heartTree = findViewById(R.id.heart_tree)
// 启动动画
heartTree.startAnimation()
}
}
说明
Drawable
资源: 我们创建了一个心形的Drawable
资源。- 自定义
View
: 在自定义View
中实现了心形的绘制和动画效果。 - 布局文件: 在布局文件中定义了一个自定义
View
。 - 启动动画: 在
MainActivity
中初始化自定义View
,并启动动画。
这个示例展示了如何在Android
中创建一个动态的心形树效果。你可以根据需要调整动画参数,例如改变动画的速度、方向或添加更多的心形元素。