在 Fragment 和 Android 中的 Activity 之间通信的最佳方式是什么?
What is the best way of communicating between a Fragment and an Activity in Android?
几乎在我读过的所有文章中,人们都使用 this approach 在 Fragment 和 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.
但是为什么人们使用这种方法,而我们可以将 Interface
或 function
作为 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()
}
}
我认为第二种方法更好,因为我们可以做到 Dependency-Injection
而且不需要做任何 upcasting
等等
问题在于,在您的应用程序生命周期中,系统可能需要再次销毁并重新创建您的片段,但它会调用不带参数的构造函数,因此您的 onBtnAddCategoryClick
不会设置。所以你必须从你的 activity 中设置它。这也是为什么您应该使用 bundle
在活动和片段之间传递数据的原因
几乎在我读过的所有文章中,人们都使用 this approach 在 Fragment 和 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.
但是为什么人们使用这种方法,而我们可以将 Interface
或 function
作为 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()
}
}
我认为第二种方法更好,因为我们可以做到 Dependency-Injection
而且不需要做任何 upcasting
等等
问题在于,在您的应用程序生命周期中,系统可能需要再次销毁并重新创建您的片段,但它会调用不带参数的构造函数,因此您的 onBtnAddCategoryClick
不会设置。所以你必须从你的 activity 中设置它。这也是为什么您应该使用 bundle