Attempt to fix lifecycle crashes with bottom sheets

bs
Laurent 5 years ago
parent 44aad63b82
commit 50ff357afa
  1. 2
      app/build.gradle
  2. 22
      app/src/main/java/net/pokeranalytics/android/ui/activity/components/BaseActivity.kt
  3. 26
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/BaseFragment.kt
  4. 36
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt
  5. 3
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/CustomFieldDataFragment.kt
  6. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/EditableDataFragment.kt
  7. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/data/PlayerDataFragment.kt
  8. 5
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterDetailsFragment.kt
  9. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FiltersListFragment.kt
  10. 6
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorFragment.kt
  11. 7
      app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt
  12. 32
      app/src/main/java/net/pokeranalytics/android/ui/viewmodel/BottomSheetViewModel.kt

@ -99,7 +99,7 @@ dependencies {
implementation 'androidx.core:core-ktx:1.3.1' implementation 'androidx.core:core-ktx:1.3.1'
implementation 'com.google.android.material:material:1.1.0' implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.work:work-runtime-ktx:2.4.0' implementation 'androidx.work:work-runtime-ktx:2.4.0'
implementation 'com.google.android.play:core-ktx:1.8.1' // In-app Reviews implementation 'com.google.android.play:core-ktx:1.8.1' // In-app Reviews

@ -10,13 +10,20 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import io.realm.Realm import io.realm.Realm
import net.pokeranalytics.android.model.realm.Location import net.pokeranalytics.android.model.realm.Location
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.util.LocationManager import net.pokeranalytics.android.util.LocationManager
import net.pokeranalytics.android.util.PermissionRequest import net.pokeranalytics.android.util.PermissionRequest
import java.util.*
class RootBottomSheetViewModel: ViewModel() {
var rowRepresentable: RowRepresentable? = null
var delegate: RowRepresentableDelegate? = null
}
abstract class BaseActivity : AppCompatActivity() { abstract class BaseActivity : AppCompatActivity() {
@ -29,6 +36,19 @@ abstract class BaseActivity : AppCompatActivity() {
private var permissionRequest: PermissionRequest? = null private var permissionRequest: PermissionRequest? = null
val bottomSheetViewModel: RootBottomSheetViewModel by lazy {
ViewModelProvider(this).get(RootBottomSheetViewModel::class.java)
}
// var bottomSheetRow: RowRepresentable?
// get() { return this.bottomSheetViewModel.rowRepresentable }
// set(value) { this.bottomSheetViewModel.rowRepresentable = value }
fun setBottomSheetParameters(rowRepresentable: RowRepresentable, delegate: RowRepresentableDelegate) {
this.bottomSheetViewModel.rowRepresentable = rowRepresentable
this.bottomSheetViewModel.delegate = delegate
}
// Lifecycle // Lifecycle
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {

@ -7,7 +7,13 @@ import androidx.fragment.app.Fragment
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.activity.components.BaseActivity import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import java.io.File import java.io.File
import java.util.*
import kotlin.collections.ArrayList
abstract class BaseFragment : Fragment() { abstract class BaseFragment : Fragment() {
@ -132,4 +138,24 @@ abstract class BaseFragment : Fragment() {
*/ */
open fun getPhotos(files: ArrayList<File>) {} open fun getPhotos(files: ArrayList<File>) {}
fun showBottomSheet(row: RowRepresentable,
delegate: RowRepresentableDelegate,
rowRepresentableEditDescriptors: List<RowRepresentableEditDescriptor>?,
isClearable: Boolean? = true,
currentCurrency: Currency? = null,
isDeletable: Boolean? = false,
valueHasPlaceholder: Boolean? = null,
alternativeLabels: Boolean = false) {
BottomSheetFragment.create(activity as BaseActivity,
row,
delegate,
rowRepresentableEditDescriptors,
isClearable,
currentCurrency,
isDeletable,
valueHasPlaceholder,
alternativeLabels)
}
} }

@ -10,22 +10,23 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowManager import android.view.WindowManager
import androidx.appcompat.view.ContextThemeWrapper import androidx.appcompat.view.ContextThemeWrapper
import androidx.fragment.app.FragmentManager import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.fragment_bottom_sheet.* import kotlinx.android.synthetic.main.fragment_bottom_sheet.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.LiveData import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.ui.modules.data.EditableDataActivity
import net.pokeranalytics.android.ui.activity.components.BaseActivity import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.activity.components.RootBottomSheetViewModel
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.modules.data.EditableDataActivity
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import net.pokeranalytics.android.ui.view.rowrepresentable.TransactionRow import net.pokeranalytics.android.ui.view.rowrepresentable.TransactionRow
import net.pokeranalytics.android.ui.viewmodel.BottomSheetViewModel import net.pokeranalytics.android.ui.viewmodel.BottomSheetViewModel
import net.pokeranalytics.android.ui.viewmodel.BottomSheetViewModelFactory
import java.util.* import java.util.*
class BottomSheetConfig(var row: RowRepresentable, class BottomSheetConfig(var row: RowRepresentable,
@ -40,12 +41,9 @@ class BottomSheetConfig(var row: RowRepresentable,
open class BottomSheetFragment : BottomSheetDialogFragment() { open class BottomSheetFragment : BottomSheetDialogFragment() {
/** protected lateinit var model: BottomSheetViewModel
* A view model used to store potential bottom sheet values
*/ private lateinit var bottomSheetViewModel: RootBottomSheetViewModel
protected val model: BottomSheetViewModel by lazy {
ViewModelProviders.of(this).get(BottomSheetViewModel::class.java)
}
private var delegate: RowRepresentableDelegate? = null private var delegate: RowRepresentableDelegate? = null
@ -58,7 +56,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
const val REQUEST_CODE_ADD_NEW_OBJECT = 100 const val REQUEST_CODE_ADD_NEW_OBJECT = 100
fun create( fun create(
fragmentManager: FragmentManager, activity: BaseActivity,
row: RowRepresentable, row: RowRepresentable,
delegate: RowRepresentableDelegate, delegate: RowRepresentableDelegate,
rowRepresentableEditDescriptors: List<RowRepresentableEditDescriptor>?, rowRepresentableEditDescriptors: List<RowRepresentableEditDescriptor>?,
@ -69,7 +67,8 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
alternativeLabels: Boolean = false alternativeLabels: Boolean = false
): BottomSheetFragment { ): BottomSheetFragment {
val bottomSheetFragment = newInstance(row.bottomSheetType) val bottomSheetFragment = newInstance(row.bottomSheetType)
bottomSheetFragment.show(fragmentManager, "bottomSheet") activity.setBottomSheetParameters(row, delegate)
bottomSheetFragment.show(activity.supportFragmentManager, "bottomSheet")
this.config = BottomSheetConfig(row, delegate, rowRepresentableEditDescriptors, isClearable, currentCurrency, isDeletable, valueHasPlaceholder, alternativeLabels) this.config = BottomSheetConfig(row, delegate, rowRepresentableEditDescriptors, isClearable, currentCurrency, isDeletable, valueHasPlaceholder, alternativeLabels)
return bottomSheetFragment return bottomSheetFragment
} }
@ -99,6 +98,21 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
return inflater.cloneInContext(contextThemeWrapper).inflate(R.layout.fragment_bottom_sheet, container, false) return inflater.cloneInContext(contextThemeWrapper).inflate(R.layout.fragment_bottom_sheet, container, false)
} }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val row = config?.row
?: (requireActivity() as? BaseActivity)?.bottomSheetViewModel?.rowRepresentable
?: throw PAIllegalStateException("row not found")
val delegate = config?.delegate
?: (requireActivity() as? BaseActivity)?.bottomSheetViewModel?.delegate
?: throw PAIllegalStateException("delegate not found")
val factory = BottomSheetViewModelFactory(row, delegate)
this.model = ViewModelProvider(requireActivity(), factory).get(BottomSheetViewModel::class.java)
this.model.clear()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)

@ -13,6 +13,7 @@ import kotlinx.android.synthetic.main.fragment_custom_view.*
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.CustomField import net.pokeranalytics.android.model.realm.CustomField
import net.pokeranalytics.android.model.realm.CustomFieldEntry import net.pokeranalytics.android.model.realm.CustomFieldEntry
import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.extensions.ChipGroupExtension import net.pokeranalytics.android.ui.extensions.ChipGroupExtension
@ -159,7 +160,7 @@ class CustomFieldDataFragment : EditableDataFragment(), StaticRowRepresentableDa
when (row) { when (row) {
is CustomFieldEntry -> { is CustomFieldEntry -> {
val data = customField.editDescriptors(row) val data = customField.editDescriptors(row)
BottomSheetFragment.create(requireFragmentManager(), row, this, data, isClearable = false, isDeletable = true) showBottomSheet(row, this, data, isClearable = false, isDeletable = true)
} }
else -> super.onRowSelected(position, row, tag) else -> super.onRowSelected(position, row, tag)
} }

@ -63,7 +63,7 @@ open class EditableDataFragment : DataManagerFragment(), RowRepresentableDelegat
} }
override fun onRowSelected(position: Int, row: RowRepresentable, tag: Int) { override fun onRowSelected(position: Int, row: RowRepresentable, tag: Int) {
BottomSheetFragment.create(requireFragmentManager(), row, this, getDataSource().editDescriptors(row), valueHasPlaceholder = true) showBottomSheet(row, this, getDataSource().editDescriptors(row), valueHasPlaceholder = true)
} }
override fun onRowValueChanged(value: Any?, row: RowRepresentable) { override fun onRowValueChanged(value: Any?, row: RowRepresentable) {

@ -134,7 +134,7 @@ class PlayerDataFragment : EditableDataFragment(), StaticRowRepresentableDataSou
PlayerRow.IMAGE -> openPictureDialog() PlayerRow.IMAGE -> openPictureDialog()
is Comment -> { is Comment -> {
val data = arrayListOf(RowRepresentableEditDescriptor(row.content)) val data = arrayListOf(RowRepresentableEditDescriptor(row.content))
BottomSheetFragment.create(requireFragmentManager(), row, this, data, isClearable = false, isDeletable = true) showBottomSheet(row, this, data, isClearable = false, isDeletable = true)
} }
else -> super.onRowSelected(position, row, tag) else -> super.onRowSelected(position, row, tag)
} }

@ -15,7 +15,6 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.helpers.DateTimePickerManager import net.pokeranalytics.android.ui.helpers.DateTimePickerManager
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.RowViewType
@ -142,7 +141,7 @@ open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSo
minutes = if (it % 60 > 0) (it % 60).toString() else null minutes = if (it % 60 > 0) (it % 60).toString() else null
} }
val data = row.editingDescriptors(mapOf("hours" to hours, "minutes" to minutes)) val data = row.editingDescriptors(mapOf("hours" to hours, "minutes" to minutes))
BottomSheetFragment.create(requireFragmentManager(), row, this, data, true) showBottomSheet(row, this, data, true)
} }
is QueryCondition.ListOfValues<*> -> { is QueryCondition.ListOfValues<*> -> {
var valueAsString: String? = null var valueAsString: String? = null
@ -150,7 +149,7 @@ open class FilterDetailsFragment : RealmFragment(), StaticRowRepresentableDataSo
valueAsString = row.listOfValues.firstOrNull()?.toString() valueAsString = row.listOfValues.firstOrNull()?.toString()
} }
val data = row.editingDescriptors(mapOf("valueAsString" to valueAsString)) val data = row.editingDescriptors(mapOf("valueAsString" to valueAsString))
BottomSheetFragment.create(requireFragmentManager(), row, this, data, true) showBottomSheet(row, this, data, true)
} }
} }
} }

@ -46,7 +46,7 @@ open class FiltersListFragment : DataListFragment() {
is Filter -> { is Filter -> {
if (tag == 1) { if (tag == 1) {
val data = row.editingDescriptors(mapOf("defaultValue" to row.name)) val data = row.editingDescriptors(mapOf("defaultValue" to row.name))
BottomSheetFragment.create(requireFragmentManager(), row, this, data, false, isDeletable = true, valueHasPlaceholder = false) showBottomSheet(row, this, data, false, isDeletable = true, valueHasPlaceholder = false)
} else { } else {
val intent = Intent() val intent = Intent()
intent.putExtra(FiltersActivity.IntentKey.FILTER_ID.keyName, row.id) intent.putExtra(FiltersActivity.IntentKey.FILTER_ID.keyName, row.id)

@ -376,8 +376,7 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
when (row) { when (row) {
HandRowType.PLAYER_NUMBER -> { HandRowType.PLAYER_NUMBER -> {
BottomSheetFragment.create( showBottomSheet(
requireFragmentManager(),
row, row,
this, this,
editDescriptors, editDescriptors,
@ -386,8 +385,7 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen
) )
} }
else -> { else -> {
BottomSheetFragment.create( showBottomSheet(
requireFragmentManager(),
row, row,
this, this,
editDescriptors, editDescriptors,

@ -28,12 +28,11 @@ import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.model.realm.Location import net.pokeranalytics.android.model.realm.Location
import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.utils.FavoriteSessionFinder import net.pokeranalytics.android.model.utils.FavoriteSessionFinder
import net.pokeranalytics.android.ui.modules.data.EditableDataActivity
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.RealmFragment import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.helpers.DateTimePickerManager import net.pokeranalytics.android.ui.helpers.DateTimePickerManager
import net.pokeranalytics.android.ui.modules.data.EditableDataActivity
import net.pokeranalytics.android.ui.modules.datalist.DataListActivity import net.pokeranalytics.android.ui.modules.datalist.DataListActivity
import net.pokeranalytics.android.ui.modules.handhistory.HandHistoryActivity import net.pokeranalytics.android.ui.modules.handhistory.HandHistoryActivity
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
@ -239,13 +238,13 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate {
} }
SessionRow.BANKROLL -> { SessionRow.BANKROLL -> {
BottomSheetFragment.create(requireFragmentManager(), row, this, data, false, session.currency) showBottomSheet(row, this, data, false, session.currency)
} }
SessionRow.HANDS -> { SessionRow.HANDS -> {
val hhIds = session.handHistories?.map { it.id }?.toTypedArray() val hhIds = session.handHistories?.map { it.id }?.toTypedArray()
DataListActivity.newInstance(this, LiveData.HAND_HISTORY, false, hhIds, false) DataListActivity.newInstance(this, LiveData.HAND_HISTORY, false, hhIds, false)
} }
else -> BottomSheetFragment.create(requireFragmentManager(), row, this, data, currentCurrency = session.currency) else -> showBottomSheet(row, this, data, currentCurrency = session.currency)
} }
} }

@ -1,19 +1,29 @@
package net.pokeranalytics.android.ui.viewmodel package net.pokeranalytics.android.ui.viewmodel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import io.realm.RealmList import io.realm.RealmList
import io.realm.RealmResults import io.realm.RealmResults
import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import java.util.* import java.util.*
class BottomSheetViewModel : ViewModel() { class BottomSheetViewModelFactory(var row: RowRepresentable, var delegate: RowRepresentableDelegate): ViewModelProvider.Factory {
lateinit var row: RowRepresentable override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return modelClass.getConstructor(RowRepresentable::class.java).newInstance(row)
}
}
class BottomSheetViewModel(var row: RowRepresentable) : ViewModel() {
// lateinit var row: RowRepresentable
var currentCurrency: Currency? = null var currentCurrency: Currency? = null
var valueAsPlaceholder: Boolean = false var valueAsPlaceholder: Boolean = false
@ -21,6 +31,24 @@ class BottomSheetViewModel : ViewModel() {
var isDeletable: Boolean = false var isDeletable: Boolean = false
var rowRepresentableEditDescriptors: List<RowRepresentableEditDescriptor>? = null var rowRepresentableEditDescriptors: List<RowRepresentableEditDescriptor>? = null
fun clear() {
this.addedData = null
this.stringValue = null
this.secondStringValue = null
this.values.clear()
this.isEditingBlinds = false
this.realmData = null
this.staticRows = listOf()
this.doubleValue = 0.0
this.currentDefaultValue = 0.0
this.defaultSize = null
this.alternativeLabels = false
this.selectedRows.clear()
this.someValues.clear()
this.limit = 0
}
/** /**
* Storage for a data that has been newly created * Storage for a data that has been newly created
*/ */

Loading…
Cancel
Save