Fragment与Fragment(或Activity)之间的监听器

3
有没有更好的方法在Fragment中放置监听器?
class FooFragment : Fragment() {

    companion object {
        private lateinit var listener: (Int) -> Unit

        fun newInstance(listener: (Int) -> Unit): FooFragment {
            Companion.listener = listener
            return FooFragment()
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_foo, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        btn.setOnClickListener {
            listener(1234)
        }
    }
}

这个调用看起来非常整洁...

FooFragment.newInstance {
    // Do something
}

我知道这段代码可能存在问题,因为在 Fragment 重新创建时可能会丢失监听器,而标准的做法是使用 onAttach(context: Context?) 方法。

但是我想要从其他 Fragment (不是一个 Activity)创建一个新的 FooFragment 实例。我可以使用类似于以下代码的东西:

private var listener: Listener? = null

interface Listener {
    fun onFooClicked()
}

override fun onAttach(context: Context?) {
    super.onAttach(context)
    // listener = context as Listener
    fragmentManager?.findFragmentById(R.id.fFooParent) as Listener
}

但是,FooFragmentonAttach(context: Context?) 方法内的这段代码将会起到反作用,因为我不想让 FooFragment 知道实例化它的类的任何信息。此外,我希望它可以是一个 Fragment 或一个 Activity


1
为什么不直接使用 LocalBroadcastManager 发送和接收广播?这是组件间通信的推荐方式。 - TheWanderer
这是一个好主意,但我想避免样板代码。 - Gabi Moreno
你正在做的事情相当基础。只需创建一个帮助方法,该方法接受 Int 参数并将其作为广播中的额外参数传递即可。 - TheWanderer
你可以使用 parentFragment as Listener 并在创建 Fragment 时使用 childFragmentManager,这样 Fragment 就不会知道创建它的 Fragment 的任何信息。 - AndreasReiff
1个回答

2
您可以创建一个实现监听器的baseActivity。
class BaseFragmentActivity:AppCompatActivity(), FooFragment.Listener{}

然后扩展class YouFragmentActivity : BaseFragmentActivity

这将确保每个托管活动的片段都配备了容器,然后您可以获取引用作为BaseFragmentActivity

您可以将AppCompatActivity替换为BaseActivity,其中BaseActivity:AppCompatActivity


如果我尝试在“Fragment”中实现接口,它会崩溃。另一方面,我不想创建一个具有许多需要在其子类中重写的方法的基本活动。这不是一个好的做法... - Gabi Moreno
1
你可以在内部类中引用监听器并在基础活动中创建一个setter,它可以接受一个引用并设置它,这将以多态的方式工作,将其转换为基础活动将使您可以访问引用以调用方法(或者如果您选择答案,则可以调用该方法),我认为这是一种干净的方式,我很想看到一些参考资料或文档,看看它是否不可行。虽然这是您的选择。 - Pavneet_Singh
1
你可以创建一个单独的接口,而不是内部类,并使用相同的方法来处理baseFragment类。 - Pavneet_Singh
1
看一下Fragment类,你会发现有许多接口可以与任何类型的片段和Android操作系统进行通信。 - Pavneet_Singh
1
使用静态监听器绝对是一种不好的做法。谢谢@Pavneet_Singh - Gabi Moreno
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接