步骤 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>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
步骤 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()
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
步骤 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>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
步骤 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()
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
说明
Drawable
资源: 我们创建了一个心形的Drawable
资源。- 自定义
View
: 在自定义View
中实现了心形的绘制和动画效果。 - 布局文件: 在布局文件中定义了一个自定义
View
。 - 启动动画: 在
MainActivity
中初始化自定义View
,并启动动画。
这个示例展示了如何在Android
中创建一个动态的心形树效果。你可以根据需要调整动画参数,例如改变动画的速度、方向或添加更多的心形元素。