这将创建MyViewModel具有默认或零参数的对象。
我的活动
ViewModelProviders.of(this)
.get(MyViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
MyViewModel如果类有自定义参数构造函数,我该如何创建?
我的视图模型
class MyViewModel(context: Application,
private val repository: MistakesRepository) : AndroidViewModel(context) {
val showLoading = ObservableBoolean(false)
val liveItems = MutableLiveData<List<Mistake>>()
fun loadAllMistakes(forceLoad: Boolean) {
}
}
Run Code Online (Sandbox Code Playgroud)
在搜索了几篇博客文章后,可以通过自定义工厂对象来完成。但为什么没有关于这个开发者页面的文档呢?或者我在这里错过了什么?
我想使用 SearchView 搜索房间数据库中的某个元素,但我遇到了一个问题,因为我无法在 RecyclerViewAdapter 中使用 getFilter 因为我有 ViewModel 也许谁知道如何将所有这些元素组合到一个项目中。
\n我搜索一种使用 Transormations.switchMap 的方法。但我无法连接它们。
\n\n\n产品视图模型
\n
class ProductViewModel(application: Application) : AndroidViewModel(application) {\n private val repository: ProductRepository\n\n val allProducts: LiveData<List<ProductEntity>>\n private val searchStringLiveData = MutableLiveData<String>()\n\n init {\n val productDao = ProductsDB.getDatabase(application, viewModelScope).productDao()\n repository = ProductRepository(productDao)\n allProducts = repository.allProducts\n searchStringLiveData.value = ""\n }\n\n fun insert(productEntity: ProductEntity) = viewModelScope.launch {\n repository.insert(productEntity)\n }\n\n\n val products = Transformations.switchMap(searchStringLiveData) { string ->\n repository.getAllListByName(string)\n\n }\n\n fun searchNameChanged(name: String) {\n searchStringLiveData.value = name\n }\n\n\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\n\n产品道 …
我正在尝试将 ViewModel 注入适配器中。注入 Fragment 时效果很好。
\n视图模型:
\nclass HomeViewModel @ViewModelInject constructor(\n): ViewModel() \nRun Code Online (Sandbox Code Playgroud)\n分段:
\n@AndroidEntryPoint\nclass HomeFragment : BaseFragment<FragmentHomeBinding, HomeViewModel>(\nR.layout.fragment_home\n) {\n\nprivate val viewModel: HomeViewModel by viewModels()\nRun Code Online (Sandbox Code Playgroud)\n目前为止没有问题。但是当我尝试注入适配器时出现问题。
\nclass HomeListAdapter @Inject constructor(\n): BaseListAdapter<Users>(\nitemsSame = { old, new -> old.username == new.username },\ncontentsSame = { old, new -> old == new }\n) {\n\n\n\nprivate val viewModel: HomeViewModel by viewModels() //viewModels() unresolved reference\nRun Code Online (Sandbox Code Playgroud)\n\n更新:
\n如果我尝试使用构造函数注入或字段注入,我会收到以下错误:
\n error: [Dagger/MissingBinding] ***.home.HomeViewModel cannot be provided without an @Inject constructor or …Run Code Online (Sandbox Code Playgroud) 我正在浏览这个 Codelab: https: //developer.android.com/codelabs/android-lifecycles#6 它解释了如何在 ViewModel 中使用 SavedStateHandle 来避免进程死亡。ViewModel的构造函数如下:
private SavedStateHandle mState;
public SavedStateViewModel(SavedStateHandle savedStateHandle) {
mState = savedStateHandle;
}
Run Code Online (Sandbox Code Playgroud)
并且viewmodel在Activity中初始化如下:
mSavedStateViewModel = new ViewModelProvider(this).get(SavedStateViewModel.class);
Run Code Online (Sandbox Code Playgroud)
ViewModel 的构造函数何时被调用?而Viewmodel是如何获取savedStateHandleViewModel的参数的呢?
编辑:
我通过这篇博文找到了问题的答案: https://www.rockandnull.com/viewmodel-savedstate/
它表示,如果 是SavedStateHandle视图模型构造函数中的唯一参数,则by viewModels委托会自动将其提供给视图模型。
然而,如果我们有依赖注入框架(Hilt)提供的自定义参数的组合,例如:存储库,还有一些其他运行时参数,例如:选定的类别 ID 和 SavedStateHandle 来帮助我们在视图模型的构造函数中避免进程死亡- 我们如何向工厂提供所有这些参数?
请发布一个小例子以供我的理解
我正在编写一个简单的应用程序,以便学习,该应用程序有两个viewModels,ItemListViewModel显示项目列表并ItemCreateViewModel让您创建项目,项目存储在 Room 中。
我的问题是,当我打开应用程序时,会显示列表,但在我打开详细信息并创建新项目后,返回第一个 ( ItemListViewModel) 列表不会更新。
@HiltViewModel
class ItemListViewModel
@Inject
constructor(private val itemRepository: ItemRepository) : ViewModel() {
var uiState by mutableStateOf(value = ItemListState(state = State.LOADING))
private set
init {
viewModelScope.launch(Dispatchers.IO) {
itemRepository.fetchItems()
.distinctUntilChanged()
.collect { items ->
uiState = uiState.copy(
state = State.IDLE,
items = if (items.isNullOrEmpty()) emptyList() else items
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里是撰写视图
@Composable
fun ItemList(
viewModel: ItemListViewModel,
navController: NavController
) {
val items = viewModel.uiState.items
ShowItems(items) // <--- this …Run Code Online (Sandbox Code Playgroud) 我是 Kotlin 和 Android Studio 的新手,现在尝试使用 ViewModel 实现 Room 数据库,但我面临问题“kotlin.UninitializedPropertyAccessException:lateinit 属性habitViewModel 尚未初始化”
我认为这是由于视图模型的早期初始化造成的,但我找不到修复它的方法。
这是我下面的代码。
创建代码时的活动
class HabitActivity : AppCompatActivity() {
lateinit var binding : ActivityHabitBinding
lateinit var habitViewModel : HabitViewModel
lateinit var habitAdapter: HabitAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityHabitBinding.inflate(layoutInflater)
habitViewModel = ViewModelProvider(this)[habitViewModel::class.java]
setContentView(binding.root)
// view model
habitViewModel.habitList.observe(this) {
habitAdapter.update(it)
}
// adapter
habitAdapter = HabitAdapter(this)
binding.rvHabitList.layoutManager = LinearLayoutManager(this)
binding.rvHabitList.adapter = habitAdapter
}
Run Code Online (Sandbox Code Playgroud)
视图模型代码
class HabitViewModel: ViewModel() {
val habitList: LiveData<MutableList<HabitDTO>>
private var habitRepository: HabitRepo = …Run Code Online (Sandbox Code Playgroud)