共享布局与代码的Fragment:组合替代继承的实现方案咨询
用组合模式实现Fragment的代码复用
核心思路
把Fragment中共享的视图初始化、通用配置逻辑抽离到一个独立的控制器类中,让每个具体Fragment通过持有该控制器的实例来复用逻辑,同时将各自差异化的部分(Adapter、回调)作为依赖传入控制器。
具体实现步骤
1. 创建共享视图控制器类
这个类负责处理所有通用的视图逻辑,比如布局绑定、RecyclerView基础配置、通用视图操作,并通过构造参数接收差异化的Adapter和回调:
class SharedFragmentController( private val rootView: View, private val recyclerAdapter: RecyclerView.Adapter<*>, private val itemClickCallback: (Any) -> Unit ) { private val titleTv: TextView = rootView.findViewById(R.id.title_tv) private val recyclerView: RecyclerView = rootView.findViewById(R.id.recycler_view) init { // 初始化通用RecyclerView配置 recyclerView.layoutManager = LinearLayoutManager(rootView.context) recyclerView.adapter = recyclerAdapter // 绑定Adapter的点击事件到传入的回调 setupAdapterClickListener() } private fun setupAdapterClickListener() { // 假设你的自定义Adapter都实现了点击监听接口,这里做类型判断并绑定 if (recyclerAdapter is BaseClickableAdapter<*>) { recyclerAdapter.setOnItemClickListener { item -> itemClickCallback(item) } } } // 对外提供通用视图操作方法 fun updateTitle(title: String) { titleTv.text = title } // 清理资源,避免内存泄漏 fun cleanup() { if (recyclerAdapter is BaseClickableAdapter<*>) { recyclerAdapter.setOnItemClickListener(null) } } } // 自定义Adapter的基础接口(如果你的Adapter没有统一的点击监听,需要先定义) interface BaseClickableAdapter<T> : RecyclerView.Adapter<*> { fun setOnItemClickListener(listener: ((T) -> Unit)?) }
2. 实现具体Fragment
每个Fragment只需要处理自己的差异化逻辑,通过实例化控制器来复用通用代码:
FragmentA
class FragmentA : Fragment() { private lateinit var sharedController: SharedFragmentController override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_shared, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 创建自己的Adapter val adapterA = AdapterA() // 定义自己的回调逻辑 val clickCallback = { item: ItemA -> (activity as MainActivity).handleFragmentAItemClick(item) } // 初始化共享控制器,传入依赖 sharedController = SharedFragmentController(view, adapterA, clickCallback) sharedController.updateTitle("Fragment A") } override fun onDestroyView() { super.onDestroyView() // 清理控制器资源 sharedController.cleanup() } }
FragmentB
class FragmentB : Fragment() { private lateinit var sharedController: SharedFragmentController override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_shared, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val adapterB = AdapterB() val clickCallback = { item: ItemB -> (activity as MainActivity).handleFragmentBItemClick(item) } sharedController = SharedFragmentController(view, adapterB, clickCallback) sharedController.updateTitle("Fragment B") } override fun onDestroyView() { super.onDestroyView() sharedController.cleanup() } }
组合模式的优势
- 低耦合:共享逻辑和差异化逻辑完全分离,修改共享逻辑不会影响具体Fragment的独立功能,反之亦然。
- 灵活性高:如果后续新增类似Fragment,只需创建自己的Adapter和回调,复用同一个控制器即可,无需修改原有代码。
- 避免继承陷阱:不会出现继承链过长、父类方法冗余、子类被迫继承不需要的逻辑等问题。
内容的提问来源于stack exchange,提问作者cheeseybiscuits
相关产品推荐
相关产品推荐

