Is it possible to somehow set `Text()` color by u...
# compose
p
Is it possible to somehow set
Text()
color by using
ColorFilter
?
k
What's your usecase? There might be some other way to achieve it.
p
I'm animating a color filter for both Image and Text. Atm I'm doing it as following, but I'm wondering if there is a better way to do it, by using single
animateColorAsState()
.
Copy code
@Composable
private fun Item(
    @DrawableRes icon: Int,
    @StringRes text: Int,
    isSelected: Boolean,
) {
    Column {
        ItemIcon(icon = icon, isSelected = isSelected)
        ItemText(text = text, isSelected = isSelected)
    }
}

@Composable
private fun ItemIcon(@DrawableRes icon: Int, isSelected: Boolean) {
    val overlayColor by animateColorAsState(
        targetValue = if (isSelected) Color.Transparent else AppColor.grey50,
        label = "icon filter color",
    )
    val colorFilter = remember(overlayColor) {
        ColorFilter.tint(overlayColor, BlendMode.SrcAtop)
    }
    Image(
        painter = painterResource(icon),
        contentDescription = null,
        colorFilter = colorFilter,
    )
}

@Composable
private fun ItemText(@StringRes text: Int, isSelected: Boolean) {
    val color by animateColorAsState(
        targetValue = if (isSelected) AppColor.blueBrand else AppColor.grey50,
        label = "item text color",
    )
    Text(text = stringResource(text), color = color)
}
Thisis how I want it to look like, in both
isSelected
states:
k
The way you are already doing is good to go.. Don't over complicate things.
p
I already opened PR with this code. I'm just wondering how to make it better.
k
You can hoist your color states to make your components more dynamic for reusability... And it's also the recommended way...
p
Yeah, I would like to do that, but how? In case of Image, I'm animating between transparent and gray (because I need ColorFilter) and in case of text, between blue and gray. Is there a way to apply ColorFilter to the Color somehow?
k
Since you're using 2 different color combinations then you have to use two different states, what I was recommending is to hoist the color aniamtion state like this.
Copy code
@Composable
private fun Item(
    @DrawableRes icon: Int,
    @StringRes text: Int,
    isSelected: Boolean,
) {
    val imageColor by animateColorAsState(
        targetValue = if (isSelected) Color.Transparent else AppColor.grey50,
        label = "icon filter color",
    )

    val textColor by animateColorAsState(
        targetValue =if (isSelected) AppColor.blueBrand else AppColor.grey50,
        label = "item text color",
    )

    Column {
        ItemIcon(icon = icon, color = imageColor)
        ItemText(text = text, color = textColor)
    }
}

@Composable
private fun ItemIcon(@DrawableRes icon: Int, color: Color) {
    Image(
        painter = painterResource(icon),
        contentDescription = null,
        colorFilter = ColorFilter.tint(color, BlendMode.SrcAtop)
    )
}

@Composable
private fun ItemText(@StringRes text: Int, color: Color) {
    Text(text = stringResource(text), color = color)
}
p
Sorry, but your solution is pretty much the same as mine, you only hoisted the colors. I'm not asking how to hoist colors, but how to join
animateColorAsState
. Something as following, but I have no idea how to set
ColorFilter
to my
Text
color.
Copy code
@Composable
private fun Item(
    @DrawableRes icon: Int,
    @StringRes text: Int,
    isSelected: Boolean,
) {
    Column {
		val overlayColor by animateColorAsState(
			targetValue = if (isSelected) Color.Transparent else AppColor.grey50,
			label = "icon filter color",
		)
		val colorFilter = remember(overlayColor) {
			ColorFilter.tint(overlayColor, BlendMode.SrcAtop)
		}
	
        Image(
			painter = painterResource(icon),
			contentDescription = null,
			colorFilter = colorFilter,
		)
		
		Text(
			text = stringResource(text),
			// Set default color like this or something:
			color = AppColor.blueBrand,
			// Not sure how to combine [colorFilter] and [AppColor.blueBrand]
		)
    }
}
k
But why exactly do you wanna do it? You have different color combination for both image and text, even if you make it work, your text willh have wrong color.
😮‍💨 1