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

Kotlin Fragment中GridView无法显示问题求助

Fragment中GridView无法显示的问题修复

问题现象

在Fragment中使用GridView时,数据已填充但GridView无显示,Adapter的getView()从未被调用,调用courseGRV.get(0)会触发索引越界异常。

核心问题分析

问题出在重复inflate布局:在onCreateView中,你已经通过FragmentDashboardBinding.inflate()创建了布局并得到root,但之后又额外inflate了一份fragment_dashboard布局,绑定的courseGRV属于这份未被添加到界面的布局,因此设置Adapter后不会被渲染。

解决方案

修复步骤

  • 移除多余的布局inflate代码,直接通过View Binding获取GridView实例
  • 规范实现Adapter的getItem()方法(返回对应位置的数据项)
  • 优化数据集合的初始化方式

修改后的Fragment代码

class DashboardFragment : Fragment() {

    private var _binding: FragmentDashboardBinding? = null
    private val binding get() = _binding!!

    lateinit var courseGRV: GridView
    lateinit var courseList: List<GridViewModal>

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentDashboardBinding.inflate(inflater, container, false)
        val root: View = binding.root

        // 直接通过View Binding获取GridView,无需重新inflate布局
        courseGRV = binding.idGRV
        // 用mutableList更简洁地初始化数据
        courseList = mutableListOf(
            GridViewModal("Art", R.drawable.art),
            GridViewModal("Culture", R.drawable.culture),
            GridViewModal("Hobbies", R.drawable.hobbies)
        )

        println(courseList.size)
        val courseAdapter = GridRVAdapter(courseList = courseList, this.requireContext())
        courseGRV.adapter = courseAdapter

        courseGRV.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ ->
            Toast.makeText(
                this.requireContext(), "${courseList[position].courseName} selected",
                Toast.LENGTH_SHORT
            ).show()
        }

        return root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

修改后的Adapter代码

internal class GridRVAdapter(
    private val courseList: List<GridViewModal>,
    private val context: Context
) : BaseAdapter() {

    private var layoutInflater: LayoutInflater? = null

    override fun getCount(): Int {
        return courseList.size
    }

    // 返回对应位置的数据项,规范实现BaseAdapter方法
    override fun getItem(position: Int): GridViewModal {
        return courseList[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong() // 用position作为itemId,更合理
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        var convertView = convertView
        println("getview")
        
        if (layoutInflater == null) {
            layoutInflater = LayoutInflater.from(context)
        }
     
        if (convertView == null) {
            convertView = layoutInflater!!.inflate(R.layout.gridview_item, parent, false)
        }

        val courseIV = convertView!!.findViewById<ImageView>(R.id.idIVCourse)
        val courseTV = convertView!!.findViewById<TextView>(R.id.idTVCourse)

        courseIV.setImageResource(courseList[position].courseImg)
        courseTV.text = courseList[position].courseName
        
        return convertView
    }
}

额外说明

  • 移除重复inflate的代码后,绑定的GridView是当前Fragment界面上的真实控件,设置Adapter后会正常触发getView()渲染。
  • Adapter中修改getItem()和getItemId()是为了符合BaseAdapter的规范,避免潜在的逻辑问题。
  • 用LayoutInflater.from(context)替代getSystemService更简洁直观,inflate布局时传入parent可以正确继承布局参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:57:56