Create fragments
The wrong sample
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager.beginTransaction()
.replace(R.id.container, NewFragment())
.commit()
}
Copy the code
The problem
In the above code, when the Activity is destroyed and restored, a new Fragment is created.
The correct sample
We should use 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()
}
}
Copy the code
Create all objects of the Fragment in onCreateView
The wrong sample
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)}Copy the code
The problem
When the Fragment is replaced by a Fragment in another container, the Fragment is not destroyed. The data object in the Fragment is still there. When the Fragment is restored, onCreateView is called again and the data in the Fragment is reset.
The correct sample
We should create all the Fragment data objects in onCreate.
private var presenter: MyPresenter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
presenter = MyPresenter()
}
Copy the code
Save the Fragment in the Activity
The wrong sample
Sometimes, we save the Fragment in the Activity so that we can call the methods in the Fragment.
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() }Copy the code
The problem
The Fragment has a lifetime, it is destroyed by the system, and the reference in the Activity does not exist. We need to make sure that the correct reference to the Fragment is constantly updated.
The correct sample
Use 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() }Copy the code
Use the simple class name as the TAG for the Fragment
The wrong sample
supportFragmentManager.beginTransaction()
.replace(
R.id.container,
fragment,
fragment.javaClass.simpleName)
.commit()
Copy the code
The problem
In Android, we use Proguard or DexGuard to obscure class names. Along the way, obscure simple names can conflict with other class names.
The danger of using getSimpleName() as TAG for Fragment
The correct sample
supportFragmentManager.beginTransaction()
.replace(
R.id.container,
fragment,
fragment.javaClass.canonicalName)
.commit()
Copy the code
reference
7 Common Mistakes Easily Made with Android Fragment