创建Fragment
错误示例
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager.beginTransaction()
.replace(R.id.container, NewFragment())
.commit()
}
问题
上面的代码,当Activity被系统销毁恢复时,一个新的Fragment将会被创建。
正确示例
我们应该使用savedInstanceState == null去判断。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, NewFragment())
.commit()
}
}
在onCreateView 中创建Fragment的所有对象
错误示例
private var presenter: MyPresenter? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
presenter = MyPresenter()
return inflater.inflate(R.layout.frag_layout, container, false)
}
问题
当Fragment被另一个容器中的Fragment替换,Fragment不会被销毁,Fragment里面的数据对象还在, 当Fragment被恢复的时候,会再次调用onCreateView,里面的数据会被重置。
正确示例
我们应该在 onCreate 中创建Fragment所有的数据对象。
private var presenter: MyPresenter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
presenter = MyPresenter()
}
在Activity中保存Fragment
错误示例
有时候,我们为了可以调用Fragment里面的方法,通常会保存Fragment在Activity里面。
private var myFragment: MyFragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
myFragment = NewFragment()
supportFragmentManager.beginTransaction()
.replace(R.id.container, myFragment)
.commit()
}
}
private fun anotherFunction() {
myFragemnt?.doSomething()
}
问题
Fragment有他的生命周期,他被系统销毁,Activity里面的引用将不存在。我们需要确保不断更新对Fragment的正确引用。
正确示例
使用findFragmentByTag。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, NewFragment(), FragmentTag)
.commit()
}
}
private fun anotherFunction() {
(supportFragmentManager.findFragmentByTag(FragmentTag) as?
NewFragment)?.doSomething()
}
使用简单类名作为Fragment的TAG
错误示例
supportFragmentManager.beginTransaction()
.replace(
R.id.container,
fragment,
fragment.javaClass.simpleName)
.commit()
问题
在 Android 中,我们使用 Proguard 或 DexGuard 模糊类名。在整个过程中,模糊的简单名称可能与其他类名发生冲突。
The danger of using getSimpleName() as TAG for Fragment
正确示例
supportFragmentManager.beginTransaction()
.replace(
R.id.container,
fragment,
fragment.javaClass.canonicalName)
.commit()