ui: fix back listener leak
Fix an issue where the OnBackPressedListeners would leak their bound views once MainFragment's view was destroyed.
This commit is contained in:
parent
736f3ec6b7
commit
d49034b664
1 changed files with 26 additions and 12 deletions
|
@ -81,10 +81,10 @@ class MainFragment :
|
||||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
private val selectionModel: SelectionViewModel by activityViewModels()
|
private val selectionModel: SelectionViewModel by activityViewModels()
|
||||||
private val detailModel: DetailViewModel by activityViewModels()
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
private lateinit var sheetBackCallback: SheetBackPressedCallback
|
private var sheetBackCallback: SheetBackPressedCallback? = null
|
||||||
private lateinit var detailBackCallback: DetailBackPressedCallback
|
private var detailBackCallback: DetailBackPressedCallback? = null
|
||||||
private lateinit var selectionBackCallback: SelectionBackPressedCallback
|
private var selectionBackCallback: SelectionBackPressedCallback? = null
|
||||||
private lateinit var exploreBackCallback: ExploreBackPressedCallback
|
private var exploreBackCallback: ExploreBackPressedCallback? = null
|
||||||
private var lastInsets: WindowInsets? = null
|
private var lastInsets: WindowInsets? = null
|
||||||
private var elevationNormal = 0f
|
private var elevationNormal = 0f
|
||||||
private var initialNavDestinationChange = true
|
private var initialNavDestinationChange = true
|
||||||
|
@ -110,13 +110,17 @@ class MainFragment :
|
||||||
// Currently all back press callbacks are handled in MainFragment, as it's not guaranteed
|
// Currently all back press callbacks are handled in MainFragment, as it's not guaranteed
|
||||||
// that instantiating these callbacks in their respective fragments would result in the
|
// that instantiating these callbacks in their respective fragments would result in the
|
||||||
// correct order.
|
// correct order.
|
||||||
sheetBackCallback =
|
val sheetBackCallback =
|
||||||
SheetBackPressedCallback(
|
SheetBackPressedCallback(
|
||||||
playbackSheetBehavior = playbackSheetBehavior,
|
playbackSheetBehavior = playbackSheetBehavior,
|
||||||
queueSheetBehavior = queueSheetBehavior)
|
queueSheetBehavior = queueSheetBehavior)
|
||||||
detailBackCallback = DetailBackPressedCallback(detailModel)
|
.also { sheetBackCallback = it }
|
||||||
selectionBackCallback = SelectionBackPressedCallback(selectionModel)
|
val detailBackCallback =
|
||||||
exploreBackCallback = ExploreBackPressedCallback(binding.exploreNavHost)
|
DetailBackPressedCallback(detailModel).also { detailBackCallback = it }
|
||||||
|
val selectionBackCallback =
|
||||||
|
SelectionBackPressedCallback(selectionModel).also { selectionBackCallback = it }
|
||||||
|
val exploreBackCallback =
|
||||||
|
ExploreBackPressedCallback(binding.exploreNavHost).also { exploreBackCallback = it }
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
val context = requireActivity()
|
val context = requireActivity()
|
||||||
|
@ -202,6 +206,14 @@ class MainFragment :
|
||||||
binding.playbackSheet.viewTreeObserver.removeOnPreDrawListener(this)
|
binding.playbackSheet.viewTreeObserver.removeOnPreDrawListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroyBinding(binding: FragmentMainBinding) {
|
||||||
|
super.onDestroyBinding(binding)
|
||||||
|
sheetBackCallback = null
|
||||||
|
detailBackCallback = null
|
||||||
|
selectionBackCallback = null
|
||||||
|
exploreBackCallback = null
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPreDraw(): Boolean {
|
override fun onPreDraw(): Boolean {
|
||||||
// We overload CoordinatorLayout far too much to rely on any of it's typical
|
// We overload CoordinatorLayout far too much to rely on any of it's typical
|
||||||
// listener functionality. Just update all transitions before every draw. Should
|
// listener functionality. Just update all transitions before every draw. Should
|
||||||
|
@ -287,7 +299,8 @@ class MainFragment :
|
||||||
|
|
||||||
// Since the navigation listener is also reliant on the bottom sheets, we must also update
|
// Since the navigation listener is also reliant on the bottom sheets, we must also update
|
||||||
// it every frame.
|
// it every frame.
|
||||||
sheetBackCallback.invalidateEnabled()
|
requireNotNull(sheetBackCallback) { "SheetBackPressedCallback was not available" }
|
||||||
|
.invalidateEnabled()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -300,7 +313,8 @@ class MainFragment :
|
||||||
// Drop the initial call by NavController that simply provides us with the current
|
// Drop the initial call by NavController that simply provides us with the current
|
||||||
// destination. This would cause the selection state to be lost every time the device
|
// destination. This would cause the selection state to be lost every time the device
|
||||||
// rotates.
|
// rotates.
|
||||||
exploreBackCallback.invalidateEnabled()
|
requireNotNull(exploreBackCallback) { "ExploreBackPressedCallback was not available" }
|
||||||
|
.invalidateEnabled()
|
||||||
if (!initialNavDestinationChange) {
|
if (!initialNavDestinationChange) {
|
||||||
initialNavDestinationChange = true
|
initialNavDestinationChange = true
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in a new issue