Android Fragments 当片段中的数据发生更改时,主活动中未触发LiveData Observer

xurqigkl  于 9个月前  发布在  Android
关注(0)|答案(1)|浏览(98)

当字符串数据被更改时,我的MainActivity中的观察者不会被触发
以下是我的主要活动:

package com.example.translator

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log

import android.widget.EditText
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.example.translator.databinding.ActivityMainBinding;
import com.example.translator.databinding.FragmentTranslateBinding
import com.example.translator.viewmodellivedata.TranslateViewModel

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var viewModel: TranslateViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding =ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        binding.translateText.text = "translation.."


        viewModel = ViewModelProvider(this).get(TranslateViewModel::class.java)
        viewModel.currentWord().observe(this, Observer {
            binding.translateText.text = it.toString()
            Log.d("current", it.toString())
        })



    }


}

TranslateViewModel:

package com.example.translator.viewmodellivedata

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.LiveData

class TranslateViewModel : ViewModel() {
    private var _currentWord = MutableLiveData<String>()

    fun currentWord(): LiveData<String> {
        return _currentWord
    }

    fun setCurrentWord(word: String) {
        _currentWord.value = word
    }



}

TranslateFragment:

package com.example.translator

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.text.TextWatcher
import android.text.Editable
import android.view.View
import android.view.ViewGroup
import android.util.Log
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.example.translator.databinding.FragmentTranslateBinding
import com.example.translator.viewmodellivedata.TranslateViewModel

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [translateFragment.newInstance] factory method to
 * create an instance of this fragment.
 */
class translateFragment : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null
    private var _binding: FragmentTranslateBinding? = null  // View Binding instance
    private val binding get() = _binding!!
    private lateinit var  viewModel: TranslateViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentTranslateBinding.inflate(inflater, container, false)
        val view = binding.root

        viewModel = ViewModelProvider(this).get(TranslateViewModel::class.java)

        binding.editText.hint = "Write something..."



        // Add a TextWatcher to the EditText
        binding.editText.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                // This method is called before text is changed
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                // This method is called as text is changing
            }

            override fun afterTextChanged(s: Editable?) {
                // This method is called after text has changed
                val enteredText = s.toString()
                //binding.editText.setText(enteredText)
                //binding.translateText.text

                viewModel.setCurrentWord(enteredText)
                //viewModel.currentWord().observe(viewLifecycleOwner, Observer { word ->
                //    // This code will execute when the LiveData value changes
                ///    Log.d("current", word.toString())
               // })




                // Reattach the TextWatcher


                // You can perform translation or any other actions here with the enteredText
            }
        })

            //val view = binding.root

        //viewModel = ViewModelProvider(this).get(TranslateViewModel::class.java)
        return view
    }
    override fun onDestroyView() {
        super.onDestroyView()
        _binding = nul
l
    }

    companion object {
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment translateFragment.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            translateFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }

我试图让TextView显示用户在使用实时数据观察器的片段editview中键入的内容,但每次我在edittext中键入内容时,textview都会重新执行它,并且观察器不会在我的MainActivity中触发

bfrts1fy

bfrts1fy1#

在Fragment内部,您需要将requireActivity()传递给ViewModelProvider构造函数,而不是传递this。你传递的参数是ViewModel将被加载到哪个作用域,所以如果它们不匹配,它们将是不同的示例。
顺便说一下,使用by viewModels()和片段中的by activityViewModels()要容易得多,而不是愚弄视图模型提供程序。

相关问题