Reputation: 175
I am trying to "dynamically" create CardView and then fill TextView with data from an API call. The thing is, to me it seems like the request is not getting called.
I created an adapter class based on Create dynamically lists with RecyclerView which is working fine and I am adding as many windows as needed. And then in the MainActivity, I am trying to do an API request with Volley. Before I created manually TextView and fed the results manually into it - which worked fine. But now with this dynamically created CardView nothing is happening. Could anyone try to guide me please?
MainActivity:
class MainActivity : AppCompatActivity() {
// private var message: TextView = findViewById<TextView>(R.id.jsonParse)
lateinit var weatherRV: RecyclerView
lateinit var weatherModelArray: ArrayList<WeatherViewModel>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar?.hide()
weatherRV = findViewById(R.id.mainView)
weatherModelArray = ArrayList()
val model1 = WeatherViewModel("Open weather", "")
val model2 = WeatherViewModel("Yr.no", "")
weatherModelArray.add(model1)
weatherModelArray.add(model2)
val weatherAdapter = WeatherAdapter(this, weatherModelArray)
val linearLayoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
weatherRV.layoutManager = linearLayoutManager
weatherRV.adapter = weatherAdapter
apICall(this@MainActivity, model1)
}
}
apiCall:
@RequiresApi(Build.VERSION_CODES.O)
internal fun apICall(context: Context, jsonView: WeatherViewModel) {
var lat: Double? = null
var lon: Double? = null
var url: String? = null
val apiKey: String = "XXXX"
lat = YYY.Y
lon = YYY.Y
url = "https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&appid=${apiKey}&units=metric&exclude=minutely,hourly"
// Instantiate the RequestQueue.
val queue = Volley.newRequestQueue(context)
val gsonPretty = GsonBuilder().setPrettyPrinting().create()
// Request a string response from the provided URL.
val stringRequest = StringRequest(
Request.Method.GET, url,
{response ->
val gson = Gson()
val openJSON = gson.fromJson(response.toString(), OpenWeatherJSON::class.java)
val prettyJsonString = gsonPretty.toJson(openJSON)
try {
val dt = openJSON.daily[0].dt
val sdf = SimpleDateFormat("dd-MM-yyyy")
val date = Date(dt * 1000) // snackbar.dismiss()
sdf.format(date) // jsonView.apiResult = sdf.format(date) // jsonView.apiResult.append("\n")
jsonView.apiResult = openJSON.daily[0].temp.toString()
}
catch (e: Exception) {
jsonView.apiResult = e.toString()
}
},
{
jsonView.apiResult = "Error"
})
// Add the request to the RequestQueue.
queue.add(stringRequest) }
Now in the image below you can see, that Result1 is not getting changed into the request response. I can change it with jsonView.text = "something"
outside the stringRequest
Update1:
class WeatherAdapter(context: Context, weatherModelArray: ArrayList<WeatherViewModel>):
RecyclerView.Adapter<WeatherAdapter.ViewHolder>() {
private val weatherModelArray: ArrayList<WeatherViewModel>
// Constructor
init {
this.weatherModelArray = weatherModelArray
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WeatherAdapter.ViewHolder {
val view: View = LayoutInflater.from(parent.context).inflate(R.layout.card_layout, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: WeatherAdapter.ViewHolder, position: Int) {
val model = weatherModelArray[position]
holder.apiName.text = model.apiName
holder.apiResult.text = model.apiResult
}
override fun getItemCount(): Int {
return weatherModelArray.size
}
inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val apiName: TextView
val apiResult: TextView
init {
apiName = itemView.findViewById(R.id.idApiName)
apiResult = itemView.findViewById(R.id.idApiResult)
}
}
}
Upvotes: 0
Views: 179
Reputation: 10910
You need to notify the RecyclerView adapter that the data has changed after you change the data. This means calling notifyDataSetChanged
from within the callback. That would look something like this:
internal fun apICall(context: Context, jsonView: WeatherViewModel, adapter: WeatherAdapter) {
//...
val stringRequest = StringRequest(
Request.Method.GET, url,
{response ->
//...
jsonView.apiResult = openJSON.daily[0].temp.toString()
adapter.notifyDataSetChanged()
},
{
jsonView.apiResult = "Error"
adapter.notifyDataSetChanged()
})
// Add the request to the RequestQueue.
queue.add(stringRequest)
}
Upvotes: 1