Last active
August 30, 2020 15:35
-
-
Save discord-gists/48353e5b174475aa8254a9c01efbeb8f to your computer and use it in GitHub Desktop.
a simplified code example of how Discord's Android app maintains panel states through device rotations while applying view updates before onLayout
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class OverlappingPanelsLayout: FrameLayout { | |
private lateinit var startPanel: View | |
private lateinit var centerPanel: View | |
private lateinit var endPanel: View | |
private var pendingUpdate: (() -> Unit)? = null | |
... | |
private fun openStartPanel() { | |
// This can get called before onLayout() where centerPanel | |
// gets initialized. If that happens, save the pendingUpdate | |
// for after centerPanel gets initialized. | |
if (!::centerPanel.isInitialized) { | |
pendingUpdate = { openStartPanel(isFling) } | |
return | |
} | |
updateCenterPanelX(x = startPanelOpenedCenterPanelX) | |
} | |
override fun onLayout( | |
changed: Boolean, | |
left: Int, | |
top: Int, | |
right: Int, | |
bottom: Int | |
) { | |
super.onLayout(changed, left, top, right, bottom) | |
// OverlappingPanelsLayout expects exactly three child | |
// views where each child view is a panel. If there are | |
// not exactly three child views, OverlappingPanelsLayout will | |
// throw an exception. | |
if (!::centerPanel.isInitialized) { | |
startPanel = getChildAt(0) | |
centerPanel = getChildAt(1) | |
endPanel = getChildAt(2) | |
pendingUpdate?.invoke() | |
pendingUpdate = null | |
... | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
epic