@HiltAndroidApp
class App: Application() { ... }
@AndroidEntryPoint
class MainActivity: ComponentActivity() {
val vm: CustomViewModel = viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(....)
setContent {
AppTheme {
CustomScreen(vm = vm)
}
}
}
}
@HiltViewModel
class CustomViewModel: ViewModel() { ... }
@Composable
fun CustomScreen(vm: CustomViewModel) { ... }
从MainActiviy用viewModels()方法获取CustomViewModel后传给CustomScreen没有问题,但是从CustomScreen用viewModel()方法获取CustomViewModel就会报错:
@AndroidEntryPoint
class MainActivity: ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(....)
setContent {
AppTheme {
CustomScreen()
}
}
}
}
@Composable
fun CustomScreen(vm: CustomViewModel = viewModel()) { ... }
希望能从composable fun中直接获取CustomViewModel
在 Jetpack Compose 中,你不能直接从 Composable 函数内部直接使用 viewModel()
函数,因为 viewModel()
是一个扩展函数,它依赖于当前的 LifecycleOwner
(如 Fragment
或 Activity
),而 Composable 函数本身并不直接持有或管理生命周期。不过,你可以通过几种方式在 Composable 函数中访问 ViewModel。
你已经展示了这种方法,即通过 Activity 或 Fragment 初始化 ViewModel,并通过参数传递给 Composable 函数。这是最常见和推荐的方式,因为它保持了 Compose UI 的声明性和无状态性。
LocalObservation
对于更复杂的场景,如果你需要在多个 Composable 中共享 ViewModel 而不显式传递它,你可以考虑使用 LocalObservation
(这是 Jetpack Compose 的一部分,但主要用于响应式数据流,而非直接用于 ViewModel)。然而,对于 ViewModel,更直接的方法(如方法 1)通常是更好的选择。
虽然不常见,但你可以通过创建一个自定义的 Compose 委托来包装对 ViewModel 的访问。然而,这通常会增加复杂性,并且不如直接传递 ViewModel 作为参数那样清晰和直接。
如果你使用 Hilt 或其他依赖注入框架,并且该框架支持 Jetpack Compose,你可以尝试使用这些框架提供的特定 Compose 集成来在 Composable 函数中注入 ViewModel。然而,对于 Hilt,通常的做法仍然是通过 Activity 或 Fragment 注入 ViewModel,并将其作为参数传递给 Composable。
在你的情况下,最简单和最直接的方法是继续使用 viewModels()
在 Activity 或 Fragment 中获取 ViewModel,并将其作为参数传递给 Composable 函数。这保持了代码的清晰性和可维护性,同时避免了在 Composable 函数中处理生命周期和依赖注入的复杂性。
@AndroidEntryPoint
class MainActivity: ComponentActivity() {
private val vm: CustomViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppTheme {
CustomScreen(vm = vm)
}
}
}
}
@Composable
fun CustomScreen(vm: CustomViewModel) {
// 使用 vm
}
我想制作一个简单的共享按钮来获取TextView值并共享它,但我不知道怎么做。 代码如下: 而相关的布局是: 我在这里看了文档和一些类似的问题,但找不到我的答案。感谢你对此的帮助。
问题内容: 我有这样的网址: 如何获取章节和帖子的参数值? 我的URL在Chapter参数的值中包含“&”。 问题答案: 您可以在Android中使用Uri类来完成此操作; https://developer.android.com/reference/android/net/Uri.html 这样,您甚至可以从查询参数中获取特定元素;
但我的问题是:我不知道如何在没有Cordova活动的情况下用java在后台服务中获得这些数据(“值”)。 Backgroud services Java:
问题内容: 我正在尝试编写一个简单的Python脚本,它将所有子目录中的index.tpl复制到index.html(有一些例外)。 通过尝试获取子目录列表,我陷入了困境。 问题答案: 我对各种功能进行了 速度测试 ,以将 完整路径 返回到所有当前子目录。 tl; dr: 始终使用: 奖励:使用,您也可以只使用而不是来获取文件夹名称。 该函数(以及下面的所有其他函数)将不会使用 自然排序 。这意味
问题内容: 给定一个函数,可以得到它的名字吗?说: 有人告诉我runtime.FuncForPC会有所帮助,但我不明白如何使用它。 问题答案: 很抱歉回答我自己的问题,但我找到了解决方案: