【问题标题】:How to avoid call observe() twice?如何避免两次调用observe()?
【发布时间】:2021-12-14 13:45:57
【问题描述】:

我在函数中有一个观察者。我首先在我的活动onCreate() 中调用此函数,它工作正常。之后,当我再次调用此函数时,我的观察者内部的代码被调用了两次。如何防止这种行为?

这是我的观察者功能

private lateinit var word: String

fun addViews() {

    viewModel.getQuestion()

    viewModel.questionResponse.observe(this, { it ->
        this.word = it.data.word

            createAnswerTextView(this.word.length)

        }
    })
}

编辑:

我想做的是通过在这些步骤中删除和添加视图来刷新布局。

  1. 创建与字长一样长的文本视图。 (addViews() 为我做)
  2. 删除这些视图。
  3. 只要有新的单词长度,就可以再次创建文本视图。 ( addViews() 为我做)

我无法在活动的onCreate() 方法中只创建一次观察者。因为我需要多次使用 addViews 函数及其观察者。

viewModel.questionResponse.removeObservers(this) 也没有用。

但是在我删除文本视图并清除属性值的函数中添加 viewModel.questionResponse = MutableLiveData() 解决了我的问题。

【问题讨论】:

  • 只是不调用它两次..
  • 或者留下一些已经观察到的标志
  • 您应该在 Activity 的 onCreate() 方法中只调用一次 viewModel.questionResponse.observe(...)
  • 你不应该在一个被多次调用的函数中开始观察

标签: android kotlin mvvm android-livedata observers


【解决方案1】:

如果您在片段中工作,则必须在“onViewCreated”中定义观察者,如果在活动中工作,则必须在 onCreateView 中定义。

此外,在您的片段中,您应该将您的视图模型定义为:

val yourviewModel by activityViewModels<YourViewModel>()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        yourviewModel.yourVariable.observe(viewLifecycleOwner) {
          // some function to do
        }
}

在你的活动中:

val yourviewModel by viewModels<YourViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        yourviewModel.yourVariable.observe(this) {
          // some function to do
        }
}

如果你不想这样做,还有另一种方法,就是移除所有的观察者:

fun addViews() {

    viewModel.getQuestion()

    // add this line
    viewModel.questionResponse.removeObservers(this)
    viewModel.questionResponse.observe(this, { it ->
        this.word = it.data.word

            createAnswerTextView(this.word.length)

        }
    })
}

【讨论】:

    【解决方案2】:

    始终在活动中调用onCreate 内部的观察者。每次调用 addViews() 函数时,您都在注册您的观察者。只需将以下代码移至 onCreate 内部

    viewModel.questionResponse.observe(this, { it ->
            this.word = it.data.word
    
                createAnswerTextView(this.word.length)
    
            }
        })
    

    【讨论】:

      【解决方案3】:

      获取数据后你应该调用 viewModel?.getData()?.removeObservers(this)

      【讨论】:

      • Mosayeb Masoumi,虽然这段代码 sn-p 可能会解决问题,但它没有解释为什么或如何回答问题。请include an explanation for your code,因为这确实有助于提高您的帖子质量。
      猜你喜欢
      • 2011-01-11
      • 1970-01-01
      • 2021-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-20
      • 1970-01-01
      • 2021-10-16
      相关资源
      最近更新 更多