You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将API获取的汽车产品数据转为列表并展示多个产品?

解决汽车产品列表只显示最后一项的问题

我来帮你排查下问题所在,你现在只显示最后一个产品的核心原因是没有正确创建并添加多个CarsListData对象到列表中,还有Adapter和Activity里的一些逻辑错误,咱们一步步改:

1. 修复API请求的列表构建逻辑

原来的代码里,你直接修改CarsListData的静态属性(看起来你的CarsListData把字段都设成了静态?),每次循环都会覆盖之前的值,最后列表里根本没添加任何新对象。正确的做法是每次循环创建一个新的CarsListData实例,设置属性后添加到列表中

fun carsList(context: Context, complete: (List<CarsListData>?, Boolean) -> Unit) {
    val carListRequest = object : JsonObjectRequest(Method.GET, URL_CAR_LIST, null,
        Response.Listener { response ->
            try {
                val carList = mutableListOf<CarsListData>()
                val listCar = response.getJSONArray("listCar")
                for (i in 0 until listCar.length()) {
                    val carData = listCar.getJSONObject(i)
                    // 每次循环创建新的CarsListData对象
                    val singleCar = CarsListData().apply {
                        title = carData.getString("adTitle")
                        date = carData.getString("adDate")
                        price = carData.getDouble("adPrice")
                        category = carData.getString("category")
                        brand = carData.getString("brand")
                        model = carData.getString("brandModel")
                        distance = carData.getDouble("kilometer")
                        year = carData.getString("modelYear")
                        fuel = carData.getString("fuelType")
                        gear = carData.getString("gearType")
                    }
                    carList.add(singleCar) // 添加到列表
                }
                complete(carList, true) // 返回完整列表
            } catch (e: JSONException) {
                Log.d("JSON", "EXC" + e.localizedMessage)
                complete(null, false)
            }
        },
        Response.ErrorListener { error ->
            Log.d("ERROR", "Could not fetch cars: $error")
            complete(null, false)
        }) {
        override fun getBodyContentType(): String {
            return "application/json; charset=utf-8"
        }
    }
    Volley.newRequestQueue(context).add(carListRequest)
}

这里把回调改成返回List<CarsListData>?,这样能把获取到的完整列表传递出去。

2. 修正Adapter的逻辑错误

你的Adapter里犯了一个严重的错误:在getView方法里调用AuthService.carsList请求数据,这会导致每个列表项绘制时都重新发起API请求,不仅浪费资源,还会覆盖之前的数据。应该让Adapter只负责接收数据并展示,不要在里面做网络请求:

class CarAdapter(context: Context, private var cars: List<CarsListData>) : BaseAdapter() {
    private val inflater = LayoutInflater.from(context)

    // 提供方法更新数据
    fun updateData(newCars: List<CarsListData>) {
        cars = newCars
        notifyDataSetChanged() // 通知列表刷新
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val view = convertView ?: inflater.inflate(R.layout.cars_list, parent, false)
        val car = cars[position]

        // 找到控件并赋值
        view.findViewById<TextView>(R.id.carDetailsTitle).text = car.title
        view.findViewById<TextView>(R.id.carDetailsCategory).text = car.category
        view.findViewById<TextView>(R.id.carDetailsPrice).text = car.price.toString()
        view.findViewById<TextView>(R.id.carDetailsDistance).text = car.distance.toString()
        view.findViewById<TextView>(R.id.carDetailsDate).text = car.date
        view.findViewById<TextView>(R.id.cardetailsGear).text = car.gear
        view.findViewById<TextView>(R.id.carDetailsYear).text = car.year
        view.findViewById<TextView>(R.id.carDetailsOil).text = car.fuel

        // 图片加载逻辑可以在这里补全,比如使用Glide/Picasso
        // Glide.with(context).load(car.imageUrl).into(view.findViewById(R.id.carDetailsImage))

        return view
    }

    override fun getItem(position: Int): Any = cars[position]
    override fun getItemId(position: Int): Long = position.toLong() // 返回position作为id更合理
    override fun getCount(): Int = cars.size
}

这里加了updateData方法,用来在获取到新数据后更新Adapter的列表并刷新。

3. 调整Activity的初始化与数据请求逻辑

原来的Activity里初始化Adapter用的是listOf(CarsListData),这并不是一个空的可更新列表,而且没有在合适的时机发起API请求并更新Adapter:

class CarListActivity : AppCompatActivity() {
    private lateinit var adapter: CarAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_car_list)

        // 初始化空列表的Adapter
        adapter = CarAdapter(this, emptyList())
        CarsListPageItems.adapter = adapter

        // 发起API请求获取汽车列表
        AuthService.carsList(this) { carList, success ->
            if (success && carList != null) {
                // 更新Adapter的数据并刷新列表
                adapter.updateData(carList)
            } else {
                // 处理请求失败的情况,比如显示Toast
                Toast.makeText(this, "Failed to load cars", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

这里先初始化一个空列表的Adapter,然后发起请求,拿到数据后调用updateData方法更新列表,这样就能显示所有产品了。

额外注意点

确保你的CarsListData类的字段不是静态的(即没有companion object或者static修饰符),否则每次赋值都会覆盖所有实例的字段值,这也是你之前只看到最后一个产品的核心原因之一。正确的CarsListData应该是普通的数据类:

data class CarsListData(
    var title: String = "",
    var date: String = "",
    var price: Double = 0.0,
    var category: String = "",
    var brand: String = "",
    var model: String = "",
    var distance: Double = 0.0,
    var year: String = "",
    var fuel: String = "",
    var gear: String = ""
)

内容的提问来源于stack exchange,提问作者user12227098

火山引擎 最新活动