You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView仅显示列表单个条目问题求助

RecyclerView仅显示单个城市的问题排查与修复

我正在开发一个可搜索城市并返回同名不同地理位置城市列表的小型项目。目前已实现搜索栏功能,能够成功获取城市列表,但RecyclerView仅显示列表中的一个城市。

现有代码

MainActivity.kt

class MainActivity : AppCompatActivity() {
    private lateinit var searchView: SearchView
    private lateinit var recyclerView: RecyclerView
    private lateinit var cityAdapter: CityAdapter

    private val apiService by lazy{
        Retrofit.Builder().baseUrl("https://api.openweathermap.org/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(WeatherApiService::class.java)
    }

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

        searchView = findViewById(R.id.searchView)
        recyclerView = findViewById(R.id.recyclerView)

        setupRecyclerView()

        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                if (!query.isNullOrBlank()) {
                    searchCities(query)
                }
                return true
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                return false
            }
        })
    }

    private fun setupRecyclerView(): Unit {
        cityAdapter=CityAdapter(mutableListOf())
        recyclerView.apply {
            layoutManager = LinearLayoutManager(this@MainActivity)
            adapter = cityAdapter
        }
    }

    private fun searchCities(cityName: String): Unit {
        CoroutineScope(Dispatchers.IO).launch{
            try{
                val apiKey = "" //api key
                val cities = apiService.searchCity(cityName, 1000, apiKey)
                Log.d("API Response: ", cities.toString())
                updateCityList(cities)
            }catch (e: Exception){
                e.printStackTrace()
            }
        }
    }

    private fun updateCityList(cities: List<CityInfo>): Unit {
        runOnUiThread {
            cityAdapter.updateData(cities);
        }
    }
}

CityAdapter.kt

class CityAdapter(private val cities: MutableList<CityInfo>):RecyclerView.Adapter<CityAdapter.CityViewHolder>(){
    fun updateData(newData: List<CityInfo>): Unit {
        cities.clear();
        cities.addAll(newData);
        notifyDataSetChanged();
    }

    class CityViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
        val cityNameTextView: TextView = itemView.findViewById(R.id.cityNameTextView)
        val countryTextView: TextView = itemView.findViewById(R.id.countryTextView)
        val locationTextView: TextView = itemView.findViewById(R.id.locationTextView)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CityViewHolder{
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_city, parent, false)
        return CityViewHolder(view)
    }

    override fun onBindViewHolder(holder: CityViewHolder, position: Int) {
        val city = cities[position]
        holder.cityNameTextView.text = city.name
        val location = "${city.country}, ${city.state}"
        holder.countryTextView.text = location
        val coordinates = "Lat: ${city.lat}, Lon: ${city.lon}"
        holder.locationTextView.text = coordinates
    }

    override fun getItemCount(): Int {
        Log.d("City List Size:", cities.size.toString())
        return cities.size
    }
}

item_city.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation = "vertical">

    <TextView
        android:id = "@+id/cityNameTextView"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:textSize = "16sp"
        android:textStyle = "bold"/>

    <TextView
        android:id = "@+id/countryTextView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textSize = "14sp"/>
    <TextView
        android:id = "@+id/locationTextView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textSize = "14sp"/>
</LinearLayout>

问题原因

列表项布局item_city.xml的根LinearLayout设置了android:layout_height="match_parent",这会让每个列表项占据RecyclerView的全部高度,后续列表项被挤出可视区域,导致视觉上只显示一个城市。

修复方案

将根LinearLayout的高度改为wrap_content,让列表项高度自适应内部内容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation = "vertical"
    android:padding="8dp">

    <TextView
        android:id = "@+id/cityNameTextView"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:textSize = "16sp"
        android:textStyle = "bold"/>

    <TextView
        android:id = "@+id/countryTextView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textSize = "14sp"/>
    <TextView
        android:id = "@+id/locationTextView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:textSize = "14sp"/>
</LinearLayout>

额外检查点:

  • 确认getItemCount()返回的列表长度与API返回一致(查看日志City List Size:)
  • 确保updateData()中正确调用notifyDataSetChanged()通知适配器更新
  • 确认RecyclerView已设置正确的LayoutManager(当前代码已配置LinearLayoutManager,无问题)

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:47:09