我从服务器下载数据,但不显示它们。如果从顶部降低快门,数据将被加载到GridView
中。
已经尝试了所有选项,可以正常读取服务器中的数据,但不会将其加载到GridView
中。你能告诉我是什么问题吗?
适配器:
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
}
活动:
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
}
答案 0 :(得分:0)
private fun getCategoryItemsFromServer()
返回空列表。
您可以在enqueue
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")))
}
adapter = CategoryBaseAdapter(list)
或使用CategoryBaseAdapter
修改fun addItems(list:ArrayList<Items>)
添加方法notifyDataSetChanged()
答案 1 :(得分:0)
由于getCategoryItemsFromServer是asynchone,因此我不确定启动适配器时是否检索到了Items。 在getCategoryItemsFromServer的onResponse中启动适配器。也许可以在带有join方法的Thread中调用此方法,以确保在继续之前该线程已结束。
编辑:不做任何更改,只需在onResponse末尾调用adapter.notifyDataSetChanged()即可。当有物品时刷新适配器
答案 2 :(得分:0)
我查看了您的代码,发现问题是由于调用-
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())接收的值来赋值列表值。