我正在尝试构建一个天气应用程序,所以我使用mvvm结构,我正在使用位置服务来获取当前位置,我正在viewModel中获取位置,但它没有在屏幕上更新,当我直接在mainactivity上使用位置服务时,它正在显示结果,但一旦我在另一个类中定义了相同的功能,ui就没有更新。
下面是代码
MainActicity.kt
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var binding:ActivityMainBinding
private lateinit var weatherModel:WeatherViewModel
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
// private var latitude:Double = 00.00
// private var longitude:Double = 00.00
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
weatherModel = ViewModelProvider(this)[WeatherViewModel::class.java]
// Log.d("weatherModel","${weatherModel.weatherResp}")
// Log.d("longi","$longitude")
// weatherModel.getWeather(latitude,longitude)
//accessing location from viewModel
if(weatherModel.fetchLocation()){
ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),101)
return
}
weatherModel.weatherResp.observe(this){
weather->
binding.apply {
tvDescription.text = weather.weather[0].description
livelocation.setOnClickListener {
Toast.makeText(this@MainActivity, "this is rohit", Toast.LENGTH_SHORT).show()
}
tvWind.text = weather.wind.speed.toString() + " Km/h"
humidity.text = weather.main.humidity.toString()
val tempInC = weather.main.temp - 273.15
val number3digits:Double = (tempInC * 1000.0).roundToInt() / 1000.0
tvTemperature.text = number3digits.toString()
visibility.text = weather.visibility.toString()
//
}
}
}
// private fun fetchLocation(){
// val task = fusedLocationProviderClient.lastLocation
// if(ActivityCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_FINE_LOCATION)
// !=PackageManager.PERMISSION_GRANTED &&
// ActivityCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_COARSE_LOCATION)
// !=PackageManager.PERMISSION_GRANTED
// ){
// ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),101)
// return
// }
// task.addOnSuccessListener {
// if(it!=null){
// latitude=it.latitude
// longitude= it.longitude
// weatherModel.getWeather(latitude,longitude)
// Log.d("longi","$longitude")
// val address = getAddressName(it.latitude,it.longitude)
// binding.tvCityName.text = address
// }
// }
//
// }
// private fun getAddressName(lat:Double,long:Double):String{
// Log.d("lat", lat.toString())
// var addressName = " "
// val geoCoder = Geocoder(this, Locale.getDefault())
// val address = geoCoder.getFromLocation(lat,long,1)
// if (address != null) {
// addressName = address[0].subAdminArea
// }
// Log.d("Address", address.toString())
// Log.d("subadmin",addressName.toString())
// return addressName
//
// }
//
//
// private fun getCoordinates(cord:String){
// var city = binding.locationQuery.text.toString()
//// val geocodeListener = Geocoder.GeocodeListener { addresses ->
//// addresses[0]
//// }
// val geocoder = Geocoder(this,Locale.getDefault())
// val address = geocoder.getFromLocationName(city,2)
// val result = address?.get(0)
//
//
// }
}
WeatherViewModel.kt
@HiltViewModel
class WeatherViewModel @Inject constructor(
private val repo:WeatherRepository,
private val application: Application,
private val fusedLocationProviderClient: FusedLocationProviderClient
) :ViewModel(){
private var getLatitude: Double = 00.00
private var getLongitude: Double = 00.00
private val _resp = MutableLiveData<WeatherDTO>()
val weatherResp:LiveData<WeatherDTO>
get() = _resp
private val _cord = MutableLiveData<Coord>()
val cord:LiveData<Coord>
get() = _cord
// init {
// check()
// getWeather(getLatitude,getLongitude)
// }
fun getWeather(latitude:Double,longitude:Double) =
viewModelScope.launch {
repo.getWeather(latitude,longitude).let { response->
if(response.isSuccessful){
_resp.postValue(response.body())
}else{
Log.d("Weather Error","getWeather Error Response: ${response.message()}")
}
}
}
fun fetchLocation():Boolean{
val task = fusedLocationProviderClient.lastLocation
if(ActivityCompat.checkSelfPermission(application,android.Manifest.permission.ACCESS_FINE_LOCATION)
!=PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(application,android.Manifest.permission.ACCESS_COARSE_LOCATION)
!=PackageManager.PERMISSION_GRANTED
){
return true
}
task.addOnSuccessListener {
if(it!=null){
// latitude=it.latitude
// longitude= it.longitude
getWeather(it.latitude,it.longitude)
// Log.d("lati","${it.latitude}")
// Log.d("longimaa","${it.longitude}")
// val address = getAddressName(it.latitude,it.longitude)
// _cord.postValue(it.latitude,it.longitude)
// binding.tvCityName.text = address
}
}
return true
}
private fun fetchLocationDetails(){
}
private fun getAddressName(lat:Double,long:Double):String{
Log.d("lat", lat.toString())
var addressName = " "
val geoCoder = Geocoder(application, Locale.getDefault())
val address = geoCoder.getFromLocation(lat,long,1)
if (address != null) {
addressName = address[0].subAdminArea
}
Log.d("Address", address.toString())
Log.d("subadmin",addressName.toString())
return addressName
}
}
我正在尝试,屏幕结果得到更新
binding.livelocation.setOnClickListener {
if(weatherModel.fetchLocation()){
ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),101)
}
}
但是仍然不知道这是如何工作的,当放在这个按钮侦听器之外时,它不是