【问题标题】:ViewModel not updating with data changeViewModel 不随数据更改而更新
【发布时间】:2019-12-09 12:59:03
【问题描述】:

所以,这是我第一次在 Android 中使用架构组件。我正在尝试创建一个 ViewModel,它将不断返回 UI 元素可以使用的最新位置。我创建了一个这样的视图模型:

    class LocationViewModel(application: Application) : AndroidViewModel(application) {
        val currentLocation = MutableLiveData<Location?>()

        init {
            val ctx = getApplication<Application>().applicationContext
            val fusedLocationProvider = LocationServices.getFusedLocationProviderClient(ctx)

            val locationRequest = LocationRequest.create()
            locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
            locationRequest.interval = 5000
            locationRequest.fastestInterval = 2000

            val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
            val client = LocationServices.getSettingsClient(ctx)

            client.checkLocationSettings(builder.build()).addOnFailureListener {
                currentLocation.postValue(null)
            }

            val locationCallback = object : LocationCallback() {
                override fun onLocationResult(p0: LocationResult?) {
                    super.onLocationResult(p0)
                    p0 ?: return
                    currentLocation.postValue(p0.lastLocation)
                }
            }

            fusedLocationProvider.requestLocationUpdates(
                locationRequest,
                locationCallback,
                Looper.getMainLooper()
            )
        }
    }

我在一个活动中观察到这个 ViewModel,就像这样

    class MainActivity : AppCompatActivity() {
        private lateinit var locationText: TextView

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)

            locationText = findViewById(R.id.locationText)

            val location = ViewModelProviders.of(this)[LocationViewModel::class.java]
            location.currentLocation.observe(this, Observer { resutlLocation: Location? ->
                locationText.text =
                    if (resutlLocation != null) "Lat: ${resutlLocation.latitude} Long: ${resutlLocation.longitude}" else "Null"
            })
        }
    }

TextView 甚至不会更新一次。像这样的事情应该怎么做?我究竟做错了什么?

【问题讨论】:

  • 是否调试过currentLocation.postValue(p0.lastLocation) 是否被调用?
  • 我没有,但我认为它没有被调用
  • 可能是问题,换成不同的数据输入验证

标签: android kotlin mvvm observable


【解决方案1】:

在视图视图模型中创建这样的函数。

fun initdata() {

    val ctx = getApplication<Application>().applicationContext
    val fusedLocationProvider = LocationServices.getFusedLocationProviderClient(ctx)

    val locationRequest = LocationRequest.create()
    locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
    locationRequest.interval = 5000
    locationRequest.fastestInterval = 2000

    val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
    val client = LocationServices.getSettingsClient(ctx)

    client.checkLocationSettings(builder.build()).addOnFailureListener {
        currentLocation.postValue(null)
    }

    val locationCallback = object : LocationCallback() {
        override fun onLocationResult(p0: LocationResult?) {
            super.onLocationResult(p0)
            p0 ?: return
            currentLocation.postValue(p0.lastLocation)
        }
    }

    fusedLocationProvider.requestLocationUpdates(
        locationRequest,
        locationCallback,
        Looper.getMainLooper()
    )
}

然后像这样使用

  val viewModel = ViewModelProviders.of(this)[LocationViewModel::class.java]
  viewModel.initdata()

编辑 1

你可以像这样延迟初始化

private val users:MutableLiveData<Location?> by lazy {
    MutableLiveData().also {
      initdata()
    }
}

更多详情请参考ViewModel

【讨论】:

  • 这看起来很hacky,文档说当我们需要ViewModel中的上下文时使用AndroidViewModel。
  • 这种情况你可以使用编辑答案
猜你喜欢
  • 1970-01-01
  • 2016-08-16
  • 1970-01-01
  • 2019-08-14
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 2014-10-06
相关资源
最近更新 更多