gpt4 book ai didi

android - 来自 Transformation 的数据绑定(bind) LiveData - Android Kotlin

转载 作者:IT老高 更新时间:2023-10-28 13:43:45 35 4
gpt4 key购买 nike

我正在学习 kotlin 和 android 架构组件。我有一个谷歌地图上的 map 切换按钮的简单用例。

我想使用数据绑定(bind)将 map 切换按钮标签绑定(bind)到我的 ViewModel 中的 MutableLiveData 字段。

我通过 Activity 中的 onCreate 方法在 MapViewModel 中设置 mapType val。如果我理解正确,这应该会触发 mapLabel val 由于使用 Transformations.map 而发生变化。

它不工作...为什么?

这是我的版本:

  • Android Studio 3.2 Canary 4
  • kotlin_version = '1.2.21'
  • 支持 = "27.1.0"
  • arch_core = "1.1.0"
  • 数据绑定(bind) = "3.2.0-alpha04"

MapViewModel.kt

class MapViewModel : ViewModel() {

val mapType: MutableLiveData<MapType> = MutableLiveData()

val mapLabel: LiveData<String> = Transformations.map(mapType, {
if (it == MapType.MAP) "SAT" else "MAP"
})
}

enum class MapType {
SAT, MAP
}

activity_maps.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

<variable
name="vm"
type="uk.co.oliverdelange.wcr_android_kt.ui.map.MapViewModel" />
</data>

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity">

<Button
android:id="@+id/map_toggle"
style="@style/Wcr_MapToggle"
android:layout_marginTop="110dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="7dp"
android:layout_gravity="top|end"
android:text="@{vm.mapLabel}" />
</fragment>
</FrameLayout>
</layout>

MapsActivity.kt

class MapsActivity : AppCompatActivity(), OnMapReadyCallback {

private lateinit var mMap: GoogleMap
private lateinit var viewModel: MapViewModel
private lateinit var binding: ActivityMapsBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

binding = DataBindingUtil.setContentView(this, R.layout.activity_maps)
viewModel = ViewModelProviders.of(this).get(MapViewModel::class.java)
binding.vm = viewModel

val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)

// I can do it this way, but I don't want to.
// viewModel.mapLabel.observe(this, Observer { map_toggle.text = it })

// Here is where i'm setting the MapType on the ViewModel.
viewModel.mapType.value = MapType.MAP
}

override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
}
}

我已经使用 MutableLiveData 对象测试了绑定(bind),我在该对象中设置了 Activity 中的字符串,它工作正常。问题似乎出在 Transformations.map 上——我是不是理解错了?

另外,在调试时,我发现我的 ViewModel 中的 mapType val 没有观察者(不确定这是对还是错,只是很有趣)

最佳答案

这里的问题是,尽管绑定(bind)到 mapLabel 字段,但当 mapLabel 字段的值更改时, View 绑定(bind)并未更新。

原因是我没有在绑定(bind)上设置生命周期所有者。

binding.setLifecycleOwner(this)

阅读this blog post后我意识到我的错误第 10 次。

我的新 MapsActivity.kt

class MapsActivity : AppCompatActivity(), OnMapReadyCallback {

private lateinit var mMap: GoogleMap
private lateinit var viewModel: MapViewModel
private lateinit var binding: ActivityMapsBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

binding = DataBindingUtil.setContentView(this, R.layout.activity_maps)
binding.setLifecycleOwner(this) //<- NEW!
viewModel = ViewModelProviders.of(this).get(MapViewModel::class.java)
binding.vm = viewModel

val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)

// Here is where i'm setting the MapType on the ViewModel.
viewModel.mapType.value = MapType.MAP
}

override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
}
}

从好的方面来说,我学到了很多关于 LiveData 内部工作原理的知识!

关于android - 来自 Transformation 的数据绑定(bind) LiveData - Android Kotlin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49551851/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com