如何从资源中设置ImageVector?

3
我正在尝试为底部导航设置图标,如下所示:
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)
}

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

4个回答

7
你应该像这样使用 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))
}

6

虽然不完全回答了问题,但也许可以帮助需要的人...

如果您正在使用Jetpack Compose并且想在使用ImageVector(如Icons.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)
        }
    }
}

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

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)
    )
}

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

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

    ...
}

更新

我已发布了一个包含该实现的库,如果需要,可以在此处找到:https://github.com/ygorluizfrazao/compose-resources

希望能帮到你。


3

是的。像R.drawable.outline_home_black_24这样的引用并不是实际的ImageVector,而是帮助在代码中获取它们的Int引用。要获取实际的图像,您应该使用类似于ContextCompat.getDrawable(context, R.drawable.***)的东西来获取实际的Drawable文件。这意味着正确的用法应该是:

sealed class Screen(val route: String, val label: String, @DrawableRes val icon: Int)

额外的注释会在未传递drawable资源 R.drawable.*** 类似这样的参数时发出警告。

3

试试这个

sealed class Screen(val route: String, val label: String, val icon: ImageVector) {
    object Home : Screen("home", "Home", painterResource(id = R.drawable.outline_home_black_24))
    object History : Screen("history", "History", painterResource(id = R.drawable.outline_history_black_24))
}

2
谢谢。非常感激。拒绝。 - Osama Omar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接