我创建了一个私人阀:
// Location data
private val _selectedLocations = MutableLiveData<LocationData?>(null)
val selectedLocations: LiveData<LocationData?> = _selectedLocations
I创建了一个调用位置的新屏幕:
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun LocationScreens(
locationsHiltViewModel: LocationsHiltViewModel,
) {
var loadingAnim by remember { mutableStateOf(false) }
val locationData = selectedLocations.value
locationData?.let { existingLocation ->
locationsHiltViewModel.locations.collectAsState(initial = NetworkResult.Loading).value.let { response ->
when(response) {
is NetworkResult.Loading -> {
loadingAnim = true
}
is NetworkResult.Success -> {
loadingAnim = false
Locations(
locationData = LocationData()
)
}
is NetworkResult.Error -> {
loadingAnim = false
Toast.makeText(
LocalContext.current,
response.message,
Toast.LENGTH_LONG
).show()
}
}
}
LoadingAnim(loadingAnim)
} ?: run {
NoLocationsMatch()
}
}
LocationsHiltViewModel:获取Repo!
的所有数据
@HiltViewModel
class LocationsHiltViewModel @Inject constructor(
private val repo: Repo
) : ViewModel() {
private val _locations = MutableStateFlow<NetworkResult<List<LocationData>>>(NetworkResult.Loading)
val locations : StateFlow<NetworkResult<List<LocationData>>> get() = _locations
init {
fetchLocations()
}
fun fetchLocations() {
viewModelScope.launch {
try {
_locations.value = NetworkResult.Loading
val response = repo.getLocationData()
if (response.isSuccessful) {
response.body()?.let { locations ->
_locations.value = NetworkResult.Success(locations)
} ?: run {
_locations.value = NetworkResult.Success(listOf())
Log.d("Locations 1", "Response body is null")
}
} else {
_locations.value = NetworkResult.Error(response.message())
Log.d("Locations 2", "Error: ${response.code()} ${response.message()}")
}
} catch (e: Exception) {
_locations.value = NetworkResult.Error(e.message.toString())
Log.d("Location 3", "Exception: ${e.message.toString()}")
}
}
}
}
LocationsCreen:
@Composable
fun Locations(
locationData: LocationData?
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.Black)
) {
Box(
modifier = Modifier
.fillMaxWidth()
.background(Color.Black)
.padding(top = 30.dp)
) {
Column(
modifier = Modifier
.padding(10.dp)
.fillMaxWidth()
.background(Color.Black)
) {
LazyVerticalGrid(
columns = GridCells.Fixed(2), // 2 columns in the grid
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(8.dp)
) {
locationData?.let { location ->
items(3) {
LocationItems(
id = location.id,
locationName = location.locationname,
lng= location.lng,
lat= location.lat
)
}
}
}
}
}
}
}
@Composable
private fun LocationItems(
id: Int?,
locationName: String?,
lng: Double?,
lat: Double?,
) {
Box(
modifier = Modifier
.padding(10.dp)
.fillMaxWidth()
.background(Color.Black, shape = RoundedCornerShape(12.dp))
.padding(10.dp),
contentAlignment = Alignment.CenterStart
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.Start
) {
id?.let { Text(text = "ID: $it") }
locationName?.let { Text(text = "Location Name: $it") }
lng?.let { Text(text = "lng: $it") }
lat?.let { Text(text = "lat: $it") }
}
}
}
确定发现的位置
从
NoLocationsMatch
composable出现,当您查看该条件时,问题就会很清楚:
locationData
必须为null。现在,这开始为空,而且由于它从未改变,因此没有其他任何东西都不会显示出
NoLocationsMatch()
如果您不想要它,然后将其删除。我不明白为什么您什至需要selectedLocations
,即使有原因不应该是livedata,它应该是utableState(当它位于可合数的时候)或mutableStateFlow(当它位于utableStateFlow时)在视图模型中)。使用作曲时不再需要Livedata。
现在您看不到找到的位置了,而是看到了黑屏。那是因为,您画了
我不知道这是什么原因,但是仅仅是为了实际看到的目的但是,即使您现在可以看到现在,这并不是从视图模型检索到的位置,因为您只需在检索它们的那一刻就把它们扔掉。您没有将它们传递到您的
Color.Black
composable,而是创建一个新的空对象并通过该对象。您真正想要的是传递
Color.White
的内容。可能构成下一个问题,因为其中包含一个Locations
LocationData()
composable(尽管其复数名称)仅接受一个Singlelocationdata对象。
韦尔,你可以从那里去。现在应该解决视图模型中无法看到的最初问题。