Fragment内RecyclerView获取API数据后无法刷新显示问题
问题:DialogFragment中RecyclerView获取数据后无法显示
我在Fragment中获取API响应结果后填充RecyclerView,已成功获取到数据,但数据始终无法显示在屏幕上。

请问我遗漏了什么?
MainActivity启动Fragment的代码:
// 生成API客户端 val client = RestClient(endpoint, TimeoutType.LONG_TIMEOUT) // 生成对话框 val dialog = AccessHistoryFragment.newInstance(client) dialog.isCancelable = true dialog.show(supportFragmentManager, AccessHistoryFragment::class.java.name)
Fragment代码:
class AccessHistoryFragment: DialogFragment() { private lateinit var context: Context private lateinit var progressBar: ProgressBar private lateinit var noResultsTv: AppCompatTextView private lateinit var accessHistoryRv: RecyclerView private lateinit var adapter: AccessHistoryRecyclerViewAdapter private lateinit var client: RestClient private var elements = mutableListOf<Access>() companion object { fun newInstance(client: RestClient): AccessHistoryFragment { val fragment = AccessHistoryFragment() fragment.client = client return fragment } } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { // 获取视图 val view = layoutInflater.inflate(R.layout.fragment_access_history, null) as View progressBar = view.findViewById(R.id.loading_bar) as ProgressBar accessHistoryRv = view.findViewById(R.id.access_history_rv) as RecyclerView noResultsTv = view.findViewById(R.id.no_results_tv) as AppCompatTextView context = view.context // 初始化RecyclerView generateRecyclerView() // 构建对话框 val builder = AlertDialog.Builder(activity) builder.setView(view) return builder.create() } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) cargarHistorial() } private fun generateRecyclerView() { try { adapter = AccessHistoryRecyclerViewAdapter(elements) accessHistoryRv.apply { this.layoutManager = LinearLayoutManager(context) this.adapter = adapter } } catch (ex: Exception) { dismiss() } } private fun cargarHistorial() { Thread { try { val history = client.getAccessHistory(DateHelper.getCurrentDate()) updateAccessHistory(history) } catch (ex: Exception) { dismiss() } }.start() } private fun updateAccessHistory(accessList: MutableList<Access>) { requireActivity().runOnUiThread { progressBar.visibility = View.GONE if (accessList.size > 0) { elements.addAll(accessList) adapter.notifyItemRangeInserted(0, accessList.size) accessHistoryRv.visibility = View.VISIBLE } else noResultsTv.visibility = View.VISIBLE } } }
Adapter代码:
class AccessHistoryRecyclerViewAdapter(private var elements: MutableList<Access>): RecyclerView.Adapter<AccessHistoryRecyclerViewAdapter.AccessHistoryViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AccessHistoryViewHolder { return AccessHistoryViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.access_item, parent, false)) } override fun onBindViewHolder(holder: AccessHistoryViewHolder, position: Int) { // 保存当前数据 holder.access = elements[position] // 初始化视图内容 holder.accessText.text = holder.access.toString() } // 返回列表长度 override fun getItemCount() = elements.size inner class AccessHistoryViewHolder(v: View) : RecyclerView.ViewHolder(v) { var accessText: TextView = v.findViewById(R.id.access_text) lateinit var access: Access } }
补充说明
改用ListView替代RecyclerView时功能正常:
val accessHistoryLv = view.findViewById(R.id.access_history_lv) as ListView val elements = accessList.map { elem -> elem.toString() } val adapter = ArrayAdapter(context, android.R.layout.simple_list_item_1, elements) accessHistoryLv.adapter = adapter accessHistoryLv.visibility = View.VISIBLE
解决方案
问题出在DialogFragment的RecyclerView没有获取到正确的布局尺寸约束,核心原因是视图inflate方式不规范,导致RecyclerView无法正常测量自身大小。
修复步骤:
- 修正视图inflate逻辑
在onCreateDialog中inflate布局时,传入父容器并设置attachToRoot=false,让布局能继承对话框的约束:
// 原代码 val view = layoutInflater.inflate(R.layout.fragment_access_history, null) as View // 修改为 val view = layoutInflater.inflate(R.layout.fragment_access_history, null, false) as View // 或者更规范的写法: val parent = LinearLayout(activity) val view = layoutInflater.inflate(R.layout.fragment_access_history, parent, false)
- 检查RecyclerView的布局属性
确保fragment_access_history.xml中的RecyclerView设置了明确的宽高:
<androidx.recyclerview.widget.RecyclerView android:id="@+id/access_history_rv" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone"/>
- 验证数据通知方式
如果不确定插入位置,可先用notifyDataSetChanged快速验证(后续再优化为更高效的notifyItemRangeInserted):
// 原代码 adapter.notifyItemRangeInserted(0, accessList.size) // 替换为 adapter.notifyDataSetChanged()
为什么ListView能正常工作?
ListView内部自带自适应尺寸的逻辑,即使父容器约束不明确也能自行计算大小;而RecyclerView依赖明确的布局参数才能完成测量和渲染,这就是两者表现不同的核心原因。
内容的提问来源于stack exchange,提问作者Lechucico
相关产品推荐
相关产品推荐

