如何将动态渐变应用于动态路径?

时间:2019-06-03 07:15:32

标签: android android-canvas android-custom-view

我正在尝试绘制带有渐变的自定义路径。最终目标是使路径具有完整的动画效果,但我还希望在动画设置时保持一致的渐变。在下面的gif中,我按预期设置了路径的动画,但是我无法弄清楚如何同时对渐变进行动画处理(即,在任何给定的线段,渐变都应产生该线段-起始和结束颜色都随着路径的增长而增长)。

enter image description here

在下图中,部分路径仅包含渐变中的绿色,但应包含完整的渐变(绿色-粉色)

partial path

这是我的自定义视图

class GradientPath @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {


    private val paint = Paint()

    var progress: Float = 0f
        set(value) {
            field = value
            invalidate()
        }

    private val startColor : Int
    private val endColor : Int
    init {
        paint.strokeWidth = 64f
        paint.style = Paint.Style.STROKE
        paint.strokeCap = Paint.Cap.ROUND
        paint.pathEffect = CornerPathEffect(paint.strokeWidth / 2)
        startColor = ContextCompat.getColor(context, R.color.colorPrimary)
        endColor = ContextCompat.getColor(context, R.color.colorAccent)
    }

    private val path = Path()
    private lateinit var measure: PathMeasure

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)

        val fullPath = Path()
        val offset = paint.strokeWidth
        fullPath.moveTo(offset,  offset)
        fullPath.lineTo(offset, h.toFloat() - offset)
        fullPath.lineTo(w.toFloat() - offset, h.toFloat() - offset)

        measure = PathMeasure(fullPath, false)

        //Setup shader
        val shader = LinearGradient(
            offset,
            offset,
            w.toFloat() - offset,
            h.toFloat() - offset,
            intArrayOf(startColor, endColor),
            null,
            Shader.TileMode.CLAMP
        )
        paint.shader = shader

    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        measure.getSegment(0f, measure.length * progress, path, true)
        canvas.drawPath(path, paint)
        path.rewind()
    }

}

我已经尝试过的:

  • 在对onDraw()的每次调用中分配一个新的渐变并应用它,但这似乎效率很低。

  • 应用自定义矩阵并随着路径的变化旋转它(但可以
    无法使其正常工作)

有没有办法有效地完成此任务?

0 个答案:

没有答案