过渡 GradientDrawable
Transitioning a GradientDrawable
我有一个功能可以在 MainActivity
的背景上创建渐变。渐变以编程方式创建为 GradientDrawable
。应用程序中的某些交互会改变渐变的颜色。
渐变和颜色显示正确,它们会相应地发生变化,但是,我想要颜色变化的过渡效果。现在,颜色立即过渡,没有交叉淡入淡出。
fun createGradient() {
gd.shape = GradientDrawable.RECTANGLE
mainActivityID.background = gd
gd.gradientType = GradientDrawable.LINEAR_GRADIENT
gd.orientation = (GradientDrawable.Orientation.BL_TR)
}
基于应用程序中的交互,我使用 when
语句更改 GradientDrawable
的颜色
fun changeGradient(){
//val td = gd as TransitionDrawable
//td.isCrossFadeEnabled = true
//td.startTransition(1500)
when(calories){
in 0..50 -> gd.colors = intArrayOf(
ContextCompat.getColor(this, R.color.dBlue),
ContextCompat.getColor(this, R.color.lBlue)
)
in 51..100 -> gd.colors = intArrayOf(
ContextCompat.getColor(this, R.color.dRed),
ContextCompat.getColor(this, R.color.lRed)
)
// etc...
}
}
我尝试将 GradientDrawable 转换为 TransitionDrawable(如上面的注释代码所示),但是崩溃了:
java.lang.ClassCastException:
android.graphics.drawable.GradientDrawable cannot be cast to
android.graphics.drawable.TransitionDrawable
如何在 GradientDrawable 颜色变化之间添加 1500 毫秒的过渡?
java.lang.NegativeArraySizeException: -16777216
进度崩溃
when(calories){
in 0..50 -> animateGradient(gd, IntArray(Color.BLACK), IntArray(Color.CYAN))
in 51..100 -> animateGradient(gd, IntArray(Color.RED), IntArray(Color.BLUE))
in 101..150 -> animateGradient(gd, IntArray(Color.GREEN), IntArray(Color.YELLOW))
// etc... about 15 more statements.
}
我认为 gradient drawable 没有内置过渡方法,但您可以 运行 您自己的值动画器来执行颜色过渡。
var anim : Animator? = null
fun animateGradient(gd: GradientDrawable, from : IntArray, to: IntArray){
require(from.size == to.size)
anim?.cancel()
val arraySize = from.size
val props = Array<PropertyValuesHolder>(arraySize){
PropertyValuesHolder.ofObject(it.toString(), ArgbEvaluator(), from[it], to[it])
}
val anim = ValueAnimator.ofPropertyValuesHolder(*props)
anim.addUpdateListener {
gd.colors = IntArray(arraySize){i ->
it.getAnimatedValue(i.toString()) as Int
}
}
anim.duration = 1500
anim.start()
this.anim = anim
}
编辑:修改方法使其跟踪当前颜色本身,减少参数数量。
var anim : Animator? = null
// variable that tracks current color - must be initialized with default gradient colors
var currentGradient = intArrayOf(
ContextCompat.getColor(this, R.color.dBlue),
ContextCompat.getColor(this, R.color.lBlue)
)
fun animateGradient(targetColors: IntArray){
val from = currentGradient
require(from.size == targetColors.size)
anim?.cancel()
val arraySize = from.size
val props = Array<PropertyValuesHolder>(arraySize){
PropertyValuesHolder.ofObject(it.toString(), ArgbEvaluator(), from[it], targetColors[it])
}
val anim = ValueAnimator.ofPropertyValuesHolder(*props)
anim.addUpdateListener {valueAnim ->
IntArray(arraySize){i ->
valueAnim.getAnimatedValue(i.toString()) as Int
}.let{
currentGradient = it
gd.colors = it
}
}
anim.duration = 1500
anim.start()
this.anim = anim
}
呼叫站点:
when(calories){
in 0..50 -> animateGradient(intArrayOf(
ContextCompat.getColor(this, R.color.dBlue),
ContextCompat.getColor(this, R.color.lBlue)
))
in 51..100 -> animateGradient(intArrayOf(
ContextCompat.getColor(this, R.color.dRed),
ContextCompat.getColor(this, R.color.lRed)
))
// etc...
}
我有一个功能可以在 MainActivity
的背景上创建渐变。渐变以编程方式创建为 GradientDrawable
。应用程序中的某些交互会改变渐变的颜色。
渐变和颜色显示正确,它们会相应地发生变化,但是,我想要颜色变化的过渡效果。现在,颜色立即过渡,没有交叉淡入淡出。
fun createGradient() {
gd.shape = GradientDrawable.RECTANGLE
mainActivityID.background = gd
gd.gradientType = GradientDrawable.LINEAR_GRADIENT
gd.orientation = (GradientDrawable.Orientation.BL_TR)
}
基于应用程序中的交互,我使用 when
语句更改 GradientDrawable
fun changeGradient(){
//val td = gd as TransitionDrawable
//td.isCrossFadeEnabled = true
//td.startTransition(1500)
when(calories){
in 0..50 -> gd.colors = intArrayOf(
ContextCompat.getColor(this, R.color.dBlue),
ContextCompat.getColor(this, R.color.lBlue)
)
in 51..100 -> gd.colors = intArrayOf(
ContextCompat.getColor(this, R.color.dRed),
ContextCompat.getColor(this, R.color.lRed)
)
// etc...
}
}
我尝试将 GradientDrawable 转换为 TransitionDrawable(如上面的注释代码所示),但是崩溃了:
java.lang.ClassCastException: android.graphics.drawable.GradientDrawable cannot be cast to android.graphics.drawable.TransitionDrawable
如何在 GradientDrawable 颜色变化之间添加 1500 毫秒的过渡?
java.lang.NegativeArraySizeException: -16777216
when(calories){
in 0..50 -> animateGradient(gd, IntArray(Color.BLACK), IntArray(Color.CYAN))
in 51..100 -> animateGradient(gd, IntArray(Color.RED), IntArray(Color.BLUE))
in 101..150 -> animateGradient(gd, IntArray(Color.GREEN), IntArray(Color.YELLOW))
// etc... about 15 more statements.
}
我认为 gradient drawable 没有内置过渡方法,但您可以 运行 您自己的值动画器来执行颜色过渡。
var anim : Animator? = null
fun animateGradient(gd: GradientDrawable, from : IntArray, to: IntArray){
require(from.size == to.size)
anim?.cancel()
val arraySize = from.size
val props = Array<PropertyValuesHolder>(arraySize){
PropertyValuesHolder.ofObject(it.toString(), ArgbEvaluator(), from[it], to[it])
}
val anim = ValueAnimator.ofPropertyValuesHolder(*props)
anim.addUpdateListener {
gd.colors = IntArray(arraySize){i ->
it.getAnimatedValue(i.toString()) as Int
}
}
anim.duration = 1500
anim.start()
this.anim = anim
}
编辑:修改方法使其跟踪当前颜色本身,减少参数数量。
var anim : Animator? = null
// variable that tracks current color - must be initialized with default gradient colors
var currentGradient = intArrayOf(
ContextCompat.getColor(this, R.color.dBlue),
ContextCompat.getColor(this, R.color.lBlue)
)
fun animateGradient(targetColors: IntArray){
val from = currentGradient
require(from.size == targetColors.size)
anim?.cancel()
val arraySize = from.size
val props = Array<PropertyValuesHolder>(arraySize){
PropertyValuesHolder.ofObject(it.toString(), ArgbEvaluator(), from[it], targetColors[it])
}
val anim = ValueAnimator.ofPropertyValuesHolder(*props)
anim.addUpdateListener {valueAnim ->
IntArray(arraySize){i ->
valueAnim.getAnimatedValue(i.toString()) as Int
}.let{
currentGradient = it
gd.colors = it
}
}
anim.duration = 1500
anim.start()
this.anim = anim
}
呼叫站点:
when(calories){
in 0..50 -> animateGradient(intArrayOf(
ContextCompat.getColor(this, R.color.dBlue),
ContextCompat.getColor(this, R.color.lBlue)
))
in 51..100 -> animateGradient(intArrayOf(
ContextCompat.getColor(this, R.color.dRed),
ContextCompat.getColor(this, R.color.lRed)
))
// etc...
}