GridView和动态数据

时间:2019-06-21 08:00:01

标签: android kotlin android-gridview

我从服务器下载数据,但不显示它们。如果从顶部降低快门,数据将被加载到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
}

3 个答案:

答案 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())接收的值来赋值列表值。