更改字符串数据时,我的 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())
})
}
}
翻译ViewModel:
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
}
}
翻译片段:
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
中输入内容时,文本视图都会对其做出反应,而观察者并没有被在我的 MainActivity 中触发
在 Fragment 内部,您需要将
requireActivity()
传递给 ViewModelProvider 构造函数,而不是传递 this
。您传递的参数是 ViewModel 将加载的范围,因此如果它们不匹配,它们将是不同的实例。
顺便说一句,使用
by viewModels()
和片段中的 by activityViewModels()
比愚弄视图模型提供者要容易得多。