无法解析片段中的 ViewModelProvider 构造?
Cannot resolve ViewModelProvider construction in a fragment?
我花了很多时间试图找出为什么在下面的代码中(接近尾声),我在 ViewModelProvider(this) 上遇到错误。我还尝试了 getActivity() 而不是 'this',同样的问题。我得到的错误是 "Cannot resolve constructor ..."
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
public class ItemSetupFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_setup, container, false);
return view;
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ItemSetupFragmentModel model = new ViewModelProvider(this).get(ItemSetupFragmentModel.class);
model.getKids().observe(this, users -> {
// update UI
});
}
}
您应该通过以下方式实例化您的 viewModel:
ItemSetupFragmentModel model = ViewModelProviders.of(this).get(ItemSetupFragmentModel.class);
首先你需要使用最新版本的生命周期扩展。应该是:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0"
或任何更新版本。
那么你应该使用requireActivity()
而不是getActivity()
。这样您将确保 activity 已附加,而不是 NullPointerException
.
ItemSetupFragmentModel model = new ViewModelProvider(requireActivity()).get(ItemSetupFragmentModel.class);
注: ViewModel Overview and Declaring Dependencies
将库添加到 Gradle 文件后,我不得不重新启动缓存。
没必要用requireActivity()
,this
就够了。
您没有使用包含 ViewModelProvider(@NonNull ViewModelStoreOwner owner)
构造函数的最新库版本。您正在查看最新的文档,但未使用 ViewModel
的最新库版本。
您需要使用
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0' // For Java
或
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' // For kotlin extension
最干净的实现必须使用 Kotlin 来实现其高级功能。您可以在单独的 Kclass 中创建此 kotlin 代码,也可以将此答案留给未来想知道如何在 Kotlin 中执行此操作的用户。基本上我们像这样通过惰性初始化 ViewModel:
确保你有这个依赖:
implementation "androidx.fragment:fragment-ktx:1.2.0"
创建这个访问内部 fragment-ktx 方法的辅助函数,该方法允许您通过懒惰创建 ViewModel 实例:
@MainThread
inline fun <reified VM : ViewModel> Fragment.fragmentViewModel() =
createViewModelLazy(
VM::class,
{ this.viewModelStore },
{ ViewModelFactory(Database.getDatabase(requireContext().applicationContext)) }
)
现在使用这个官方 java 示例创建一个 ViewModelFactory:
或者,这里是 Kotlin 变体:
class ViewModelFactory(private val database: Database?) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
requireNotNull(database) { "Database must not be null" }
return when {
modelClass.isAssignableFrom(ItemSetupFragmentModel::class.java) -> {
ItemSetupFragmentModel() as T
}
else -> {
throw IllegalArgumentException("Unknown ViewModel class")
}
}
}
}
现在进入您的片段并像这样简单地初始化您的 ViewModel
class ItemSetupFragment : Fragment() {
private val model by viewModel<ItemSetupFragmentModel>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.getKids().observe(this, users -> {
// update UI
});
}
}
希望对您有所帮助!
我花了很多时间试图找出为什么在下面的代码中(接近尾声),我在 ViewModelProvider(this) 上遇到错误。我还尝试了 getActivity() 而不是 'this',同样的问题。我得到的错误是 "Cannot resolve constructor ..."
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
public class ItemSetupFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_setup, container, false);
return view;
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ItemSetupFragmentModel model = new ViewModelProvider(this).get(ItemSetupFragmentModel.class);
model.getKids().observe(this, users -> {
// update UI
});
}
}
您应该通过以下方式实例化您的 viewModel:
ItemSetupFragmentModel model = ViewModelProviders.of(this).get(ItemSetupFragmentModel.class);
首先你需要使用最新版本的生命周期扩展。应该是:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0"
或任何更新版本。
那么你应该使用requireActivity()
而不是getActivity()
。这样您将确保 activity 已附加,而不是 NullPointerException
.
ItemSetupFragmentModel model = new ViewModelProvider(requireActivity()).get(ItemSetupFragmentModel.class);
注: ViewModel Overview and Declaring Dependencies
将库添加到 Gradle 文件后,我不得不重新启动缓存。
没必要用requireActivity()
,this
就够了。
您没有使用包含 ViewModelProvider(@NonNull ViewModelStoreOwner owner)
构造函数的最新库版本。您正在查看最新的文档,但未使用 ViewModel
的最新库版本。
您需要使用
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0' // For Java
或
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' // For kotlin extension
最干净的实现必须使用 Kotlin 来实现其高级功能。您可以在单独的 Kclass 中创建此 kotlin 代码,也可以将此答案留给未来想知道如何在 Kotlin 中执行此操作的用户。基本上我们像这样通过惰性初始化 ViewModel:
确保你有这个依赖:
implementation "androidx.fragment:fragment-ktx:1.2.0"
创建这个访问内部 fragment-ktx 方法的辅助函数,该方法允许您通过懒惰创建 ViewModel 实例:
@MainThread
inline fun <reified VM : ViewModel> Fragment.fragmentViewModel() =
createViewModelLazy(
VM::class,
{ this.viewModelStore },
{ ViewModelFactory(Database.getDatabase(requireContext().applicationContext)) }
)
现在使用这个官方 java 示例创建一个 ViewModelFactory:
或者,这里是 Kotlin 变体:
class ViewModelFactory(private val database: Database?) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
requireNotNull(database) { "Database must not be null" }
return when {
modelClass.isAssignableFrom(ItemSetupFragmentModel::class.java) -> {
ItemSetupFragmentModel() as T
}
else -> {
throw IllegalArgumentException("Unknown ViewModel class")
}
}
}
}
现在进入您的片段并像这样简单地初始化您的 ViewModel
class ItemSetupFragment : Fragment() {
private val model by viewModel<ItemSetupFragmentModel>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.getKids().observe(this, users -> {
// update UI
});
}
}
希望对您有所帮助!