I download data from the server and they are not displayed. If you lower the shutter from the top, the data is loaded into the GridView
.
Already tried all options, data from the server are read normally, but are not loaded in GridView
. Could you tell me, please, what is the problem?
Adapter:
private val list = list
override fun getView(position:Int, convertView: View?, parent: ViewGroup?):View{
// Inflate the custom view
val inflater = parent?.context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val view = inflater.inflate(R.layout.shop_item,null)
// Get the custom view widgets reference
val tv = view.findViewById<TextView>(R.id.tv_name)
val card = view.findViewById<CardView>(R.id.card_view)
// Display color name on text view
tv.text = list[position].name
Picasso.get().load("http://first-gadget.ru/" + list[position].img).into(view.image)
// Set a click listener for card view
card.setOnClickListener{
// Show selected color in a toast message
Toast.makeText(parent.context,
"Clicked : ${list[position].name}",Toast.LENGTH_SHORT).show()
}
// Finally, return the view
return view
}
Activity:
private lateinit var title: String
private var adapter: CategoryBaseAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_category)
adapter = CategoryBaseAdapter(getCategoryItemsFromServer())
grid_view.adapter = adapter
// Configure the grid view
grid_view.numColumns = 2
grid_view.horizontalSpacing = 30
grid_view.verticalSpacing = 30
grid_view.stretchMode = GridView.STRETCH_COLUMN_WIDTH
}
private fun getCategoryItemsFromServer(): ArrayList<Items> {
val list = ArrayList<Items>()
val url = "http://first-gadget.ru/api/shop.php"
val requestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("category", "cars")
.build()
val request = Request.Builder().url(url).post(requestBody).build()
var client = OkHttpClient()
client.newCall(request).enqueue(object: Callback {
override fun onResponse(call: Call, response: Response) {
val body = response.body()?.string()
val obj = JSONObject(body)
val array = obj.getJSONArray("array")
for (i in 0 until array.length()) {
var detail: JSONObject =array.getJSONObject(i)
list.add(Items(detail.getInt("id"), detail.getString("name"), detail.getString("img")))
}
}
override fun onFailure(call: Call, e: IOException) {
Toast.makeText(this@CategoriesActivity, "Sasat", Toast.LENGTH_SHORT).show()
}
})
return list
}
I looked into your code and got that the issue is coming due to calling of-
adapter = CategoryBaseAdapter(getCategoryItemsFromServer())
grid_view.adapter = adapter
When creating constructor for CategoryBaseAdapter and passing getCategoryItemsFromServer() as a parameter but before getting the response from server (by another thread), Main thread will complete the flow with empty list. As a result no data will show there. Now when server data will be received then nothing will remain to be done by the adapter.
Now the solution will be, call your adapter once you received the data from server or call notifyDataSetChanged() once the data is populated. So the final code will be
private lateinit var title: String
private var adapter: CategoryBaseAdapter? = null
val list = ArrayList<Items>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_category)
//Creating adapter with empty list
adapter = CategoryBaseAdapter(list)
grid_view.adapter = adapter
// Configure the grid view
grid_view.numColumns = 2
grid_view.horizontalSpacing = 30
grid_view.verticalSpacing = 30
grid_view.stretchMode = GridView.STRETCH_COLUMN_WIDTH
//Calling server to populate list
getCategoryItemsFromServer()
}
private fun getCategoryItemsFromServer() {
val url = "http://first-gadget.ru/api/shop.php"
val requestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("category", "cars")
.build()
val request = Request.Builder().url(url).post(requestBody).build()
var client = OkHttpClient()
client.newCall(request).enqueue(object: Callback {
override fun onResponse(call: Call, response: Response) {
val body = response.body()?.string()
val obj = JSONObject(body)
val array = obj.getJSONArray("array")
for (i in 0 until array.length()) {
var detail: JSONObject =array.getJSONObject(i)
list.add(Items(detail.getInt("id"), detail.getString("name"), detail.getString("img")))
}
//List populated from server data, now refreshing to populated updated one.
adapter.notifyDataSetChanged();
}
override fun onFailure(call: Call, e: IOException) {
Toast.makeText(this@CategoriesActivity, "Sasat", Toast.LENGTH_SHORT).show()
}
})
}
Now inside the adapter, don't create list object rather create a list referance variable and assing the list value as received from the adapter constructor call (i.e, from activity onCreate()).