如何在RecyclerView自定义监听器的onScrollStateChanged中更新UI?
解决方法
下面是几种在CustomScrollListener中调用Controller.updateUI()的实用方案,都是Android开发中常用的解耦方式:
方案一:构造函数注入Controller实例
直接在CustomScrollListener的构造方法中传入已初始化好的Controller对象,这是最直观且低耦合的方式:
修改CustomScrollListener:
class CustomScrollListener(private val controller: Controller) : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { // 满足滚动状态条件时调用 controller.updateUI(true) } }
在创建监听器的地方(比如Activity或Fragment中,这里已经有Controller实例)设置:
// 假设在Activity中已经初始化了Controller val controller = Controller(this, findViewById(R.id.root_view)) recyclerView.addOnScrollListener(CustomScrollListener(controller))
方案二:使用接口回调解耦
如果不想让CustomScrollListener直接依赖Controller,可以定义一个回调接口,让Controller实现该接口,监听器只持有接口引用:
- 定义回调接口:
interface ScrollCallback { fun onScrollTriggerUpdateUI(isTriggered: Boolean) }
- 修改
CustomScrollListener持有接口实例:
class CustomScrollListener(private val callback: ScrollCallback) : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { // 满足条件时触发回调 callback.onScrollTriggerUpdateUI(true) } }
- 让
Controller实现接口:
class Controller(activity: Activity, viewGroup: ViewGroup) : ScrollCallback { fun updateUI(boolean: Boolean) { // 原逻辑 } override fun onScrollTriggerUpdateUI(isTriggered: Boolean) { updateUI(isTriggered) } }
- 设置监听器时传入Controller实例:
val controller = Controller(this, findViewById(R.id.root_view)) recyclerView.addOnScrollListener(CustomScrollListener(controller))
方案三:通过RecyclerView的Tag传递Controller
如果不想修改监听器的构造函数,可以将Controller实例存入RecyclerView的Tag中,在监听器内获取:
设置监听器时给RecyclerView设置Tag:
val controller = Controller(this, findViewById(R.id.root_view)) recyclerView.setTag(R.id.controller_tag, controller) // 建议用自定义的资源ID作为key recyclerView.addOnScrollListener(CustomScrollListener())
修改CustomScrollListener获取Controller:
class CustomScrollListener : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { val controller = recyclerView.getTag(R.id.controller_tag) as? Controller controller?.let { it.updateUI(true) } } }
注意:使用Tag时要确保类型转换安全,避免ClassCastException,建议用
as?配合let处理。
内容的提问来源于stack exchange,提问作者Karthik . N
相关产品推荐
相关产品推荐

