Status Update
Comments
il...@google.com <il...@google.com> #2
As a general note, what you're checking makes little sense - onAttachFragment
is called as fragments move through their lifecycle methods (specifically, right after onAttach()
is called on the fragment) and is therefore likely to be called while FragmentTransactions are being processed - if you have multiple commit()
s in flight, the state you get back in onAttachFragment
will certainly not be the final state the FragmentManager will be when all of the FragmentTransactions are executed, making this a bit of a meaningless check.
That being said, this is caused by the mechanism used to kick off transitions when reordering is not allowed, which is being reworked in
As a workaround, you can use setReorderingAllowed(true)
on your transaction, which will allow your example project to work correctly.
il...@google.com <il...@google.com> #3
This has been fixed internally and will be avilable in Fragment 1.3.0-alpha08.
Note: this fix relies on using the
Description
androidx.appcompat:appcompat:1.1.0
androidx.fragment:fragment:1.3.0-alpha03
Theme used: Theme.AppCompat.Light.DarkActionBar
Devices/Android versions reproduced on: Pixel 4 (RP1A.200115.001.C1)
Recreating this issue per comment on
Minimal code to reproduce is below. Clicking on the displayed button will cause a crash, as the prior expectation was that in onAttachFragment(), the FragmentManager will contain the Fragment that is passed as a parameter to onAttachFragment(), but this is no longer the case.
_______________
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams
import android.widget.Button
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
private const val FRAGMENT_TAG = "tag"
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
.add(android.R.id.content, StartingFragment(), FRAGMENT_TAG)
.commit()
}
}
override fun onAttachFragment(fragment: Fragment) {
super.onAttachFragment(fragment)
val fragmentByTag = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG)
if (fragment != fragmentByTag) {
throw IllegalStateException("Expected $fragment but found $fragmentByTag")
}
}
fun replaceFragment() {
supportFragmentManager
.beginTransaction()
.replace(android.R.id.content, ReplacementFragment(), FRAGMENT_TAG)
.addToBackStack(null)
.commit()
}
class StartingFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return Button(requireContext()).apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
text = "Replace fragment"
setOnClickListener {
(requireActivity() as MainActivity).replaceFragment()
}
}
}
}
class ReplacementFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return ImageView(requireContext()).apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
setBackgroundColor(Color.BLUE)
}
}
}
}