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

huangapple go评论75阅读模式
英文:

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

问题

几乎在我阅读的所有文章中,人们都使用这种方法来在Fragment和Activity之间进行通信:

在您的活动和片段之间进行通信的最简单方式是使用接口。基本思想是在给定的片段A内定义一个接口,然后让活动实现该接口。

一旦它实现了该接口,您可以在它覆盖的方法中执行任何您想要的操作。

但是为什么人们要使用这种方法,而不是将Interfacefunction作为Fragment的构造函数参数传递,然后使用它呢?

我的意思是,我们可以在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()
        }
    }

}

然后在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()
    }

}

我认为第二种方法更好,因为我们可以进行依赖注入,而且不需要进行任何向上转型等操作。

英文:

Almost in all articles I've read people use this approach for communicating between Fragments and an Activity:

> The easiest way to communicate between your activity and fragments is
> using interfaces. The idea is basically to define an interface inside
> a given fragment A and let the activity implement that interface.
>
> 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?

I mean we can do something like this inside Fragment(I've used Kotlin functions as constructor parameter but we can also use 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:

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.

答案1

得分: 2

问题在于,在应用程序的生命周期内,系统可能需要销毁并重新创建您的片段,但它将调用没有参数的构造函数,因此您的onBtnAddCategoryClick将不会设置。因此,您需要从您的活动中设置它。这也是为什么您应该使用bundle在活动和片段之间传递数据的原因。

英文:

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. so you have to set that from your activity. This is also why you should pass the data between activities and fragments using bundle

huangapple
  • 本文由 发表于 2020年8月9日 00:04:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/63317501.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定