Fragment transaction: allow state loss when needed

This commit is contained in:
ganfra 2020-09-15 12:36:27 +02:00
parent 94a7db26f5
commit 624a8ff04c
5 changed files with 46 additions and 40 deletions

View file

@ -22,36 +22,37 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
fun VectorBaseActivity.addFragment(frameId: Int, fragment: Fragment) { fun VectorBaseActivity.addFragment(frameId: Int, fragment: Fragment, allowStateLoss: Boolean = false) {
supportFragmentManager.commitTransaction { add(frameId, fragment) } supportFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment) }
} }
fun <T : Fragment> VectorBaseActivity.addFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) { fun <T : Fragment> VectorBaseActivity.addFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null, allowStateLoss: Boolean = false) {
supportFragmentManager.commitTransaction { supportFragmentManager.commitTransaction(allowStateLoss) {
add(frameId, fragmentClass, params.toMvRxBundle(), tag) add(frameId, fragmentClass, params.toMvRxBundle(), tag)
} }
} }
fun VectorBaseActivity.replaceFragment(frameId: Int, fragment: Fragment, tag: String? = null) { fun VectorBaseActivity.replaceFragment(frameId: Int, fragment: Fragment, tag: String? = null, allowStateLoss: Boolean = false) {
supportFragmentManager.commitTransaction { replace(frameId, fragment, tag) } supportFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment, tag) }
} }
fun <T : Fragment> VectorBaseActivity.replaceFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) { fun <T : Fragment> VectorBaseActivity.replaceFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null, allowStateLoss: Boolean = false) {
supportFragmentManager.commitTransaction { supportFragmentManager.commitTransaction(allowStateLoss) {
replace(frameId, fragmentClass, params.toMvRxBundle(), tag) replace(frameId, fragmentClass, params.toMvRxBundle(), tag)
} }
} }
fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null, allowStateLoss: Boolean = false) {
supportFragmentManager.commitTransaction { replace(frameId, fragment).addToBackStack(tag) } supportFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment).addToBackStack(tag) }
} }
fun <T : Fragment> VectorBaseActivity.addFragmentToBackstack(frameId: Int, fun <T : Fragment> VectorBaseActivity.addFragmentToBackstack(frameId: Int,
fragmentClass: Class<T>, fragmentClass: Class<T>,
params: Parcelable? = null, params: Parcelable? = null,
tag: String? = null, tag: String? = null,
allowStateLoss: Boolean = false,
option: ((FragmentTransaction) -> Unit)? = null) { option: ((FragmentTransaction) -> Unit)? = null) {
supportFragmentManager.commitTransaction { supportFragmentManager.commitTransaction(allowStateLoss) {
option?.invoke(this) option?.invoke(this)
replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag)
} }

View file

@ -26,62 +26,62 @@ import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
fun VectorBaseFragment.addFragment(frameId: Int, fragment: Fragment) { fun VectorBaseFragment.addFragment(frameId: Int, fragment: Fragment, allowStateLoss: Boolean = false) {
parentFragmentManager.commitTransaction { add(frameId, fragment) } parentFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment) }
} }
fun <T : Fragment> VectorBaseFragment.addFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) { fun <T : Fragment> VectorBaseFragment.addFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null, allowStateLoss: Boolean = false) {
parentFragmentManager.commitTransaction { parentFragmentManager.commitTransaction(allowStateLoss) {
add(frameId, fragmentClass, params.toMvRxBundle(), tag) add(frameId, fragmentClass, params.toMvRxBundle(), tag)
} }
} }
fun VectorBaseFragment.replaceFragment(frameId: Int, fragment: Fragment) { fun VectorBaseFragment.replaceFragment(frameId: Int, fragment: Fragment, allowStateLoss: Boolean = false) {
parentFragmentManager.commitTransaction { replace(frameId, fragment) } parentFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment) }
} }
fun <T : Fragment> VectorBaseFragment.replaceFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) { fun <T : Fragment> VectorBaseFragment.replaceFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null, allowStateLoss: Boolean = false) {
parentFragmentManager.commitTransaction { parentFragmentManager.commitTransaction(allowStateLoss) {
replace(frameId, fragmentClass, params.toMvRxBundle(), tag) replace(frameId, fragmentClass, params.toMvRxBundle(), tag)
} }
} }
fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null, allowStateLoss: Boolean = false) {
parentFragmentManager.commitTransaction { replace(frameId, fragment, tag).addToBackStack(tag) } parentFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment, tag).addToBackStack(tag) }
} }
fun <T : Fragment> VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) { fun <T : Fragment> VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null, allowStateLoss: Boolean = false) {
parentFragmentManager.commitTransaction { parentFragmentManager.commitTransaction(allowStateLoss) {
replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag)
} }
} }
fun VectorBaseFragment.addChildFragment(frameId: Int, fragment: Fragment, tag: String? = null) { fun VectorBaseFragment.addChildFragment(frameId: Int, fragment: Fragment, tag: String? = null, allowStateLoss: Boolean = false) {
childFragmentManager.commitTransaction { add(frameId, fragment, tag) } childFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment, tag) }
} }
fun <T : Fragment> VectorBaseFragment.addChildFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) { fun <T : Fragment> VectorBaseFragment.addChildFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null, allowStateLoss: Boolean = false) {
childFragmentManager.commitTransaction { childFragmentManager.commitTransaction(allowStateLoss) {
add(frameId, fragmentClass, params.toMvRxBundle(), tag) add(frameId, fragmentClass, params.toMvRxBundle(), tag)
} }
} }
fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragment: Fragment, tag: String? = null) { fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragment: Fragment, tag: String? = null, allowStateLoss: Boolean = false) {
childFragmentManager.commitTransaction { replace(frameId, fragment, tag) } childFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment, tag) }
} }
fun <T : Fragment> VectorBaseFragment.replaceChildFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) { fun <T : Fragment> VectorBaseFragment.replaceChildFragment(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null, allowStateLoss: Boolean = false) {
childFragmentManager.commitTransaction { childFragmentManager.commitTransaction(allowStateLoss) {
replace(frameId, fragmentClass, params.toMvRxBundle(), tag) replace(frameId, fragmentClass, params.toMvRxBundle(), tag)
} }
} }
fun VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { fun VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null, allowStateLoss: Boolean = false) {
childFragmentManager.commitTransaction { replace(frameId, fragment).addToBackStack(tag) } childFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment).addToBackStack(tag) }
} }
fun <T : Fragment> VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null) { fun <T : Fragment> VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragmentClass: Class<T>, params: Parcelable? = null, tag: String? = null, allowStateLoss: Boolean = false) {
childFragmentManager.commitTransaction { childFragmentManager.commitTransaction(allowStateLoss) {
replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag)
} }
} }

View file

@ -27,6 +27,11 @@ inline fun androidx.fragment.app.FragmentManager.commitTransactionNow(func: Frag
} }
} }
inline fun androidx.fragment.app.FragmentManager.commitTransaction(func: FragmentTransaction.() -> FragmentTransaction) { inline fun androidx.fragment.app.FragmentManager.commitTransaction(allowStateLoss: Boolean = false, func: FragmentTransaction.() -> FragmentTransaction) {
beginTransaction().func().commit() val transaction = beginTransaction().func()
if (allowStateLoss) {
transaction.commitAllowingStateLoss()
} else {
transaction.commit()
}
} }

View file

@ -87,13 +87,13 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
viewModel.navigateEvent.observeEvent(this) { uxStateEvent -> viewModel.navigateEvent.observeEvent(this) { uxStateEvent ->
when (uxStateEvent) { when (uxStateEvent) {
KeysBackupRestoreSharedViewModel.NAVIGATE_TO_RECOVER_WITH_KEY -> { KeysBackupRestoreSharedViewModel.NAVIGATE_TO_RECOVER_WITH_KEY -> {
addFragmentToBackstack(R.id.container, KeysBackupRestoreFromKeyFragment::class.java) addFragmentToBackstack(R.id.container, KeysBackupRestoreFromKeyFragment::class.java, allowStateLoss = true)
} }
KeysBackupRestoreSharedViewModel.NAVIGATE_TO_SUCCESS -> { KeysBackupRestoreSharedViewModel.NAVIGATE_TO_SUCCESS -> {
viewModel.keyVersionResult.value?.version?.let { viewModel.keyVersionResult.value?.version?.let {
KeysBackupBanner.onRecoverDoneForVersion(this, it) KeysBackupBanner.onRecoverDoneForVersion(this, it)
} }
replaceFragment(R.id.container, KeysBackupRestoreSuccessFragment::class.java) replaceFragment(R.id.container, KeysBackupRestoreSuccessFragment::class.java, allowStateLoss = true)
} }
KeysBackupRestoreSharedViewModel.NAVIGATE_TO_4S -> { KeysBackupRestoreSharedViewModel.NAVIGATE_TO_4S -> {
launch4SActivity() launch4SActivity()

View file

@ -121,7 +121,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
is HomeActivitySharedAction.CloseDrawer -> drawerLayout.closeDrawer(GravityCompat.START) is HomeActivitySharedAction.CloseDrawer -> drawerLayout.closeDrawer(GravityCompat.START)
is HomeActivitySharedAction.OpenGroup -> { is HomeActivitySharedAction.OpenGroup -> {
drawerLayout.closeDrawer(GravityCompat.START) drawerLayout.closeDrawer(GravityCompat.START)
replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java) replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true)
} }
}.exhaustive }.exhaustive
} }