努力获取相同的 ViewModel 实例
Struggle to get the same ViewModel instance
我不确定我是否正确理解了 Android 中的 ViewModel
体系结构。我想 ViewModel 生命周期与 activity 相关,所以我们期待相同的实例,如果我们将 activity 或片段上下文传递给 ViewModelProvider
?[=16= 并不重要]
无论如何,这是我的 ViewModel:
class MainViewModel : ViewModel() {
var teamName: String = "Warriors";
}
这是我的 Activity:
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
viewModel.teamName = "Cavaliers";
Log.d("YouQi", "activity viewModel.teamName: ${viewModel.teamName}");
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
}
}
最后这是我的片段:
class MainFragment : androidx.fragment.app.Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.main_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
Log.d("YouQi", "fragment viewModel.teamName: ${viewModel.teamName}");
}
}
我在 Logcat 中得到以下输出:
2018-06-03 16:06:24.591 31124-31124/com.axzae.zapkotlin D/YouQi: activity viewModel.teamName: Cavaliers
2018-06-03 16:06:24.652 31124-31124/com.axzae.zapkotlin D/YouQi: fragment viewModel.teamName: Warriors
显示数值没有更新到骑士队。我是不是用错了ViewModel,应该用Dagger来实现单例?
您使用的 ViewModelProvider
是来自 activity 还是来自片段。请尝试使用 ViewModelProviders.of(getActivity())
作为片段。
这实际上非常方便 - 您可以分别保留片段相关模型和更通用的 activity 绑定模型。
不,您不需要使用依赖注入来实现ViewModel 中的单例。您可以像这样将 activity 上下文传递给 ViewModel:
viewModel = ViewModelProviders.of(activity).get(MainViewModel::class.java)// by this you will get the same value of teamName as your activity
我不确定我是否正确理解了 Android 中的 ViewModel
体系结构。我想 ViewModel 生命周期与 activity 相关,所以我们期待相同的实例,如果我们将 activity 或片段上下文传递给 ViewModelProvider
?[=16= 并不重要]
无论如何,这是我的 ViewModel:
class MainViewModel : ViewModel() {
var teamName: String = "Warriors";
}
这是我的 Activity:
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
viewModel.teamName = "Cavaliers";
Log.d("YouQi", "activity viewModel.teamName: ${viewModel.teamName}");
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
}
}
最后这是我的片段:
class MainFragment : androidx.fragment.app.Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.main_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
Log.d("YouQi", "fragment viewModel.teamName: ${viewModel.teamName}");
}
}
我在 Logcat 中得到以下输出:
2018-06-03 16:06:24.591 31124-31124/com.axzae.zapkotlin D/YouQi: activity viewModel.teamName: Cavaliers
2018-06-03 16:06:24.652 31124-31124/com.axzae.zapkotlin D/YouQi: fragment viewModel.teamName: Warriors
显示数值没有更新到骑士队。我是不是用错了ViewModel,应该用Dagger来实现单例?
您使用的 ViewModelProvider
是来自 activity 还是来自片段。请尝试使用 ViewModelProviders.of(getActivity())
作为片段。
这实际上非常方便 - 您可以分别保留片段相关模型和更通用的 activity 绑定模型。
不,您不需要使用依赖注入来实现ViewModel 中的单例。您可以像这样将 activity 上下文传递给 ViewModel:
viewModel = ViewModelProviders.of(activity).get(MainViewModel::class.java)// by this you will get the same value of teamName as your activity