ViewModel是jetpack下面比较常用的组件。他是MVVM架构中的重要组成部分,承担着类似MVP架构中Presenter的作用。
由此图片我们可以看出,ViewModel的生命周期犹如Service一般,贯穿Activity的整个生命周期。这也就是它为什么能够在即使屏幕旋转之后,也能保存下来数据。因为在它的创建在onCreate的时候就已经创建好了,所以,不管activity如何如何,他依旧我行我素,算是一个有个性的组件。
class NumViewModel : ViewModel() {
var num = 0
}
class MainActivity : AppCompatActivity() {
private lateinit var numViewModel: NumViewModel
private lateinit var tv:TextView
@SuppressLint("SetTextI18n", "MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tv = findViewById(R.id.num_tv)
//viewmodel的创建
numViewModel = ViewModelProvider(this)[NumViewModel::class.java]
tv.text = numViewModel.num.toString()
}
@SuppressLint("SetTextI18n")
fun add(view: View) { //自定义button点击事件
numViewModel.num++
tv.text = numViewModel.num.toString()
}
}
ViewModel采用工厂模式进行创建,让ViewModel整个生命周期设置为Activity级别的ViewModel。
如果直接实例化NumViewModel是没有用的,在之后的hilt依赖注入会让代码更加解耦
class OneFragment : Fragment() {
private lateinit var btn:Button
private lateinit var tv:TextView
private lateinit var numViewModel:NumViewModel
@SuppressLint("MissingInflatedId", "SetTextI18n")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_one,container,false)
numViewModel = ViewModelProvider(requireActivity())[NumViewModel::class.java]
btn = view.findViewById(R.id.fragment1_btn)
tv = view.findViewById(R.id.fragment1_num_tv)
tv.text =numViewModel.num.toString()
btn.setOnClickListener {
++numViewModel.num
tv.text =(numViewModel.num).toString()
}
return view
}
}
class TwoFragment : Fragment() {
private lateinit var btn: Button
private lateinit var tv: TextView
private lateinit var numViewModel:NumViewModel
@SuppressLint("MissingInflatedId", "SetTextI18n")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_second,container,false)
numViewModel = ViewModelProvider(requireActivity())[NumViewModel::class.java]
btn = view.findViewById(R.id.fragment2_btn)
tv = view.findViewById(R.id.fragment2_num_tv)
tv.text =numViewModel.num.toString()
btn.setOnClickListener {
tv.text =(++numViewModel.num).toString()
}
return view
}
}
numViewModel = ViewModelProvider(requireActivity())[NumViewModel::class.java]
此代码中我将此viewmodel设置为activity级别,这样,就能实现fragment中的数据共享,但是,我们发现了一个问题,那就是,只要不触发点击事件,就无法更新UI组件,所以,livedata的出现弥补了ViewModel的不足。
class SecondActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
}
}