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

Android RecyclerView获取数据成功但无法显示问题求助

RecyclerView获取数据后不显示的问题排查与解决

问题描述

我尝试从本地API获取图片详情并通过RecyclerView展示,已在Logcat中通过Log.d("data", data.toString())确认数据成功获取,但RecyclerView无法显示数据。以下是对应源码:

Activity源码

lateinit var rvMain:RecyclerView
lateinit var myAdapter: MyAdapter


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_2)
    rvMain = findViewById<RecyclerView>(R.id.recycler_view)
    setContent {

        rvMain.findViewById<RecyclerView>(R.id.recycler_view)
        rvMain.layoutManager = LinearLayoutManager(this)


        getAllData()

    }
}

private fun getAllData() {

    var retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(ApiInterface::class.java)

    var retroData = retrofit.getData()

    retroData.enqueue(object :Callback<List<MyDataItem>> {
        override fun onResponse(
            call:Call<List<MyDataItem>>,
            response: retrofit2.Response<List<MyDataItem>>
        ) {
            var data = response.body()

            myAdapter = MyAdapter(baseContext, data as ArrayList<MyDataItem>)

            rvMain.adapter = myAdapter

            Log.d("data", data.toString())
        }

        override fun onFailure(call: Call<List<MyDataItem>>, t: Throwable) {
            t.message?.let { Log.d("data", it) }
        }
    })
}

Adapter源码

class MyAdapter(var con  :Context,val list:ArrayList<MyDataItem>):RecyclerView.Adapter<MyAdapter.ViewHolder>() {

    inner class ViewHolder(v : View):RecyclerView.ViewHolder(v) {
        var img = v.findViewById<ImageView>(R.id.RV_Image)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        var view = LayoutInflater.from(con).inflate(R.layout.list_item,parent,false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        Glide.with(con).load(list[position].image_path).into(holder.img)

    }

    override fun getItemCount(): Int {
        return list.count()
    }
}

问题排查与修正

1. 核心问题:XML与Compose布局冲突

你在onCreate中先调用setContentView(R.layout.activity_2)加载XML布局,随后又调用setContent(Jetpack Compose布局方法),这会直接替换掉原XML布局,导致你获取的rvMain根本没有显示在界面上。

2. 冗余错误代码

rvMain.findViewById<RecyclerView>(R.id.recycler_view)完全多余,rvMain本身就是已获取的RecyclerView实例,无需重复查找。

3. 数据安全与代码优化

直接强转response.body()为ArrayList存在空指针风险,需先判空;同时集合长度用size替代count()更符合Kotlin规范。


修正后的代码

修正后的Activity代码

lateinit var rvMain: RecyclerView
lateinit var myAdapter: MyAdapter

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_2)
    rvMain = findViewById<RecyclerView>(R.id.recycler_view)
    // 直接设置布局管理器,无需进入setContent块
    rvMain.layoutManager = LinearLayoutManager(this)
    getAllData()
}

private fun getAllData() {
    val retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(ApiInterface::class.java)

    val retroData = retrofit.getData()

    retroData.enqueue(object : Callback<List<MyDataItem>> {
        override fun onResponse(
            call: Call<List<MyDataItem>>,
            response: retrofit2.Response<List<MyDataItem>>
        ) {
            val data = response.body() ?: return // 空数据直接返回,避免崩溃
            myAdapter = MyAdapter(this@Activity2, ArrayList(data)) // 安全转换为ArrayList
            rvMain.adapter = myAdapter
            Log.d("data", data.toString())
        }

        override fun onFailure(call: Call<List<MyDataItem>>, t: Throwable) {
            t.message?.let { Log.d("data", it) }
        }
    })
}

注意:将this@Activity2替换为你的Activity实际类名

修正后的Adapter代码

class MyAdapter(private val context: Context, private val list: ArrayList<MyDataItem>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {

    inner class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
        val img: ImageView = v.findViewById(R.id.RV_Image)
    }

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

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        Glide.with(context)
            .load(list[position].image_path)
            .placeholder(R.drawable.placeholder) // 可选:添加加载占位图,验证加载状态
            .error(R.drawable.error) // 可选:添加错误占位图
            .into(holder.img)
    }

    override fun getItemCount(): Int {
        return list.size // 用size替代count(),更规范
    }
}

额外检查项

  • 确认list_item.xml中的ImageView设置了合理宽高,例如:
    <ImageView
        android:id="@+id/RV_Image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:scaleType="centerCrop"/>
    
  • 验证image_path是可访问的有效路径(本地API需注意是否需要拼接BASE_URL)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 07:31:37