Android 中的共享视图模型
在android中,我们可以使用ViewModel通过在所有片段之间共享同一个ViewModel来在各种片段或活动之间共享数据,并且它们可以访问ViewModel中定义的所有内容。这是在片段或活动之间进行通信的一种方式。几乎每个应用程序在各种活动或片段之间都有一些通信。
我们将在本文中构建什么?
在本文中,我们将学习 Android 中的 Shared ViewModel 与其他 Fragment 进行通信。我们将开发一个包含两个片段的应用程序,其中一个片段更新两个片段之间共享的 ViewModel 中的数据,另一个片段观察该数据的变化并将更新后的数据显示在屏幕上。应用程序的工作是发送->接收->显示消息。下面给出了一个示例 GIF,以了解我们将在本文中做什么。
分步实施
第 1 步:创建一个新项目
要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。请注意,选择 Kotlin 作为编程语言。
第二步:创建一个类 SharedViewModel
转到SharedViewModel.kt文件并参考以下代码。下面是 SharedViewModel.kt 文件的代码。代码中添加了注释以更详细地理解代码。
Kotlin
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class SharedViewModel : ViewModel() {
// variable to contain message whenever
// it gets changed/modified(mutable)
val message = MutableLiveData()
// function to send message
fun sendMessage(text: String) {
message.value = text
}
}
Kotlin
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import androidx.lifecycle.ViewModelProvider
class MessageSenderFragment : Fragment() {
// to send message
lateinit var btn: Button
// to write message
lateinit var writeMSg: EditText
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_message_sender, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// reference for button and EditText
btn = view.findViewById(R.id.button)
writeMSg = view.findViewById(R.id.writeMessage)
// create object of SharedViewModel
val model = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
// call function "sendMessage" defined in SharedVieModel
// to store the value in message.
btn.setOnClickListener { model.sendMessage(writeMSg.text.toString()) }
}
}
XML
Kotlin
class MessageReceiverFragment : Fragment() {
// to contain and display shared message
lateinit var displayMsg: TextView
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// inflate the fragment layout
return inflater.inflate(R.layout.fragment_message_receiver, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// reference for the container declared above
displayMsg = view.findViewById(R.id.textViewReceiver)
// create object of SharedViewModel
val model = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
// observing the change in the message declared in SharedViewModel
model.message.observe(viewLifecycleOwner, Observer {
// updating data in displayMsg
displayMsg.text = it
})
}
}
XML
XML
Kotlin
mport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
第 3 步:创建两个片段,它们是 – MessageSenderFragment & MessageReceiverFragment
MessageSenderFragment – 发送将由MessageReceiverFragment接收的消息。单击它后,它将有一个按钮来发送消息。转到MessageSenderFragment.kt文件并参考以下代码。下面是 MessageSenderFragment.kt 文件的代码。代码中添加了注释以更详细地理解代码。
科特林
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.EditText
import androidx.lifecycle.ViewModelProvider
class MessageSenderFragment : Fragment() {
// to send message
lateinit var btn: Button
// to write message
lateinit var writeMSg: EditText
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_message_sender, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// reference for button and EditText
btn = view.findViewById(R.id.button)
writeMSg = view.findViewById(R.id.writeMessage)
// create object of SharedViewModel
val model = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
// call function "sendMessage" defined in SharedVieModel
// to store the value in message.
btn.setOnClickListener { model.sendMessage(writeMSg.text.toString()) }
}
}
导航到app > res > fragment_message_sender.xml并将以下代码添加到该文件中。下面是fragment_message_sender.xml文件的代码。
XML
MessageReceiverFragment – 接收 MessageSenderFragment 发送的消息。它将有一个 TextView 来在屏幕上显示更新的消息。转到MessageReceiverFragment.kt文件并参考以下代码。下面是 MessageReceiverFragment.kt 文件的代码。代码中添加了注释以更详细地理解代码。
科特林
class MessageReceiverFragment : Fragment() {
// to contain and display shared message
lateinit var displayMsg: TextView
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// inflate the fragment layout
return inflater.inflate(R.layout.fragment_message_receiver, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// reference for the container declared above
displayMsg = view.findViewById(R.id.textViewReceiver)
// create object of SharedViewModel
val model = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
// observing the change in the message declared in SharedViewModel
model.message.observe(viewLifecycleOwner, Observer {
// updating data in displayMsg
displayMsg.text = it
})
}
}
导航到app > res > fragment_message_receiver.xml并将以下代码添加到该文件中。下面是fragment_message_receiver.xml文件的代码。
XML
我们已经创建了SharedViewModel的对象,它与我们作为所有者使用相同的单一活动是同一个对象。这就是它被共享的原因。请注意,我们在两个片段中都使用了 requireActivity()。
. . .
ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
. . .
第三步:更新activity_main.xml
该活动由两个片段组成,并且是这两个片段的宿主。
XML
MainActivity.kt保持原样。
科特林
mport androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
现在,运行应用程序。
输出:
源代码:点击这里