Is there a way to dynamically set an icon value in Jetpack Compose?
Example, instead of:
Icon(Icons.Filled.Print, "print")
I'd like to do:
Icon(Icons.Filled.(iconValue), iconValueName)
Is there a way to dynamically set an icon value in Jetpack Compose?
Example, instead of:
Icon(Icons.Filled.Print, "print")
I'd like to do:
Icon(Icons.Filled.(iconValue), iconValueName)
You can use Java reflection. I rely on the fact that each material icon is placed in a separate file, and all of them are declared under androidx.compose.material.icons.filled
package.
@Composable
fun IconByName(name: String) {
val icon: ImageVector? = remember(name) {
try {
val cl = Class.forName("androidx.compose.material.icons.filled.${name}Kt")
val method = cl.declaredMethods.first()
method.invoke(null, Icons.Filled) as ImageVector
} catch (_: Throwable) {
null
}
}
if (icon != null) {
Icon(icon, "$name icon")
}
}
You can check out this answer for more details how Kotlin extensions are compiled to Java code.
I would also write a test for this logic using a couple of icons, just in case Compose changes something in future releases - a package name or moving multiple icons together in the same file, although this is unlikely.
You can then use a when statement and select appropriate image vector.
when(imageStringFromWeb) {
is "email" -> {
Icon(Icons.Filled.Email, null)
}
...
}
Edited to simplfy the code.