Android跨模块复用Fragment时如何优雅替换布局绑定的字符串资源
无侵入复用组件Fragment的实现方案
原有继承重写provideResource()的方案确实侵入性强,会强制业务方耦合组件层的Fragment实现,后续组件迭代时子类维护成本极高,以下是三个可直接落地的更优方案,按推荐优先级排序:
方案1:Fragment可选参数透传(通用场景首选)
完全不需要业务方继承Fragment,遵循Android官方Fragment的参数传递规范,把自定义文本资源作为可选入参处理:
- Components模块的Fragment实现逻辑:保留布局中默认的
@string/resource1配置作为兜底,在onViewCreated阶段检查arguments中是否传入自定义资源ID,有传入就覆盖默认文本,没有就展示布局默认值 - 代码参考:
// Components模块通用Fragment class CommonFragment : Fragment() { companion object { private const val KEY_TEXT_RES = "key_text_res" // 无参调用时直接使用布局默认资源 @JvmStatic fun newInstance(customTextResId: Int? = null) = CommonFragment().apply { arguments = Bundle().apply { customTextResId?.let { putInt(KEY_TEXT_RES, it) } } } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 读取传入的自定义资源,非空时覆盖默认文本 arguments?.getInt(KEY_TEXT_RES, 0)?.takeIf { it != 0 }?.let { resId -> view.findViewById<TextView>(R.id.target_text_view).setText(resId) } } }
- App模块复用方式:直接调用newInstance传入自身模块的字符串资源即可,不需要写任何子类:
// App模块页面内使用 supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, CommonFragment.newInstance(R.string.app_custom_text)) .commit()
- 优势:支持多页面差异化配置,可扩展支持传入String文本、富文本等其他类型参数,和组件层完全解耦,后续组件升级不影响业务层调用。
方案2:资源覆盖(全局统一替换场景适用)
如果App模块所有用到该Fragment的场景都展示同一段文本,完全不需要修改组件层的任何代码,利用Android资源合并的规则直接覆盖即可:
- 确认Components模块中布局绑定的字符串资源名为
resource1 - 在App模块的
res/values/strings.xml中定义同名资源,打包时App模块的资源会自动覆盖组件层的同名资源:
<!-- App模块strings.xml --> <string name="resource1">App模块全局替换后的展示文本</string>
- 注意:该方案是全局生效,同一个Fragment需要在不同页面展示不同文本时不适用。
方案3:自定义属性配置(XML/导航图静态声明场景适用)
如果项目使用XML静态添加Fragment、或者用Navigation组件做导航,可以通过自定义属性实现配置化赋值:
- 在Components模块的
res/values/attrs.xml中定义Fragment可配置属性:
<declare-styleable name="CommonFragment"> <attr name="fragmentText" format="reference|string" /> </declare-styleable>
- Fragment在
onInflate(XML加载场景)和onViewCreated阶段读取属性值,覆盖默认文本即可。App模块在XML布局或者导航图中添加Fragment时,直接通过app:fragmentText="@string/xxx"赋值,不需要写额外代码。
不推荐继续使用继承重写的方案:当后续组件需要新增更多可配置项(比如文本颜色、点击事件、图标资源等)时,业务方需要重写的方法会越来越多,子类数量会快速膨胀,维护成本会指数级上升。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

