I'm making my first app with Kotlin and Jetpack Compose, I’m still studying. The app, It is a meteorological application that takes the data from an API. The MainScreen starts with the data of the city of Madrid by default, and has a searchBar where you can search for any other city. My problem is that when a new city is introduced in the searchbar, this name travels to the backend and makes the calls to the API, the API responds with the new data but these never come back to the interface. The MainScreen is never updated with new data, but I can see the data on my console.
Any help in welcome, thanks in advance
MainScreen
#RequiresApi(Build.VERSION_CODES.O)
#SuppressLint("UnusedMaterialScaffoldPaddingParameter", "SimpleDateFormat")
#Composable
fun MainScreen(
MainViewModel: MainViewModel
) {
val acceso = Accesso_API()
acceso.coger_tiempo_nombre("Madrid")
while (!acceso.datos_adquiridos) {}
Log.println(Log.ASSERT, "Inicio MainScreen", acceso.resultado.toString())
Surface(
color = MaterialTheme.colors.background,
modifier = Modifier
.fillMaxHeight()
.fillMaxSize()
) {
val searchWidgetState by MainViewModel.searchWidgetState
val searchTextState by MainViewModel.searchTextState
Scaffold(
modifier = Modifier
.fillMaxSize(),
topBar = {
MainAppBar(
searchWidgetState = searchWidgetState,
searchTextState = searchTextState,
onTextChange = {
MainViewModel.updateSearchTextState(newValue = it)
},
onCloseClicked = {
MainViewModel.updateSearchWidgetState(newValue = SearchWidgetState.CLOSED)
},
onSearchClicked = {
Log.d("Searched Text", it)
MainViewModel.searchTextState.value
Log.d("searchTextState", searchTextState)
acceso.coger_tiempo_nombre(searchTextState)
},
onSearchTriggered = {
MainViewModel.updateSearchWidgetState(newValue = SearchWidgetState.OPENED)
}
)
}
) {
Column(
modifier = Modifier
.background(Color.White)
.fillMaxWidth()
.padding(20.dp)
.verticalScroll(rememberScrollState())
) {
//TARJETA PRICIPAL
Card(
modifier = Modifier
.fillMaxWidth(),
backgroundColor = GreyCard,
elevation = 0.dp,
shape = RoundedCornerShape(10.dp)
) {
WeatherDisplayDailyCard(acceso.resultado)
}
//DETALLES
Row(
modifier = Modifier
.padding(
top = 5.dp,
bottom = 0.dp
)
.align(Alignment.CenterHorizontally),
horizontalArrangement = Arrangement.SpaceBetween,
) {
DetailsItem(
details = WeatherDetails(
units = "Pressure",
data = "${acceso.resultado.presion.toString()} mb",
R.drawable.pressure,
color = GreyCard
)
)
DetailsItem(
details = WeatherDetails(
units = "Wind",
data = "${acceso.resultado.viento.toString()} km/h",
R.drawable.wind2,
color = GreyCard
)
)
}
Row(
modifier = Modifier
.padding(
top = 0.dp,
bottom = 0.dp
)
.align(Alignment.CenterHorizontally),
horizontalArrangement = Arrangement.SpaceBetween,
) {
DetailsItem(
details = WeatherDetails(
units = "UV Index",
data = acceso.resultado.uv_text.toString(),
R.drawable.rays,
color = GreyCard
)
)
DetailsItem(
details = WeatherDetails(
units = "Humidity",
data = "${acceso.resultado.humedad_relativa.toString()} %",
R.drawable.water,
color = GreyCard
)
)
}
Spacer(modifier = Modifier.height(16.dp))
//12 HORAS
var hour_1 = acceso.resultado.hora_1;
var hour_2 = acceso.resultado.hora_2;
var hour_3 = acceso.resultado.hora_3;
var hour_4 = acceso.resultado.hora_4;
var hour_5 = acceso.resultado.hora_5;
var hour_6 = acceso.resultado.hora_6;
var hour_7 = acceso.resultado.hora_7;
var hour_8 = acceso.resultado.hora_8;
var hour_9 = acceso.resultado.hora_9;
var hour_10 = acceso.resultado.hora_10;
var hour_11 = acceso.resultado.hora_11;
var hour_12 = acceso.resultado.hora_12;
val formatterHour = DateTimeFormatter.ISO_DATE_TIME
val time1: LocalTime? = LocalTime.parse(hour_1, formatterHour)
val time2: LocalTime? = LocalTime.parse(hour_2, formatterHour)
val time3: LocalTime? = LocalTime.parse(hour_3, formatterHour)
val time4: LocalTime? = LocalTime.parse(hour_4, formatterHour)
val time5: LocalTime? = LocalTime.parse(hour_5, formatterHour)
val time6: LocalTime? = LocalTime.parse(hour_6, formatterHour)
val time7: LocalTime? = LocalTime.parse(hour_7, formatterHour)
val time8: LocalTime? = LocalTime.parse(hour_8, formatterHour)
val time9: LocalTime? = LocalTime.parse(hour_9, formatterHour)
val time10: LocalTime? = LocalTime.parse(hour_10, formatterHour)
val time11: LocalTime? = LocalTime.parse(hour_11, formatterHour)
val time12: LocalTime? = LocalTime.parse(hour_12, formatterHour)
HourlyForecastSheet(
hourlyForecast = listOf(
HourlyDetails(
hour = time1.toString(),
icon = acceso.resultado.icono_hora_1,
temperature = acceso.resultado.temperatura_hora_1
),
HourlyDetails(
hour = time2.toString(),
icon = acceso.resultado.icono_hora_2,
temperature = acceso.resultado.temperatura_hora_2
),
HourlyDetails(
hour = time3.toString(),
icon = acceso.resultado.icono_hora_3,
temperature = acceso.resultado.temperatura_hora_3
),
HourlyDetails(
hour = time4.toString(),
icon = acceso.resultado.icono_hora_4,
temperature = acceso.resultado.temperatura_hora_4
),
HourlyDetails(
hour = time5.toString(),
icon = acceso.resultado.icono_hora_5,
temperature = acceso.resultado.temperatura_hora_5
),
HourlyDetails(
hour = time6.toString(),
icon = acceso.resultado.icono_hora_6,
temperature = acceso.resultado.temperatura_hora_6
),
HourlyDetails(
hour = time7.toString(),
icon = acceso.resultado.icono_hora_7,
temperature = acceso.resultado.temperatura_hora_7
),
HourlyDetails(
hour = time8.toString(),
icon = acceso.resultado.icono_hora_8,
temperature = acceso.resultado.temperatura_hora_8
),
HourlyDetails(
hour = time9.toString(),
icon = acceso.resultado.icono_hora_9,
temperature = acceso.resultado.temperatura_hora_9
),
HourlyDetails(
hour = time10.toString(),
icon = acceso.resultado.icono_hora_10,
temperature = acceso.resultado.temperatura_hora_10
),
HourlyDetails(
hour = time11.toString(),
icon = acceso.resultado.icono_hora_11,
temperature = acceso.resultado.temperatura_hora_11
),
HourlyDetails(
hour = time12.toString(),
icon = acceso.resultado.icono_hora_12,
temperature = acceso.resultado.temperatura_hora_12
),
)
)
Spacer(modifier = Modifier.height(8.dp))
//5 DIAS
Column()
{
val date_1 = acceso.resultado.fecha_dia_1
val date_2 = acceso.resultado.fecha_dia_2
val date_3 = acceso.resultado.fecha_dia_3
val date_4 = acceso.resultado.fecha_dia_4
val date_5 = acceso.resultado.fecha_dia_5
val formatterDate = DateTimeFormatter.ISO_DATE_TIME
val day_1: OffsetDateTime = OffsetDateTime.parse(date_1, formatterDate)
val day_2: OffsetDateTime = OffsetDateTime.parse(date_2, formatterDate)
val day_3: OffsetDateTime = OffsetDateTime.parse(date_3, formatterDate)
val day_4: OffsetDateTime = OffsetDateTime.parse(date_4, formatterDate)
val day_5: OffsetDateTime = OffsetDateTime.parse(date_5, formatterDate)
val date1: DayOfWeek? = LocalDate.from(day_1).dayOfWeek
val date2: DayOfWeek? = LocalDate.from(day_2).dayOfWeek
val date3: DayOfWeek? = LocalDate.from(day_3).dayOfWeek
val date4: DayOfWeek? = LocalDate.from(day_4).dayOfWeek
val date5: DayOfWeek? = LocalDate.from(day_5).dayOfWeek
Next5daysForecastItem(
Next5daysForecast(
date_5days = date1.toString(),
icon_5days = acceso.resultado.icono_dia_1,
temperature_min_5days = acceso.resultado.Temp_min_dia_1,
temperature_max_5days = acceso.resultado.Temp_max_dia_1,
icon_frase_5days = acceso.resultado.frase_dia_1,
)
)
Next5daysForecastItem(
Next5daysForecast(
date_5days = date2.toString(),
icon_5days = acceso.resultado.icono_dia_2,
temperature_min_5days = acceso.resultado.Temp_min_dia_2,
temperature_max_5days = acceso.resultado.Temp_max_dia_2,
icon_frase_5days = acceso.resultado.frase_dia_2,
)
)
Next5daysForecastItem(
Next5daysForecast(
date_5days = date3.toString(),
icon_5days = acceso.resultado.icono_dia_3,
temperature_min_5days = acceso.resultado.Temp_min_dia_3,
temperature_max_5days = acceso.resultado.Temp_max_dia_3,
icon_frase_5days = acceso.resultado.frase_dia_3,
)
)
Next5daysForecastItem(
Next5daysForecast(
date_5days = date4.toString(),
icon_5days = acceso.resultado.icono_dia_4,
temperature_min_5days = acceso.resultado.Temp_min_dia_4,
temperature_max_5days = acceso.resultado.Temp_max_dia_4,
icon_frase_5days = acceso.resultado.frase_dia_4,
)
)
Next5daysForecastItem(
Next5daysForecast(
date_5days = date5.toString(),
icon_5days = acceso.resultado.icono_dia_5,
temperature_min_5days = acceso.resultado.Temp_min_dia_5,
temperature_max_5days = acceso.resultado.Temp_max_dia_5,
icon_frase_5days = acceso.resultado.frase_dia_5,
)
)
Log.println(Log.ASSERT, "Final MainScreen", acceso.resultado.toString())
}
}
}
}
}
MainViewModel
#RequiresApi(Build.VERSION_CODES.O)
class MainViewModel : ViewModel() {
private val _searchWidgetState: MutableState<SearchWidgetState> =
mutableStateOf(value = SearchWidgetState.CLOSED)
val searchWidgetState: State<SearchWidgetState> = _searchWidgetState
private val _searchTextState: MutableState<String> =
mutableStateOf(value = "")
val searchTextState: State<String> = _searchTextState
fun updateSearchWidgetState(newValue: SearchWidgetState) {
_searchWidgetState.value = newValue
}
fun updateSearchTextState(newValue: String) {
_searchTextState.value = newValue
}
}
API_Access
class Accesso_API {
val api_key ="87EYQdAb8jlViEELJJ6KsgJGfkcKG6qu"
#RequiresApi(Build.VERSION_CODES.O)
var resultado: Datos_Tiempo = Datos_Tiempo()
var datos_adquiridos: Boolean = false
#RequiresApi(Build.VERSION_CODES.O)
fun coger_tiempo_posicion_gps(longitud: Float, latitud: Float) {
coger_datos("", longitud,latitud,"")
}
#RequiresApi(Build.VERSION_CODES.O)
fun coger_tiempo_nombre(
nombre: String,
) {
coger_datos(nombre, 0.0f,0.0f,"")
}
#RequiresApi(Build.VERSION_CODES.O)
fun coger_tiempo_key(key: String) {
coger_datos("", 0.0f,0.0f,key)
}
#RequiresApi(Build.VERSION_CODES.O)
private fun coger_datos(nombre: String, longitud: Float, latitud: Float, p_key: String) {
datos_adquiridos = false
val quotesApi = RetrofitHelper.getInstance().create(QuotesApi_Tiempo::class.java)
// launching a new coroutine
GlobalScope.launch {
var key = "308526"
var ciudad_texto = "Sevilla"
Log.println(Log.ASSERT, "", "Ciudad entregada:" + nombre)
if (nombre != "") {
Log.println(Log.ASSERT, "", "Ciudad entregada por nombre:" + nombre)
// Coger la respuesta del rest API de la consulta de localidad por nombre
var respuesta = quotesApi.get_localidad_nombre(nombre, apikey = api_key)
Log.println(Log.ASSERT, "respuesta", respuesta.toString())
// Convertir la respuesta al objeto: List<Localidad>
var ciudades = respuesta.body()
key = ciudades?.get(0)?.Key.toString()
ciudad_texto = ciudades?.get(0)?.EnglishName.toString()
Log.println(Log.ASSERT, "", key)
Log.println(Log.ASSERT, "", ciudad_texto)
}
else {
if (p_key == "") {
// Coger la respuesta del rest API de la consulta de localidad por geoposición (longitud y latitud)
var respuesta = quotesApi.get_localidad_geoposition(
q = longitud.toString() + "," + latitud.toString(),
apikey = api_key
)
// Convertir la respuesta al objeto: Localidad
var ciudad = respuesta.body()
key = ciudad?.Key.toString()
ciudad_texto = ciudad?.localizedName.toString()
} else {
key = p_key
}
}
// Coger la respuesta del rest API de la consulta de las condiciones actuales
val respuesta_cond_act = quotesApi.get_condiciones_actuales(localidad = key, apikey = api_key, details = true, metric = true)
// Convertir la respuesta al objeto: List<Condiciones>
val cond_act = respuesta_cond_act.body()
// Coger la respuesta del rest API de la consulta de la previción de 1 dia
val respuesta_prev_1day = quotesApi.get_prevision_1_dia(localidad = key, apikey = api_key, details = true, metric = true)
// Convertir la respuesta al objeto: Previccion
val prev_1day = respuesta_prev_1day.body()
// Coger la respuesta del rest API de la consulta de la previcción de 5 dias
val respuesta_prev_5d = quotesApi.get_prevision_5_dias(localidad = key, apikey = api_key, details = true, metric = true)
// Convertir la respuesta al objeto: Previccion_5dias
val prev_5d = respuesta_prev_5d.body()
// Coger la respuesta del rest API de la consulta de la previcción de 12 horas
val respuesta_prev_12h = quotesApi.get_prevision_12_horas(localidad = key, apikey = api_key, details = true, metric = true)
// Convertir la respuesta al objeto: List<Previccion_12Horas>
val prev_12h = respuesta_prev_12h.body()
resultado.ciudad = ciudad_texto
// CARTA PRICIPAL
if (cond_act?.get(0) != null) {
resultado.temperatura_actual = cond_act?.get(0)?.Temperature?.Metric?.Value
resultado.unidades_temperatura = cond_act?.get(0)?.Temperature?.Metric?.UnitType.toString()
resultado.icono = cond_act?.get(0)?.WeatherIcon
resultado.icono_frase = cond_act?.get(0)?.WeatherText
}
if (prev_1day != null) {
resultado.temperatura_maxima = prev_1day?.DailyForecasts?.get(0)?.Temperature?.Maximum?.Value
resultado.temperatura_minima = prev_1day?.DailyForecasts?.get(0)?.Temperature?.Minimum?.Value
}
// DETALLES
if (cond_act?.get(0) != null) {
resultado.presion = cond_act?.get(0)?.Pressure?.Metric?.Value
resultado.uv = cond_act?.get(0)?.UVIndex
resultado.uv_text = cond_act?.get(0)?.UVIndexText
resultado.humedad_relativa = cond_act?.get(0)?.RelativeHumidity
resultado.viento = cond_act?.get(0)?.Wind?.Speed?.Metric?.Value
resultado.direccion_viento = cond_act?.get(0)?.Wind?.Direction?.Localized
}
// 12 HORAS
if (prev_12h?.get(0) != null) {
resultado.hora_1 = prev_12h?.get(0)?.DateTime?.toString().toString()
resultado.temperatura_hora_1 = prev_12h?.get(0)?.Temperature?.Value!!
resultado.icono_hora_1 = prev_12h.get(0).WeatherIcon!!
resultado.hora_2 = prev_12h.get(1).DateTime.toString()
resultado.temperatura_hora_2 = prev_12h.get(1).Temperature?.Value!!
resultado.icono_hora_2 = prev_12h.get(1).WeatherIcon!!
resultado.hora_3 = prev_12h.get(2).DateTime.toString()
resultado.temperatura_hora_3 = prev_12h.get(2).Temperature?.Value!!
resultado.icono_hora_3 = prev_12h.get(2).WeatherIcon!!
resultado.hora_4 = prev_12h?.get(3)?.DateTime.toString()
resultado.temperatura_hora_4 = prev_12h.get(3).Temperature?.Value!!
resultado.icono_hora_4 = prev_12h.get(3).WeatherIcon!!
resultado.hora_5 = prev_12h.get(4).DateTime.toString()
resultado.temperatura_hora_5 = prev_12h?.get(4)?.Temperature?.Value!!
resultado.icono_hora_5 = prev_12h?.get(4)?.WeatherIcon!!
resultado.hora_6 = prev_12h?.get(5)?.DateTime.toString()
resultado.temperatura_hora_6 = prev_12h?.get(5)?.Temperature?.Value!!
resultado.icono_hora_6 = prev_12h?.get(5)?.WeatherIcon!!
resultado.hora_7 = prev_12h?.get(6)?.DateTime.toString()
resultado.temperatura_hora_7 = prev_12h?.get(6)?.Temperature?.Value!!
resultado.icono_hora_7 = prev_12h?.get(6)?.WeatherIcon!!
resultado.hora_8 = prev_12h?.get(7)?.DateTime.toString()
resultado.temperatura_hora_8 = prev_12h?.get(7)?.Temperature?.Value!!
resultado.icono_hora_8 = prev_12h?.get(7)?.WeatherIcon!!
resultado.hora_9 = prev_12h?.get(8)?.DateTime.toString()
resultado.temperatura_hora_9 = prev_12h?.get(8)?.Temperature?.Value!!
resultado.icono_hora_9 = prev_12h?.get(8)?.WeatherIcon!!
resultado.hora_10 = prev_12h?.get(9)?.DateTime.toString()
resultado.temperatura_hora_10 = prev_12h?.get(9)?.Temperature?.Value!!
resultado.icono_hora_10 = prev_12h?.get(9)?.WeatherIcon!!
resultado.hora_11 = prev_12h?.get(10)?.DateTime.toString()
resultado.temperatura_hora_11 = prev_12h?.get(10)?.Temperature?.Value!!
resultado.icono_hora_11 = prev_12h?.get(10)?.WeatherIcon!!
resultado.hora_12 = prev_12h?.get(11)?.DateTime.toString()
resultado.temperatura_hora_12 = prev_12h?.get(11)?.Temperature?.Value!!
resultado.icono_hora_12 = prev_12h?.get(11)?.WeatherIcon!!
}
// 5 dias
if (prev_5d != null) {
resultado.fecha_dia_1 = prev_5d?.DailyForecasts?.get(0)?.Date.toString()
resultado.frase_dia_1 = prev_5d?.DailyForecasts?.get(0)?.Day?.ShortPhrase.toString()
resultado.icono_dia_1 = prev_5d?.DailyForecasts?.get(0)?.Day?.Icon!!
resultado.Temp_max_dia_1 = prev_5d?.DailyForecasts?.get(0)?.Temperature?.Maximum?.Value!!
resultado.Temp_min_dia_1 = prev_5d?.DailyForecasts?.get(0)?.Temperature?.Minimum?.Value!!
resultado.fecha_dia_2 = prev_5d?.DailyForecasts?.get(1)?.Date.toString()
resultado.frase_dia_2 = prev_5d?.DailyForecasts?.get(1)?.Day?.ShortPhrase.toString()
resultado.icono_dia_2 = prev_5d?.DailyForecasts?.get(1)?.Day?.Icon!!
resultado.Temp_max_dia_2 = prev_5d?.DailyForecasts?.get(1)?.Temperature?.Maximum?.Value!!
resultado.Temp_min_dia_2 = prev_5d?.DailyForecasts?.get(1)?.Temperature?.Minimum?.Value!!
resultado.fecha_dia_3 = prev_5d?.DailyForecasts?.get(2)?.Date.toString()
resultado.frase_dia_3 = prev_5d?.DailyForecasts?.get(2)?.Day?.ShortPhrase.toString()
resultado.icono_dia_3 = prev_5d?.DailyForecasts?.get(2)?.Day?.Icon!!
resultado.Temp_max_dia_3 =prev_5d?.DailyForecasts?.get(2)?.Temperature?.Maximum?.Value!!
resultado.Temp_min_dia_3 = prev_5d?.DailyForecasts?.get(2)?.Temperature?.Minimum?.Value!!
resultado.fecha_dia_4 = prev_5d?.DailyForecasts?.get(3)?.Date.toString()
resultado.frase_dia_4 = prev_5d?.DailyForecasts?.get(3)?.Day?.ShortPhrase.toString()
resultado.icono_dia_4 = prev_5d?.DailyForecasts?.get(3)?.Day?.Icon!!
resultado.Temp_max_dia_4 = prev_5d?.DailyForecasts?.get(3)?.Temperature?.Maximum?.Value!!
resultado.Temp_min_dia_4 = prev_5d?.DailyForecasts?.get(3)?.Temperature?.Minimum?.Value!!
resultado.fecha_dia_5 = prev_5d?.DailyForecasts?.get(4)?.Date.toString()
resultado.frase_dia_5 = prev_5d?.DailyForecasts?.get(4)?.Day?.ShortPhrase.toString()
resultado.icono_dia_5 = prev_5d?.DailyForecasts?.get(4)?.Day?.Icon!!
resultado.Temp_max_dia_5 = prev_5d?.DailyForecasts?.get(4)?.Temperature?.Maximum?.Value!!
resultado.Temp_min_dia_5 = prev_5d?.DailyForecasts?.get(4)?.Temperature?.Minimum?.Value!!
}
datos_adquiridos = true
Log.println(Log.ASSERT, "datos_tiempo", resultado.toString())
}
}
}
DataModel
data class Datos_Tiempo #RequiresApi(Build.VERSION_CODES.O) constructor(
// Card principal
var ciudad: String? = "Cordoba",
var temperatura_actual: Double? = 18.0,
var temperatura_maxima: Double? = 12.0,
var temperatura_minima: Double? = 6.0,
var unidades_temperatura: String? = "grados",
var icono: Int? = 1,
var icono_frase: String? = "Cloudy",
// Detalles
var presion: Double? = 1020.0,
var direccion_viento: String? = "Sur",
var viento: Double? = 30.0,
var uv: Int? = 4,
var uv_text: String? = "Low",
var humedad_relativa: Double? = 50.0,
#DrawableRes val icon: Int? = R.drawable.ic_1,
val data: String? = "45",
val units: String? = "km/h",
val color: Color? = GreyCard,
//12horas
var hora_1: String = "2022-12-07T12:00:00+01:00",
var icono_hora_1: Int = 6,
var temperatura_hora_1: Double = 13.5,
var temperatura_hora_2: Double = 12.3,
var hora_2: String = "2022-12-07T13:00:00+01:00",
var icono_hora_2: Int = 12,
var temperatura_hora_3: Double = 14.3,
var hora_3: String = "2022-12-07T14:00:00+01:00",
var icono_hora_3: Int = 13,
var temperatura_hora_4: Double = 15.3,
var hora_4: String = "2022-12-07T15:00:00+01:00",
var icono_hora_4: Int = 15,
var temperatura_hora_5: Double = 13.3,
var hora_5: String = "2022-12-07T16:00:00+01:00",
var icono_hora_5: Int = 13,
var temperatura_hora_6: Double = 12.3,
var hora_6: String = "2022-12-07T17:00:00+01:00",
var icono_hora_6: Int = 12,
var temperatura_hora_7: Double = 12.3,
var hora_7: String = "2022-12-07T18:00:00+01:00",
var icono_hora_7: Int = 6,
var temperatura_hora_8: Double = 13.3,
var hora_8: String = "2022-12-07T19:00:00+01:00",
var icono_hora_8: Int = 7,
var temperatura_hora_9: Double = 11.3,
var hora_9: String = "2022-12-07T20:00:00+01:00",
var icono_hora_9: Int = 6,
var temperatura_hora_10: Double = 14.3,
var hora_10: String = "2022-12-07T21:00:00+01:00",
var icono_hora_10: Int = 6,
var temperatura_hora_11: Double = 13.3,
var hora_11: String = "2022-12-07T22:00:00+01:00",
var icono_hora_11: Int = 26,
var temperatura_hora_12: Double = 12.3,
var hora_12: String = "2022-12-07T23:00:00+01:00",
var icono_hora_12: Int = 36,
//5dias
var fecha_dia_1: String = "2022-12-07T18:00:00+01:00",
var frase_dia_1: String = "Mostly Cloudy w/ T-Storms",
var icono_dia_1: Int = 17,
var Temp_max_dia_1: Double = 12.0,
var Temp_min_dia_1: Double = 2.0,
var fecha_dia_2: String = "2022-12-08T18:00:00+01:00",
var frase_dia_2: String = "Rain",
var icono_dia_2: Int = 18,
var Temp_max_dia_2: Double = 15.0,
var Temp_min_dia_2: Double = 4.0,
var fecha_dia_3: String = "2022-12-09T18:00:00+01:00",
var frase_dia_3: String = "Flurries",
var icono_dia_3: Int = 19,
var Temp_max_dia_3: Double = 16.0,
var Temp_min_dia_3: Double = 5.0,
var fecha_dia_4: String = "2022-12-10T18:00:00+01:00",
var frase_dia_4: String = "Mostly Cloudy w/ Flurries",
var icono_dia_4: Int = 20,
var Temp_max_dia_4: Double = 14.0,
var Temp_min_dia_4: Double = 4.0,
var fecha_dia_5: String = "2022-12-11T18:00:00+01:00",
var frase_dia_5: String = "Mostly Cloudy w/ T-Storms",
var icono_dia_5: Int = 16,
var Temp_max_dia_5: Double = 16.0,
var Temp_min_dia_5: Double = 5.0,
)
Two major problems.
First, you are creating your instance of Accesso_API in the Composable, so it is recreated every time things recompose, so you end up with many copies (probably an infinite loop that will eventually crash the device with out-of-memory error), and you are always looking at a new copy who doesn't have any fetched data yet. You need to wrap it in remember { } so it is initialized only once:
val acceso = remember {
Accesso_API()
.apply { coger_tiempo_nombre("Madrid") }
}
Second, you cannot do this kind of thing in UI code:
while (!acceso.datos_adquiridos) {}
This will freeze the whole device because it blocks the main thread.
Compose is meant to be reactive. Don't wait and repeatedly poll values. Create your data property as State that the Composable uses. When the data isn't ready yet, your composable should show a loading indicator or blank screen or something.
So, in your Accesso_API class, change resultado to be MutableState, and you can use null to represent the state when no data is acquired yet:
var resultado: Datos_Tiempo? by mutableStateOf(null)
And completely delete the datos_adquiridos property and any code where you use it.
In your composable, you can get a reference to this state, and you can determine whether it is received yet by checking if it is null.
val resultado = acceso.resultado
if (resultado == null) {
// show screen with loading indicator
return
}
// the rest of your code that builds the screen using non-null resultado.
There could be other problems to fix, but you have so much code I didn't go through it all in detail.
Side note, this kind of repetitive code should be avoided:
//12horas
var hora_1: String = "2022-12-07T12:00:00+01:00",
var icono_hora_1: Int = 6,
var temperatura_hora_1: Double = 13.5,
var temperatura_hora_2: Double = 12.3,
var hora_2: String = "2022-12-07T13:00:00+01:00",
var icono_hora_2: Int = 12,
//...
Use lists or arrays instead of many similar properties! Then you can iterate things and won't have super long functions with repetitive code wherever you work with this data class.