你如何观察片段外的 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 的更多信息。