有没有办法在Kotlin和Android中捆绑函数引用,以便可以从其他片段调用函数?例如,我的片段工厂方法如下所示:
fun newInstance(tryAgainFunction: () -> Unit): TimeOutHandlerFragment {
val fragment = TimeOutHandlerFragment()
val bundle = Bundle()
return fragment
}
Run Code Online (Sandbox Code Playgroud)
我希望能够将我的tryAgainFunction保存在bundle中以便进一步检索.
非常感谢!
编辑
最后,最合适的解决方案是使用热键的答案,然后在onViewCreated中使用传递的函数初始化一个侦听器.完整的代码如下:
companion object {
val CALLBACK_FUNCTION: String = "CALLBACK_FUNCTION"
fun newInstance(tryAgainFunction: () -> Unit): TimeOutHandlerFragment {
val fragment = TimeOutHandlerFragment()
val bundle = Bundle()
bundle.putSerializable(CALLBACK_FUNCTION, tryAgainFunction as Serializable)
fragment.arguments = bundle
return fragment
}
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
try {
val callback: () -> Unit = arguments.getSerializable(CALLBACK_FUNCTION) as () -> Unit
btnTryAgain.setOnClickListener { callback.invoke() }
} catch (ex: Exception) {
// callback has a wrong format
ex.printStackTrace()
}
}
Run Code Online (Sandbox Code Playgroud)
感谢大家的帮助!
Sam*_*hen 12
2022 年更新:
NotSerializableException.Fragment,即FragmentResultListener官方教程在这里: https: //youtu.be/oP-zXjkT0C0?t =468 。FragmentResultListener不能满足您的需求,Shared ViewModel最终解决方案在那里: https: //youtu.be/THt9QISnIMQ。1.您需要添加id 'kotlin-parcelize'到您的build.gradle(应用程序)中,如下所示:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'kotlin-parcelize' //here
}
Run Code Online (Sandbox Code Playgroud)
2. 创建一个类来包装您的 Lambda 函数:
@Parcelize
class Listener(val clickAction: () -> Unit) : Parcelable {
fun onClick() = clickAction()
}
Run Code Online (Sandbox Code Playgroud)
3. 传递您的 Lambda:
val bundle = Bundle().apply {
putParcelable("listener", Listener(clickAction))
}
private val clickAction: () -> Unit = {
//do your stuff
}
Run Code Online (Sandbox Code Playgroud)
4. 检索:
arguments?.getParcelable<Listener>("listener")?.onClick()
Run Code Online (Sandbox Code Playgroud)
演示(全部Fragment): https: //youtu.be/0OnaW4ZCnbk
如果tryAgainFunction是Serializable,则可以将其放入bundle使用中bundle.putSerializable("try_again_function", tryAgainFunction);。
实际上Serializable是函数引用(SomeClass::someFunction)还是lambda。但是,如果它是功能接口的某些自定义实现,则可能不是() -> Unit,所以您应该检查一下并处理不存在的情况。
也许为时已晚,但是:
你有没有试过把val callback里面的同伴对象?解决方案可能类似于:
companion object {
private lateinit var callback
fun newInstance(tryAgainFunction: () -> Unit): TimeOutHandlerFragment {
val fragment = TimeOutHandlerFragment()
this.callback = tryAgainFunction
return fragment
}
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btnTryAgain.setOnClickListener { callback.invoke() }
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3488 次 |
| 最近记录: |