Анимация clipPath из onDraw

Я рисую пользовательскую фигуру в onDraw с помощью Paint и Canvas. В классе onDraw у меня есть прямоугольник clipPath.

Я хотел бы иметь возможность анимировать положение (анимировать слева направо) clipPath из MainActivity. Это скроет нарисованную фигуру (BlackGraph) слева направо.

class BlackGraph(context: Context) : View(context) {

    var clipAmount:Float = 0.0f

    override fun onDraw(canvas: Canvas) {
        val paint = Paint()
        paint.style = Paint.Style.FILL
        paint.color = Color.parseColor("#000000")
        val path = Path()

        val clipPath = Path()
        clipPath.addRect(clipAmount, 0f, width.toFloat(), height.toFloat(), Path.Direction.CW)
        canvas.clipPath(clipPath)

        path.moveTo(0f, height-30.toFloat())
        path.lineTo(width.toFloat(), 0f)
        path.lineTo(width.toFloat(), height.toFloat())
        path.lineTo(0f, height.toFloat())
        path.lineTo(0f, 0f)

        canvas.drawPath(path, paint)

    }
}

В onCreate:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val layout1 = findViewById<android.support.constraint.ConstraintLayout>(R.id.layout1)
    val blackGraph = BlackGraph(this)

    layout1.addView(blackGraph)

    val valueAnimator = ValueAnimator.ofFloat(0f, 450f)
    valueAnimator.addUpdateListener {
        val value = it.animatedValue as Float
        println("Value -> $value")
        blackGraph.clipAmount = value
    }
    valueAnimator.duration = 2000
    valueAnimator.start()

}

Я пытаюсь просто анимировать положение clipAmount для достижения желаемой анимации.

Проблема в onCreate, значение clipAmount никогда не анимировалось. Однако оператор печати работает нормально. Logcat полон значений с плавающей запятой в диапазоне от 0,0 до 450,0.

Как я могу анимировать движение clipPath?

1
0
492
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо, у вас есть некоторые проблемы здесь. Во-первых, вы не должны инициализировать Paint, Path в onDraw(), он должен быть инициализирован первым, и вы можете изменить его позже, и вы получите лучшую производительность. Когда вы обновляете значение clipAmount, вам нужно вызвать postInvalidateOnAnimation(), чтобы ваше представление BlackGraph снова отрисовывалось, это вызовет метод onDraw(). Последнее, что clipPath нужно вызвать reset() для очистки перед добавлением нового пути с помощью метода addRect().

class BlackGraph(context: Context) : View(context) {

    var clipAmount:Float = 0.0f
    val paint = Paint().apply {
        style = Paint.Style.FILL
        color = Color.parseColor("#000000")
    }
    val path = Path()
    val clipPath = Path()

    override fun onDraw(canvas: Canvas) {
        clipPath.apply {
            reset()
            addRect(clipAmount, 0f, width.toFloat(), height.toFloat(), Path.Direction.CW)
        }
        canvas.clipPath(clipPath)

        path.moveTo(0f, height-30.toFloat())
        path.lineTo(width.toFloat(), 0f)
        path.lineTo(width.toFloat(), height.toFloat())
        path.lineTo(0f, height.toFloat())
        path.lineTo(0f, 0f)

        canvas.drawPath(path, paint)
    }

    fun animateClipAmount() {
        val valueAnimator = ValueAnimator.ofFloat(0f, 450f)
        valueAnimator.addUpdateListener {
            val value = it.animatedValue as Float
            clipAmount = value
            println("Value -> $clipAmount")
            postInvalidateOnAnimation()
        }
        valueAnimator.duration = 2000
        valueAnimator.start()
    }

}

В onCreate:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val layout1 = findViewById<android.support.constraint.ConstraintLayout>(R.id.layout1)

        val blackGraph = BlackGraph(this)
        layout1 .addView(blackGraph)
        blackGraph.animateClipAmount()
    }

}

Другие вопросы по теме