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
相关产品推荐
相关产品推荐

