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

RecyclerView未显示问题求助:API汇率数据无法展示

问题描述

我开发了一款调用API展示汇率基础数据的应用,但RecyclerView的元素无法在屏幕上显示,仅能看到TextView。我已尝试删除可能遮挡RecyclerView的TextView,其他代码调整均无效,怀疑可能与ViewBinding有关,但无法定位具体问题。相关代码如下:

StartFragment 代码

class StartFragment : Fragment() {

    private lateinit var binding: FragmentStartBinding
    private lateinit var recyclerView: RecyclerView
    private lateinit var adapter: StartAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        // Inflate the layout for this fragment
        binding = FragmentStartBinding.inflate(inflater, container, false)

        val viewModel = ViewModelProvider(this)[StartViewModel::class.java]
        recyclerView = binding.rvStart
        adapter = StartAdapter()
        recyclerView.adapter = adapter
        viewModel.getCash()
        viewModel.myCashList.observe(viewLifecycleOwner) { list ->
            list.body()?.let { adapter.setList(it) }
        }

        return binding.root
    }
}

StartAdapter 代码

class StartAdapter:RecyclerView.Adapter<StartAdapter.StartViewHolder>() {

    private var listStart = emptyList<CashItem>()

    class StartViewHolder(val binding: ItemMoneyLayoutBinding):RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StartViewHolder {
        val binding = ItemMoneyLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return StartViewHolder(binding)
    }

    override fun getItemCount(): Int {
        return listStart.size
    }

    override fun onBindViewHolder(holder: StartViewHolder, position: Int) {
        holder.binding.itemName.text = listStart[position].ccy
        holder.binding.itemBuy.text = listStart[position].buy
        holder.binding.itemSale.text = listStart[position].sale
    }

    @SuppressLint("NotifyDataSetChanged")
    fun setList(list: List<CashItem>){
        listStart = list
        notifyDataSetChanged()
    }
}

fragment_start.xml 布局

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".screens.start.StartFragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</FrameLayout>

Repository 代码

class Repository {

    suspend fun getCashMoney(): Response<Cash>{
        return RetrofitInstance.api.getCash()
    }

    suspend fun getNonCashMoney(): Response<NonCash>{
        return RetrofitInstance.api.getNonCash()
    }
}
解决方案

1. 为RecyclerView添加LayoutManager(核心问题)

RecyclerView必须设置LayoutManager才能渲染条目,你的代码里完全缺失这一步,这是导致条目不显示的最主要原因。修改StartFragment的初始化代码:

recyclerView = binding.rvStart
adapter = StartAdapter()
// 添加以下一行,设置线性布局管理器
recyclerView.layoutManager = LinearLayoutManager(requireContext())
recyclerView.adapter = adapter

2. 修复布局重叠问题

原布局用FrameLayout,TextView和RecyclerView默认重叠在左上角,即使删除TextView,RecyclerView用wrap_content也可能因为数据加载前高度为0导致显示异常。建议把FrameLayout换成垂直方向的LinearLayout,并调整RecyclerView的高度属性:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".screens.start.StartFragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_start"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

这样RecyclerView会自动占满TextView下方的剩余空间,避免重叠,也能正确显示所有条目。

3. 验证API数据是否正常传递

在LiveData观察者里添加日志,确认API返回的数据是否正确到达适配器:

viewModel.myCashList.observe(viewLifecycleOwner) { list ->
    val dataList = list.body()
    Log.d("StartFragment", "API返回数据:$dataList")
    dataList?.let { 
        adapter.setList(it)
        Log.d("StartFragment", "适配器接收数据条数:${it.size}")
    }
}

如果日志里显示数据为空或条数为0,那问题出在API请求或解析环节,需要检查Retrofit配置、接口返回格式是否和CashItem类匹配。

4. 确认Item布局的正确性

检查item_money_layout.xml的布局,确保里面的itemName、itemBuy、itemSale三个TextView存在,且布局参数合理(比如宽度设为wrap_content或match_parent,避免内容被挤压隐藏)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 20:55:37