如何消除RecyclerView出现的非预期黑色分隔线
问题根因
你看到的黑色分隔线和Volley、Picasso库没有任何关系,是你代码里主动给RecyclerView添加了系统默认的DividerItemDecoration分隔线,只是代码放错了位置,才造成了“引入库才出线”的错觉:
- 用本地自定义ArrayList加载数据时,不会触发网络请求成功的回调逻辑,添加分隔线的代码根本不会执行,自然看不到黑线
- 引入Volley发起网络请求、拿到接口返回数据后,才会执行到添加分隔线的代码,所以你误以为是库导致的问题
你贴的代码里存在明显的逻辑错误:在遍历接口返回图书数据的for循环里,每遍历一条数据,就会重复执行三次冗余操作:重新创建LayoutManager、重新实例化Adapter、给RecyclerView新增一个分隔线装饰。等于接口返回多少条数据,你就给RecyclerView叠了多少个分隔线装饰,不仅会出黑线,还会造成列表滑动卡顿、内存占用升高的问题。
对应的错误代码片段如下:
for(i in 0 until data.length()) { val bookjsonobj = data.getJSONObject(i) // ... 图书数据解析逻辑 bookInfoList.add(booklist) // 错误1:循环内重复初始化布局管理器 layoutManager = LinearLayoutManager(activity) // 错误2:循环内重复创建适配器 adapter = Dashboard_Recycler_Adapter(activity as Context, bookInfoList) recyclerView.adapter = adapter recyclerView.layoutManager = layoutManager // 错误3:循环内重复添加分隔线装饰,这就是黑线的直接来源 recyclerView.addItemDecoration( DividerItemDecoration( recyclerView.context, (layoutManager as LinearLayoutManager).orientation ) ) }
修复方案
- 把LayoutManager初始化、Adapter实例化、分隔线添加的逻辑全部移到网络请求外侧,和你之前本地加载数据的初始化逻辑放在一起,不要塞进接口回调的循环里
- 接口请求成功、遍历完所有返回数据、全部存入
bookInfoList之后,只需要调用一次adapter.notifyDataSetChanged()刷新列表即可,不需要重复创建适配器和布局管理器 - 如果你本身就不需要分隔线,直接删掉
recyclerView.addItemDecoration(...)整段代码,黑线会立刻消失
修正后的核心代码参考:
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.fragment_dashboard_fragment, container, false) recyclerView = view.findViewById(R.id.rvdashboard) // 布局管理器、适配器统一初始化,全局只执行一次 layoutManager = LinearLayoutManager(activity) adapter = Dashboard_Recycler_Adapter(activity as Context, bookInfoList) recyclerView.adapter = adapter recyclerView.layoutManager = layoutManager // 需要分隔线就在这里加一次,不需要就直接删掉这段 recyclerView.addItemDecoration( DividerItemDecoration( recyclerView.context, (layoutManager as LinearLayoutManager).orientation ) ) // 网络连通性检查逻辑保持不变 if(!isOnline(activity as Context)) { // ... 原有断网弹窗逻辑不变 return view } val queue = Volley.newRequestQueue(activity as Context) val url = "http://13.235.250.119/v1/book/fetch_books/" val jsonObjectRequest = object: JsonObjectRequest(Request.Method.GET, url, null, Response.Listener { val success = it.getBoolean("success") if(success) { val data = it.getJSONArray("data") // 循环内只做数据解析和添加,不做任何控件初始化操作 for(i in 0 until data.length()) { val bookjsonobj = data.getJSONObject(i) val booklist = book( bookjsonobj.getString("book_id"), bookjsonobj.getString("name"), bookjsonobj.getString("author"), bookjsonobj.getString("rating"), bookjsonobj.getString("price"), bookjsonobj.getString("image") ) bookInfoList.add(booklist) } // 所有数据加载完成后统一刷新一次列表即可 adapter.notifyDataSetChanged() } }, Response.ErrorListener { Log.e(TAG, "图书列表加载失败", it) }) queue.add(jsonObjectRequest) return view }
内容的提问来源于stack exchange,提问作者Abhishek Dadwal
相关产品推荐
相关产品推荐

