如何在kotlin中的多种颜色之间切换



嘿,我正试图在无尽的循环中在5种颜色之间更改背景颜色。

我试过的是这个

private val myColors = arrayOf(red, yellow, purple, orange, green)
private val colorCycle = TransitionDrawable(myColors)

private fun myFunction() {
this.background = colorCycle
colorCycle.startTransition(2000)
}

现在我知道这个实现只在2种颜色之间工作;LayerDrawables的扩展,用于在第一层和第二层之间交叉渐变。要启动转换,请调用startTransition(int(。要只显示第一层,请调用resetTransition(("但是我找不到关于如何做到这一点的信息,我想做的,5种颜色之间的无休止循环

如果有人能为我指明正确的方向,那将是完美的,谢谢!

我不认为在典型的库中有任何东西可以处理这个问题——就像你说的,TransitionDrawable只处理两层,它更多的是关于两个东西(通常是图像(之间的渐变。从技术上讲,你可以为每个过渡制作一个(color1colour2color2colour3等等(,并在每个过渡结束时交换它们,但这需要一些工作。

制作自己的实用程序类可能更容易,它可以在一堆颜色之间进行插值,比如

class ColourCycler(val transitionLength: Int, @ColorInt val colours: List<Int>) {
private var startTime: Long? = null
val currentColour
get(): @ColorInt Int {
// work out how much time has elapsed, and where that falls on the cycle
val elapsed = System.currentTimeMillis() - (startTime ?: 0)
val cyclePosition = ((elapsed / transitionLength) % colours.size).toInt()
val transitionPercent = (elapsed % transitionLength).toFloat() / transitionLength
// grab this colour on the cycle and the next (wrapping around the list)
// and blend them using the ColorUtils package from the androidx.core library
val colour1 = colours[cyclePosition]
val colour2 = colours[(cyclePosition + 1) % colours.size]
return ColorUtils.blendARGB(colour1, colour2, transitionPercent)
}
fun start() {
startTime = System.currentTimeMillis()
}
}

这样,一旦你start()它,你就可以随时轮询它,以获得当前时间的混合颜色。这里有一种协同程序的方法,但你可以使用任何你喜欢的重复任务方法——它只需要获得颜色,并更新背景:

// in your fragment's onViewCreated or whatever
// initialise your cycle and start it
val cycler = ColourCycler(
transitionLength = 2000, colours = listOf(
Color.parseColor("red"),
Color.parseColor("yellow"),
Color.parseColor("lime"),
Color.parseColor("cyan")
)
).apply { start() }
// set up a repeating task to poll it and update the background
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
// run continuously while the coroutine is active (not cancelled)
while (isActive) {
binding.layout.setBackgroundColor(cycler.currentColour)
// update every 16 ms i.e. ~60fps
delay(16)
}
}
}

一个更好的方法是将ColourCycler对象保持在ViewModel中,这样它就可以在旋转中幸存下来,而无需重新初始化(并从第一种颜色开始(。

您可能还想放弃整个启动状态,只需将currentColour属性转换为一个纯函数,该函数采用已运行值并返回适当的颜色,而不是自行决定已运行了多少时间。这样,您就可以在其他地方跟踪运行时间,并通过存储当前运行值来暂停循环,向后运行,等等!

最新更新