对于我制作的每个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]
有人知道更好的方法吗?您对如何改进我的方法有一些建议吗?还是整个想法注定要失败,而我浪费了一个上午?
答案 0 :(得分:1)
您可以拥有一个定义公共args
参数的基本片段
abstract class BaseFragment : Fragment() {
companion object {
const val ARGS_KEY = "__ARGS__"
}
fun <T: Parcelable> getArgs(): T = requireArguments().getParcelable(ARGS_KEY)
fun putArgs(args: Parcelable): Bundle = (arguments ?: Bundle()).apply {
putParcelable(ARGS_KEY, args)
}
}
然后
@Parcelize data class Args(val parameter1: String, val parameter2: Int)
companion object {
fun newInstance(args: Args) = MyDialog().apply {
putArgs(args)
}
}
现在您可以像这样
class MyFragment: BaseFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val args: Args = getArgs()
args.parameter2
}
}
答案 1 :(得分:0)
此问题的“答案”是使用Android Jetpack导航库。它提供了SafeArgs,可以大大简化将参数传递给Fragment的过程。参见:
https://developer.android.com/guide/navigation/navigation-pass-data#Safe-args