1

I want to fetch some json data, see in the image the green arrow:

enter image description here

The problem is that Android Studio doesn't let me get the data I want. It stops until a step before (I think). In my adapter class check:

holder?.view?.textWeather?.text = weatherFor.weather.toString()

Also it shows me in the emulator the red arrow, what is this?

Below is my main Activity's json method with the classes i want to fetch data for, and the associated Adapter class.

Main Activity

fun fetchJson() {
     val url="https://api.openweathermap.org/data/2.5/forecast?q=Prague,CZ&appid=4cf7f6610d941a1ca7583f50e7e41ba3"
     val request=Request.Builder().url(url).build()
     val client= OkHttpClient()
     client.newCall(request).enqueue(object :Callback {

         override fun onResponse(call: Call?, response: Response?) {
             val body=response?.body()?.string()
             println(body)

             val gson=GsonBuilder().create()

             val forecastfeed=gson.fromJson(body,ForecastFeed::class.java)

             runOnUiThread{
                 recyclerView_main.adapter=MainAdapter(forecastfeed)
             }
         }

         override fun onFailure(call: Call?, e: IOException?) {
             println("Failed to execute request")
         }
     })
}

class ForecastFeed(val list:List<ForecastWeatherList>) { }

class ForecastWeatherList(val weather:List<WeatherData>) { }

class WeatherData(val main:String,val icon:String) { }

Adapter

class MainAdapter(val forecastfeed: ForecastFeed): RecyclerView.Adapter<CustomViewHolder>() {

    val forecastWeather = listOf<String>("First","Second")

    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
        val weatherFor = forecastfeed.list.get(position)
        holder?.view?.textWeather?.text = weatherFor.weather.toString()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder{
        //how do we even create a view
        val layoutInflater =LayoutInflater.from(parent?.context)
        val cellForRow=layoutInflater.inflate(R.layout.weather_row,parent,false)
        return CustomViewHolder(cellForRow)
    }    

    override fun getItemCount(): Int {
        return forecastfeed.list.count()
    }
}

class CustomViewHolder(val view: View):RecyclerView.ViewHolder(view) { }

2 Answers 2

2

You can format the data manually

holder?.view?.textWeather?.text = "weather ${weatherFor.weather.map{it.main}.joinToString(", ")}"

or use data classes

Sign up to request clarification or add additional context in comments.

4 Comments

I think the OP should not use either manual formatting or data classes, but both of them: WeatherData looks like a simple data container, so a data class would perfectly fit the use case. Also, I think manual formatting is better than overriding toString, since the latter should be used to return "a string representation of the object", not something specific to a specific use case
it still gives me an error on the "main" word "Unresolved reference main"
weatherFor.weather is a collection of WeatherData objects, you can iterate over it. for example: holder?.view?.textWeather?.text ="weather ${weatherFor.weather.map{it.main}.joinToString(", ")}"
@akaki Thank you so much!!(If you want edit your post and put the answer you gave me now on it!)
0

You need to overwrite WeatherData.toString() to have a hand on what's displayed.

class WeatherData(val main:String,val icon:String) {

    override fun toString(): String {
        return "$main $icon"
    }

}

Further more you should use a RecyclerView with a ViewHolder to handle properties one-by-one and enable more complex layouts. If needed.

1 Comment

Ok but how can i get only the main or only the icon??

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.