LiveData Transformation未被触发

时间:2018-03-16 14:06:46

标签: android-room android-livedata

我订阅了ui中的idssearch,但我没有得到任何结果,所以我逐步调试,发现转换没有在第一次触发后触发。因此,当我第一次setIds更新ids时,但是对于第一次调用后的每次调用,转换都不会触发。同样适用于search

任何想法可能出错?

class MyViewModel : ViewModel() {

    private val repository = Repository.sharedInstance

    var recentRadius: LiveData<List<RecentRadius>>?
    var recentRoute: LiveData<List<RecentRoute>>?

    init {
        recentRadius = repository.recentRadius()
        recentRoute = repository.recentRoute()
    }


    private val idsInput = MutableLiveData<String>()
    fun setIdsInput(textId: String) {
        idsInput.value = textId
    }

    val ids: LiveData<List<String>> = Transformations.switchMap(idsInput) { id ->
        repository.ids(id)
    }

    private val searchInput = MutableLiveData<Search>()
    fun setSearchInput(search: Search) {
        searchInput.value = search
    }


    val search: LiveData<SearchResult> = Transformations.switchMap(searchInput) { search ->
        when (search.type) {
            SearchType.ID -> repository.id(search)
            SearchType.RADIUS -> repository.radius(search)
            SearchType.ROUTE -> repository.route(search)
        }
    }
}

3 个答案:

答案 0 :(得分:14)

转换未被触发的最常见原因是因为没有Observer观察它或输入LiveData没有被更改。

答案 1 :(得分:0)

下面的示例说明了将观察者附加到活动中时对地图的使用。

活动

class MainActivity : AppCompatActivity() {

lateinit var mBinding : ActivityMainBinding

private val mViewModel : MainViewModel by lazy {
   getViewModel { MainViewModel(this.application) }
}

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
   mBinding.vm = mViewModel

   // adding obeserver
   mViewModel.videoName.observe(this, Observer<String> { value ->
       value?.let {
           //Toast.makeText(this, it, Toast.LENGTH_LONG).show()
       }
   })
 }
}

ViewModel 与地图

class MainViewModel(val appContext : Application) : AndroidViewModel(appContext) {

   private val TAG = "MainViewModel"

   var videoData = MutableLiveData<VideoDownload>()
   var videoName : LiveData<String>

   init {
      // Update the data
      videoName = Transformations.map(videoData) { "updated : "+it.webUrl }
    }

    fun onActionClick(v : View) {
       // change data
       videoData.value = VideoDownload(System.currentTimeMillis().toString())
    }

    fun onReActionClick(v : View) {
       // check data
       Toast.makeText(appContext, videoName.value, Toast.LENGTH_LONG).show()
    }

}

ViewModel 和switchMap

class MainViewModel(val appContext : Application) : AndroidViewModel(appContext) {

    private val TAG = "MainViewModel"

    var videoData = MutableLiveData<VideoDownload>()
    var videoName : LiveData<String>

    init {
       // Update the data
       videoName = Transformations.switchMap(videoData) { modData(it.webUrl) }

    }

    private fun modData(str: String): LiveData<String> {
        val liveData = MutableLiveData<String>()
        liveData.value = "switchmap : "+str
        return liveData
    }

    fun onActionClick(v : View) {
        // change data
        videoData.value = VideoDownload(System.currentTimeMillis().toString())
    }

    fun onReActionClick(v : View) {
        // check data
        Toast.makeText(appContext, videoName.value, Toast.LENGTH_LONG).show()
    }

}

答案 2 :(得分:0)

对我来说,这是因为观察者所有者是一个碎片。导航到不同片段时,它停止触发。我将观察者所有者更改为活动,并按预期触发了该事件。

itemsViewModel.items.observe(requireActivity(), Observer {

视图模型被定义为类属性:

    private val itemsViewModel: ItemsViewModel by lazy {
    ViewModelProvider(requireActivity()).get(ItemsViewModel::class.java)
}