Я изучил ваш код и понял, что проблема возникает из-за вызова of-
adapter = CategoryBaseAdapter(getCategoryItemsFromServer())
grid_view.adapter = adapter
При создании конструктора для CategoryBaseAdapter и передаче getCategoryItemsFromServer () в качестве параметра, но до получения ответа от сервера (другим потоком), основной поток завершит поток пустым списком.В результате там не будет никаких данных.Теперь, когда данные сервера будут получены, адаптер не сможет ничего сделать.
Теперь решение будет таким: вызовите свой адаптер, как только вы получите данные от сервера, или вызовите notifyDataSetChanged () после заполнения данных.,Таким образом, окончательный код будет
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()
}
})
}
Теперь внутри адаптера не создавайте объект списка, а создайте переменную ссылки на список и задавайте значение списка, полученное из вызова конструктора адаптера (т. Е. Из действия onCreate).()).