Implementing a Color Gradient Animation in Android with GradientDrawable and PropertyAnimator
This article demonstrates how to create a smooth color‑gradient animation for an Android view by dynamically configuring a GradientDrawable and driving the transition with a Kotlin PropertyAnimator, including code examples and step‑by‑step explanations.
1. Introduction
The article introduces a visual effect where a control’s background color gradually changes from one color to another after a click, aiming for a smooth transition without using custom views.
2. Scenario Analysis
It discusses the need for a gradual color change using gradients (linear, radial, sweep) and decides to use a linear gradient for the demonstration.
3. Implementation
(1) Gradient Implementation
Instead of static XML, the gradient is created programmatically with GradientDrawable. An initial demo uses two colors (purple and pink) and sets the drawable as the background of a TextView.
private fun setBg(){
val colors = intArrayOf(
Color.parseColor("#9932CC"),
Color.parseColor("#FF69B4")
)
val drawable = GradientDrawable()
drawable.gradientType = GradientDrawable.LINEAR_GRADIENT
drawable.orientation = GradientDrawable.Orientation.LEFT_RIGHT
drawable.colors = colors
tvTest?.background = drawable
}Attempts to animate the gradient using the drawable’s level property reveal limitations, prompting a switch to the newer setColors(colors, offsets) method available from Android Q.
(2) Color Transition Process
A ValueAnimator drives a float variable x from 0 to 1.1, which is used as offsets for the gradient, creating a smooth transition.
private fun setBg() {
val colors = intArrayOf(
Color.parseColor("#9932CC"),
Color.parseColor("#FF69B4")
)
val offsets = floatArrayOf(x - 0.1f, x)
val drawable = GradientDrawable()
drawable.gradientType = GradientDrawable.LINEAR_GRADIENT
drawable.orientation = GradientDrawable.Orientation.LEFT_RIGHT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
drawable.setColors(colors, offsets)
}
tvTest?.background = drawable
}
private var mValueAnimator1: ValueAnimator? = null
fun startToStopChange() {
if (mValueAnimator1 == null) {
mValueAnimator1 = ValueAnimator.ofFloat(0f, 1.1f)
mValueAnimator1?.addUpdateListener {
x = it.animatedValue as Float
setBg()
}
}
mValueAnimator1?.setDuration(2000)?.start()
}The full activity code ties everything together, initializing the view, setting the initial background, and starting the animation on click.
var tvTest: TextView? = null
var x = 0f
private var mValueAnimator1: ValueAnimator? = null
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.test_main)
tvTest = findViewById(R.id.tv_test)
setBg()
tvTest?.setOnClickListener { startToStopChange() }
}
// setBg() and startToStopChange() implementations as shown above4. Summary
The effect is achieved in two steps: first, create a linear GradientDrawable with two colors; second, animate the gradient by updating its offsets via a ValueAnimator. The article emphasizes that complex UI effects are built from simple, well‑understood fundamentals.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
