简体   繁体   English

Android 中的 Fragment 和 Activity 之间通信的最佳方式是什么?

[英]What is the best way of communicating between a Fragment and an Activity in Android?

Almost in all articles I've read people use this approach for communicating between Fragments and an Activity:几乎在我读过的所有文章中,人们都使用这种方法在 Fragment 和 Activity 之间进行通信:

The easiest way to communicate between your activity and fragments is using interfaces.在 Activity 和 Fragment 之间进行通信的最简单方法是使用接口。 The idea is basically to define an interface inside a given fragment A and let the activity implement that interface.这个想法基本上是在给定的片段 A 中定义一个接口,并让活动实现该接口。

Once it has implemented that interface, you could do anything you want in the method it overrides.一旦它实现了那个接口,你就可以在它覆盖的方法中做任何你想做的事情。

But Why does people use this approach while we can pass an Interface or a function as constructor parameter of Fragment and then use it?但是为什么人们使用这种方法,而我们可以传递一个Interface或一个function作为 Fragment 的构造函数参数然后使用它?

I mean we can do something like this inside Fragment(I've used Kotlin functions as constructor parameter but we can also use Interfaces ):我的意思是我们可以在 Fragment 中做这样的事情(我使用 Kotlin 函数作为构造函数参数,但我们也可以使用Interfaces ):

class CategoryListFragment(private val onBtnAddCategoryClick: () -> Unit) : Fragment() {

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        fab_add_category.setOnClickListener {
            onBtnAddCategoryClick()
        }
    }

}

and use it like this inside Activity:并在 Activity 中像这样使用它:

class MainActivity : AppCompatActivity() {

    companion object{
        const val TAG_ADD_CATEGORY_DIALOG = "TAG_ADD_CATEGORY_DIALOG"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        val fragmentTransaction = supportFragmentManager.beginTransaction()
        fragmentTransaction.replace(R.id.container, CategoryListFragment{
            Toast.makeText(this@MainActivity, "show add category", Toast.LENGTH_SHORT).show()
        })
        fragmentTransaction.commit()
    }

}

I think the second approach is better as we can do Dependency-Injection and also it's not required to do any upcasting etc.我认为第二种方法更好,因为我们可以进行Dependency-Injection ,并且不需要进行任何upcasting等。

the problem is that during your application life cycle the system may need to destroy and recreate your fragment again but it will call the constructor with no parameters so your onBtnAddCategoryClick will not set.问题是在您的应用程序生命周期中,系统可能需要再次销毁并重新创建您的片段,但它会调用不带参数的构造函数,因此您的onBtnAddCategoryClick不会设置。 so you have to set that from your activity.所以你必须从你的活动中设置它。 This is also why you should pass the data between activities and fragments using bundle这也是为什么您应该使用bundle在活动和片段之间传递数据的原因

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM