【发布时间】:2019-01-31 11:26:17
【问题描述】:
对于我创建的每个 Fragment 类,我添加如下内容:
companion object {
private const val PARAMETER_1 = "parameter1"
private const val PARAMETER_2 = "parameter2"
fun newInstance(parameter1: String, parameter2: Int) = MyDialog().apply {
arguments = bundleOf(
PARAMETER_1 to parameter1,
PARAMETER_2 to parameter2)
}
}
然后我添加:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val args = arguments ?: return
property1 = args[PARAMETER_1]
property2 = args[PARAMETER_2]
}
这并不可怕。但它是样板,摆脱它会很棒。
这是我目前的尝试:
abstract class BaseFragment : Fragment() {
abstract val constructorArguments: List<KMutableProperty<*>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val args = arguments ?: return
constructorArguments.forEach {
val key = keyPrefix + it.name
val argument = args.get(key)
val clazz = it.javaClass
val typedArgument = clazz.cast(argument)
it.setter.call(typedArgument)
}
}
companion object {
const val keyPrefix = "ARGUMENT_"
fun newInstance(fragment: BaseFragment, vararg parameters: Any): BaseFragment {
val constructorArguments = fragment.constructorArguments
val parameterMap = mutableListOf<Pair<String, Any?>>()
constructorArguments.forEachIndexed { index, kMutableProperty ->
val key = keyPrefix + kMutableProperty.name
val parameter = parameters[index]
parameterMap.add(Pair(key, parameter))
}
val args = bundleOf(*parameterMap.toTypedArray())
fragment.arguments = args
return fragment
}
}
}
然后,在实际的片段中,我可以拥有:
class MyFragment : BaseFragment() {
lateinit var myProperty: String
override val constructorArguments = listOf<KMutableProperty<*>>(
::myProperty
)
companion object {
fun newInstance(argument: String) = BaseFragment.newInstance(MyFragment(), argument)
}
}
这种方法远非完美——尤其是:
val parameter = parameters[index]
有人知道更好的方法吗?您对如何改进我的方法有什么建议吗?还是这整个想法注定要失败,我浪费了一个上午?
【问题讨论】:
-
这有什么不“美”的?即你想优化什么代码质量参数?让它更通用?让它更快?通过捆绑传递是一种非常成熟的做事方式。我的问题是为什么你要向你的片段传递这么多参数以至于你需要一个可变列表而不是仅仅从你的片段本身访问数据......
-
我想要一种将参数传递给静态构造函数的通用方法,而无需在每个 Fragment 类中手动设置 Bundle。如果我们可以使每个 Fragment 子类与 Bundle 无关,那将是理想的。
标签: android kotlin fragment static-constructor