Delayed construction of VectorDrawables
The go-to way of declaring VectorDrawables on Android is a Java-esque Singleton that delays construction to the first access:
private var _Smiley: ImageVector? = null
public val Smiley: ImageVector
get() {
if (_Smiley != null) {
return _Smiley!!
}
_Smiley = ImageVector.Builder(
name = "Smiley",
defaultWidth = 500.dp,
defaultHeight = 500.dp,
viewportWidth = 500f,
viewportHeight = 500f
)
.apply {
// ... Vector Path Commands
}
}
or if you choose the function equivalent it will use Compose’s remember to re-use the constructed VectorDrawable across compositions:
@Composable
fun rememberSmiley(): ImageVector {
return remember {
ImageVector.Builder(
name = "Smiley",
defaultWidth = 500.dp,
defaultHeight = 500.dp,
viewportWidth = 500f,
viewportHeight = 500f
)
.apply {
// ... Vector Path Commands
}
}
}
Note that the latter one works in Compose Contexts only.
The pre-made Material Icons provided by Google follow this pattern as well:
public val Icons.Outlined.Edit: ImageVector
get() {
if (_edit != null) {
return _edit!!
}
_edit = materialIcon(name = "Outlined.Edit") {
materialPath {
// ... Vector Path Commands
}
}
}
There’s a better, more Kotlin-idiomatic way of doing this:
public val Smiley: ImageVector by lazy {
ImageVector.Builder(
name = "Smiley",
defaultWidth = 500.dp,
defaultHeight = 500.dp,
viewportWidth = 500f,
viewportHeight = 500f
)
.apply {
// ... Vector Path Commands
}.build()
}
This way it is still an immutable val, the construction delayed to the first access but way simpler and cleaner. And since it doesn’t rely on remember, it can be used outside of a Composable Context.