DEV Community

Cover image for Using gradient for styling text
Chris Margonis
Chris Margonis

Posted on

3

Using gradient for styling text

Having an engaging and fancy user interface is essential for providing a delightful user experience. In some cases, this calls for using gradient colors. While Android’s styling system is pretty powerful, it lacks an out-of-the-box way to style a text using a gradient for coloring its text. Since at Plum we always try to explore new ways to achieve the best results, we had to come up with a solution!

CharacterStyle to the rescue!

Thankfully the android.text.style package contains enough tools for extending the already-provided styling capabilities. There’re many ways to extend it, but for this case, we’ll take a look at extending CharacterStyle to match our needs.

The key method of that abstract class is updateDrawState:



public abstract void updateDrawState(TextPaint tp);


Enter fullscreen mode Exit fullscreen mode

This method has as a parameter the TextPaint that will be used in our TextView. Most importantly, the TextPaint can have a shader object for drawing. And for that, we’ll be using LinearGradient shader!

The code

Without further ado, here’s what we came up with:

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView: TextView = findViewById(R.id.tv_hello)
val text = "Hello World!"
val purple = getColor(R.color.purple_200)
val teal = getColor(R.color.teal_200)
val spannable = text.toSpannable()
spannable[0..text.length] = LinearGradientSpan(text, text, purple, teal)
textView.text = spannable
}
}
view raw ExampleUsage.kt hosted with ❤ by GitHub
import android.graphics.LinearGradient
import android.graphics.Shader
import android.text.TextPaint
import android.text.style.CharacterStyle
import android.text.style.UpdateAppearance
import androidx.annotation.ColorInt
/**
* Applies a linear gradient on the text to which the span is attached.
*
* @param containingText The text that encloses the text that needs the gradient.
* @param textToStyle The text that the gradient will be applied on. Can be a substring of `containingText` or equal to `containingText`.
* @param startColorInt Resolved color to use as the gradient's start color.
* @param endColorInt Resolved color to use as the gradient's end color.
*/
class LinearGradientSpan(
private val containingText: String,
private val textToStyle: String,
@ColorInt private val startColorInt: Int,
@ColorInt private val endColorInt: Int
) : CharacterStyle(), UpdateAppearance {
override fun updateDrawState(tp: TextPaint?) {
tp ?: return
var leadingWidth = 0f
val indexOfTextToStyle = containingText.indexOf(textToStyle)
if (!containingText.startsWith(textToStyle) && containingText != textToStyle) {
leadingWidth = tp.measureText(containingText, 0, indexOfTextToStyle)
}
val gradientWidth = tp.measureText(containingText, indexOfTextToStyle, indexOfTextToStyle + textToStyle.length)
tp.shader = LinearGradient(
leadingWidth,
0f,
leadingWidth + gradientWidth,
0f,
startColorInt,
endColorInt,
Shader.TileMode.REPEAT
)
}
}

Using it

The LinearGradientSpan can be used as any other character style:



val textView: TextView = findViewById(R.id.tv_hello)
val text = "Hello World!"
val purple = getColor(R.color.purple_200)
val teal = getColor(R.color.teal_200)
val spannable = text.toSpannable()
spannable[0..text.length] = LinearGradientSpan(text, text, purple, teal)
textView.text = spannable


Enter fullscreen mode Exit fullscreen mode

It’s a relatively easy way to produce an interesting text effect.

hello_gradient

While in a more real scenario (taken from Plum’s android application) the effect can have a more subtle effect:

plum_gradient

Closing

As I’m not an expert in Graphics (let alone Android graphics 🤣), there should be plenty of optimizations that this utility class could receive. If you also want to build amazing things (and maybe improve the LinearGradientSpan!) check out our openings!

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay