如何从资源设置 ImageVector?

Osa*_*mar 3 android kotlin android-resources android-jetpack-compose

我正在尝试为底部导航设置一个图标,如下所示:

sealed class Screen(val route: String, val label: String, val icon: ImageVector) {
    object Home : Screen("home", "Home",R.drawable.outline_home_black_24)
    object History : Screen("history", "History", R.drawable.outline_history_black_24)
}
Run Code Online (Sandbox Code Playgroud)

但它说我需要将参数切换为 Int。感谢帮助,谢谢。:)

Zor*_*ran 9

您应该像这样使用 ImageVector.vectorResource 函数:

import androidx.compose.ui.res.vectorResource


sealed class Screen(val route: String, val label: String, val icon: ImageVector) {
     object Home : Screen("home", "Home",ImageVector.vectorResource(R.drawable.outline_home_black_24))
     object History : Screen("history", "History", ImageVector.vectorResource(R.drawable.outline_history_black_24))
}
Run Code Online (Sandbox Code Playgroud)


Ygo*_*zão 6

不完全是问题的答案,但是,也许可以帮助有需要的人......

如果您使用 Jetpack Compose 并希望在使用ImageVector、 asIcons.Filled.Favorite和使用可绘制资源之间保持灵活性,则可以通过使用辅助类来实现此目的,如下所示:

class IconResource private constructor(
    @DrawableRes private val resID: Int?,
    private val imageVector: ImageVector?
) {

    @Composable
    fun asPainterResource(): Painter {
        resID?.let {
            return painterResource(id = resID)
        }
        return rememberVectorPainter(image = imageVector!!)
    }

    companion object {
        fun fromDrawableResource(@DrawableRes resID: Int): IconResource {
            return IconResource(resID, null)
        }

        fun fromImageVector(imageVector: ImageVector?): IconResource {
            return IconResource(null, imageVector)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用该类,您可以相应地创建密封类:

sealed class Screen(val route: String, @StringRes val resourceId: Int, icon: IconResource) {
    object Home : Screen(
        "home", R.string.something,
        IconResource.fromDrawableResource(R.drawable.outline_home_black_24)
    )

    object History : Screen(
        "history", R.string.something,
        IconResource.fromImageVector(Icons.Filled.Favorite)
    )
}
Run Code Online (Sandbox Code Playgroud)

然后,只需调用您的可组合项:

navigationItems.forEach { screen ->
    BottomNavigationItem(icon = {
        Icon(
            screen.icon.asPainterResource(),
            contentDescription = null
        )
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

更新

我已经发布了一个带有该实现的库,如果您需要它,可以在这里找到: https: //github.com/ygorluizfrazao/compose-resources

希望能帮助到你。