无法在视图模型中增加计数器变量



我有一个应用程序,我将视图模型绑定到主活动生命周期,并且我确实根据调用的生命周期增加了一个计数器,但我无法增加计数器变量,不管是什么原因,谢谢

  • 这是我的视图模型类
class CounterViewModel : ViewModel(), DefaultLifecycleObserver {

private var onCreateCounter = 0
private var onStartCounter = 0
private var onResumeCounter = 0

// This class defines the ViewModel which keeps track of the number of times onCreate(), onStart() and onResume() have been called.
companion object {
private const val TAG = "CounterViewModel"
}
// TODO :
// Create variables to keep a track of the number of times onCreate(), onStart() and onResume() have been called.
// To keep track of each count, define two variables as specified below.
// Define a private variable of type MutableLiveData that can only be modified within the ViewModel class.
// Define an internal/public variable of type LiveData that can be accessed externally by the UI/fragment but cannot be modified.
// Use a backing property to specify the getter function for the internal/public variable
// Refer to the link below for a more detailed explanation/example
// https://developer.android.com/codelabs/basic-android-kotlin-training-viewmodel#4
private val _onStartMutableLiveData  : MutableLiveData<Int> = MutableLiveData(onStartCounter)
val onStartLiveData : LiveData<Int> get() = _onStartMutableLiveData
private val _onCreateMutableLiveData  : MutableLiveData<Int> = MutableLiveData(onCreateCounter)
val onCreateLiveData : LiveData<Int> get() = _onCreateMutableLiveData
private val _onResumeMutableLiveData  : MutableLiveData<Int> = MutableLiveData(onResumeCounter)
val onResumeLiveData : LiveData<Int> get() = _onResumeMutableLiveData

val onCreateProperty : LiveData<Int>
get()  {
return onCreateLiveData
}
val onStartProperty : LiveData<Int>
get()  {
return onStartLiveData
}
val onResumeProperty : LiveData<Int>
get()  {
return onResumeLiveData
}

internal fun bindToActivityLifecycle(mainActivity: MainActivity) {
// TODO :
// Add the current instance of CounterViewModel as a LifeCycleObserver to the MainActivity
// Use the addObserver function
mainActivity.lifecycle.addObserver(this)
}

override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
// Update the appropriate count variable
Log.i(TAG,"Entered onResume")
onResumeCounter++
_onResumeMutableLiveData.value = onResumeCounter
}
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
// Update the appropriate count variable
Log.i(TAG,"Entered onCreate")
onCreateCounter++
_onCreateMutableLiveData.value = onCreateCounter
}

override fun onStart(owner: LifecycleOwner) {
super.onStart(owner)
// Update the appropriate count variable
Log.i(TAG,"Entered onStart")
onStartCounter++
_onStartMutableLiveData.value = onStartCounter
}
}

**片段代码

class FirstFragment : Fragment() {
/** Binding to XML layout */
private lateinit var binding: FirstFragmentBinding
// Create a variable of type CounterViewModel to keep track of counts
private lateinit var viewModel: CounterViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Use the provided binding object to inflate the layout.
binding = FirstFragmentBinding.inflate(inflater, container, false)
// Update ActionBar label to distinguish which Fragment is displayed
(requireActivity() as AppCompatActivity).supportActionBar?.title = this.javaClass.simpleName
// Set onClickListener to navigate to the second fragmant from the first
binding.fab.setOnClickListener {
findNavController().navigate(FirstFragmentDirections.actionFirstFragmentToSecondFragment())
}
// Return the root view.
return binding.root
}
@SuppressLint("SetTextI18n")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// TODO:
// Initialize CounterViewModel instance
viewModel = ViewModelProvider(this)[CounterViewModel::class.java]
// TODO:
// Use binding to display initial counts
binding.onCreate.text = "onCreate Called : ${viewModel.onCreateLiveData.value}"
binding.onStart.text = "onStart Called : ${viewModel.onStartLiveData.value}"
binding.onResume.text = "onResume Called : ${viewModel.onResumeLiveData.value}"
// The function below updates the counts over time
beginObservingCounter()
}
@SuppressLint("SetTextI18n")
private fun beginObservingCounter() {
// TODO:
// Register observers for each of the count variables
// In the body of the observe function, update the text to be displayed by using the binding
viewModel.onStartLiveData.observe(viewLifecycleOwner){ counter ->
binding.onStart.text = "onStart Called Again $counter"
}
viewModel.onCreateLiveData.observe(viewLifecycleOwner){ counter ->
binding.onCreate.text = "onCreate Called Again $counter"
}
viewModel.onResumeLiveData.observe(viewLifecycleOwner){ counter ->
binding.onResume.text = "onResume Called Again $counter"
}
}
}

您在评论中提到,当您旋转时,会调用init块-哪个init块?旋转屏幕应该会给你一个相同的ViewModel实例,它的所有状态都完好无损,这就是它们的重点。也许你初始化它们的方式不对,也许你创建了另一个副本,并从中观察LiveData,而不是实际观察你生命周期并递增的实例?

值得一提的是,你的代码在这样的Activity中对我来说很好:

val counterViewModel: CounterViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
counterViewModel.bindToActivityLifecycle(this)
// onResumeProperty works too since it's the same thing!
counterViewModel.onResumeLiveData.observe(this) { count ->
Toast.makeText(this, "Resumes: $count", Toast.LENGTH_SHORT).show()
}
}

每次onResume发生时,我都会得到一个Toast——从技术上讲,这种情况发生得更频繁,因为它在旋转时首先观察旧数据,然后在再次点击onResume时获得新值,但它确实有效!所以我会确保你处理正确的实例

因此,虽然operator fun inc()的定义用于++,但它们不起相同的作用,0.inc()有效,而0++无效。事实证明,inc所做的只是返回值加1(请参阅文档(,++调用inc,但也设置新值。因此,您可以更改为使用++或进行onStartCounter = onStartCounter.inc()

相关内容

  • 没有找到相关文章

最新更新