89

Jetpack Compose – Text Shadows

 3 years ago
source link: https://handstandsam.com/2021/08/09/jetpack-compose-text-shadows/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Jetpack Compose – Text Shadows – Handstand Sam

As of version 1.0 of Jetpack Compose, Text Shadows don’t exist in the same way they used to on TextView. 😿

Adding a Shadow on a TextView looked like this:

<TextView
    android:id="@+id/text"
    style="@style/CategoryRowTitle"
    tools:text="Category" />
<style name="CategoryRowTitle" parent="TextAppearance.AppCompat">
    <item name="android:textSize">24sp</item>
    <item name="android:textColor">@color/white</item>
    <item name="android:shadowColor">@color/black</item>
    <item name="android:shadowDx">4</item>
    <item name="android:shadowDy">4</item>
    <item name="android:shadowRadius">8</item>
</style>

Adding a Shadow to Text in Jetpack Compose

You try can put a “shadow” on your Text Composable, but it’ll create a shadow behind the text container, not the actual characters. 🤔

Text(
    text = "Fruits",
    modifier = Modifier
        .shadow(elevation = 2.dp)
)

Creating a Custom Shadow in Jetpack Compose

I did my best to create a shadow myself by making a copy of the text, setting it to a dark color, and offsetting it by 2.dp.

@Composable
fun TextWithShadow(
    text: String,
    modifier: Modifier
) {
    Text(
        text = text,
        color = Color.DarkGray,
        modifier = modifier
            .offset(
                x = 2.dp,
                y = 2.dp
            )
            .alpha(0.75f)
    )
    Text(
        text = text,
        color = Color.White,
        modifier = modifier
    )
}

Looks great! But small differences.

Let’s Cheat and Use an AndroidView in Compose 😃

Compose has amazing interoperability with the Android View system. If something isn’t perfect in Compose, we can always just use the Android View version. Pixel perfect match! However, this wouldn’t work in Compose for Desktop because it keeps us tied to the Android View system.

@Composable
fun ComposeAndroidTextView(
    text: String,
    modifier: Modifier
) {
    AndroidView(
        modifier = modifier,
        factory = { context ->
            AppCompatTextView(context).apply {
                setTextAppearance(R.style.ItemRowTitle)
                this.text = text
            }
        }
    )
}

Let’s Try Again with Compose… StackOverflow? 🤔

I did find this Stack Overflow post that was similar, but not exactly what I needed. Here is what it had:

val textPaintStroke = Paint().asFrameworkPaint().apply {
    isAntiAlias = true
    style = android.graphics.Paint.Style.STROKE
    textSize = 64f
    color = android.graphics.Color.BLACK
    strokeWidth = 12f
    strokeMiter = 10f
    strokeJoin = android.graphics.Paint.Join.ROUND
}

val textPaint = Paint().asFrameworkPaint().apply {
    isAntiAlias = true
    style = android.graphics.Paint.Style.FILL
    textSize = 64f
    color = android.graphics.Color.WHITE
}

Canvas(
    modifier = Modifier.fillMaxSize(),
    onDraw = {
        drawIntoCanvas {
            it.nativeCanvas.drawText(
                "Sample",
                0f,
                120.dp.toPx(),
                textPaintStroke
            )
            it.nativeCanvas.drawText(
                "Sample",
                0f,
                120.dp.toPx(),
                textPaint
            )
        }
    }
)

What’s the Perfect Way to Match a TextView Shadow with Compose?

I’m not really sure.

I wanted to share my journey so far in figuring this out. It looks like the way to do it will be some custom way, and hopefully it is easy once we figure it out I’ll update this post. Tips are welcome via @HandstandSam on Twitter. Thanks!


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK