Last active
May 4, 2022 09:35
-
-
Save cmargonis/d1822422ac3f604b97ec06757ff351cd to your computer and use it in GitHub Desktop.
Gradient span which can be applied to an Android TextView
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment