Как применить динамический градиент к динамическому пути? - PullRequest
0 голосов
/ 03 июня 2019

Я пытаюсь нарисовать собственный путь с градиентом.Конечная цель состоит в том, чтобы анимировать путь к полной длине, но я также хочу поддерживать постоянный градиент по мере его анимации.На рисунке ниже у меня есть путь анимации, как и предполагалось, но я не могу понять, как также анимировать градиент (т. Е. В любом данном сегменте градиент должен порождать сегмент - как начальный, так и конечный цвета, и растут по мере роста пути).

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 () и примените его, но это кажется очень неэффективным.

  • Применить пользовательскую матрицу и вращать ее при изменении пути (но может
    не заставить его работать должным образом)

Есть ли способ сделать это эффективно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...