你如何观察片段外的 LiveData
How do you observe LiveData outside a fragment
我在 Fragment 中有一个 TextView。使用 LiveData 我可以从片段中更改文本。通过使用 MainActivity 中的按钮(片段外),我试图更改 TextView 中的文本,但它不起作用。有人可以帮忙吗。这是我的代码:
这是具有按钮和片段的 MainActivity
class MainActivity : AppCompatActivity() {
var tg: ToneGenerator? = null
private lateinit var btn: Button
private lateinit var viewModel:ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tg = ToneGenerator(AudioManager.STREAM_SYSTEM, 100)
btn = findViewById(R.id.buttonTest1)
viewModel = ViewModelProvider(this).get(ViewModel::class.java)
btn.setOnClickListener {
tg?.startTone(ToneGenerator.TONE_PROP_BEEP)
viewModel.changeMLD()
}
}
}
这是具有 TextView 的片段
class Fragment : Fragment() {
private lateinit var txt1: TextView
public lateinit var viewModel:ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view: View = inflater.inflate(R.layout.fragment, container, false)
txt1 = view.findViewById(R.id.txt1)
viewModel = ViewModelProvider(this).get(ViewModel::class.java)
viewModel.initiateMLD()
viewModel.LD.observe(viewLifecycleOwner, Observer {
txt1.setText("Count is "+it)
})
return view
}
}
这是带有 LiveData 的 ViewModel
class ViewModel : ViewModel(){
private var clickCount:Int = 0
private var MLD = MutableLiveData<Int>()
var LD : LiveData<Int> = getMLD() // observer watches this variable
fun initiateMLD(){
MLD.value = 5
clickCount = 5
}
fun getMLD():MutableLiveData<Int>{
return MLD
}
fun changeMLD(){
clickCount+=2
MLD.value = clickCount
}
}
您正在使用 ViewModel
的 2 个不同实例。 ViewModelProvider
为您的 activity 创建一个,为您的片段创建一个。这是因为他们都是 viewModelStoreOwners。如果你想在 Fragment 和 Activity 中使用相同的 ViewModel 实例。它必须在 activity 范围内。你可以这样做
ViewModelProvider(requireActivity()).get(ViewModel::class.java)
在您的 fragment
中,您使用 fragment
作为 owner
、
创建了 viewModel
viewModel = ViewModelProvider(this).get(ViewModel::class.java)
而要与 activity
通信,您需要使用 activity
作为 owner
创建 viewModel
对象。这些被称为 sharedViewModels
.
ViewModelProvider(requireActivity()).get(ViewModel::class.java)
您可以在此 codelab 教程中阅读有关 SharedViewModel
的更多信息。
我在 Fragment 中有一个 TextView。使用 LiveData 我可以从片段中更改文本。通过使用 MainActivity 中的按钮(片段外),我试图更改 TextView 中的文本,但它不起作用。有人可以帮忙吗。这是我的代码:
这是具有按钮和片段的 MainActivity
class MainActivity : AppCompatActivity() {
var tg: ToneGenerator? = null
private lateinit var btn: Button
private lateinit var viewModel:ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tg = ToneGenerator(AudioManager.STREAM_SYSTEM, 100)
btn = findViewById(R.id.buttonTest1)
viewModel = ViewModelProvider(this).get(ViewModel::class.java)
btn.setOnClickListener {
tg?.startTone(ToneGenerator.TONE_PROP_BEEP)
viewModel.changeMLD()
}
}
}
这是具有 TextView 的片段
class Fragment : Fragment() {
private lateinit var txt1: TextView
public lateinit var viewModel:ViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view: View = inflater.inflate(R.layout.fragment, container, false)
txt1 = view.findViewById(R.id.txt1)
viewModel = ViewModelProvider(this).get(ViewModel::class.java)
viewModel.initiateMLD()
viewModel.LD.observe(viewLifecycleOwner, Observer {
txt1.setText("Count is "+it)
})
return view
}
}
这是带有 LiveData 的 ViewModel
class ViewModel : ViewModel(){
private var clickCount:Int = 0
private var MLD = MutableLiveData<Int>()
var LD : LiveData<Int> = getMLD() // observer watches this variable
fun initiateMLD(){
MLD.value = 5
clickCount = 5
}
fun getMLD():MutableLiveData<Int>{
return MLD
}
fun changeMLD(){
clickCount+=2
MLD.value = clickCount
}
}
您正在使用 ViewModel
的 2 个不同实例。 ViewModelProvider
为您的 activity 创建一个,为您的片段创建一个。这是因为他们都是 viewModelStoreOwners。如果你想在 Fragment 和 Activity 中使用相同的 ViewModel 实例。它必须在 activity 范围内。你可以这样做
ViewModelProvider(requireActivity()).get(ViewModel::class.java)
在您的 fragment
中,您使用 fragment
作为 owner
、
viewModel
viewModel = ViewModelProvider(this).get(ViewModel::class.java)
而要与 activity
通信,您需要使用 activity
作为 owner
创建 viewModel
对象。这些被称为 sharedViewModels
.
ViewModelProvider(requireActivity()).get(ViewModel::class.java)
您可以在此 codelab 教程中阅读有关 SharedViewModel
的更多信息。