-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WorkflowLayout.start needs a Lifecycle, BackStackScreen is supported.
On a lot of Samsung devices running Anroid 12 / API 30, the sketchy `WorkflowLayout.takeWhileAttached` method at the heart of `WorkflowLayout.start` was having surprising effects -- we'd see redundant calls to `OnAttachStateChangeListener.onViewAttachedToWindow`. The problem goes away if we get more conventional and use the new `repeatOnLifecycle` function as described in [this blog post](https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda). The old methods are deprecated and will be deleted soon. Making this change required making our `BackPressHandler` mechanism more robust, as it too was pretending that `OnAttachStateChangeListener` was an adequate lifecycle. Specifically, we were relying on `onViewAttachedToWindow` to be called in a predicable order, which stopped being the case with the move away from `WorkflowLayout.takeWhileAttached`. This PR changes things so that… - We register handlers immediately, so that we can count on them being stacked in the expected order - We lean on `OnAttachStateChangeListener` solely to enable and disable the `BackPressHandler` associated with a view - And take advantage of our recently added support for `ViewTreeLifecycleOwner` for clean up `ModalContainer`'s contribution to coping with the back button also had to be beefed up, for similar reasons. It needs to ensure that back button events are blocked by modal windows, just like any other event, which is tricky with the singleton `OnBackPressedDispatcher` that androidx provides. It does this by putting a no-op handler in place as a backstop for any set by modal renderings. Its bespoke code for doing this was also inadvertently relying on the order of `onViewAttachedToWindow` calls. We now achieve this by wrapping modal renderings with a reliable `BackStackScreen`, which is promoted from the sample container set.
- Loading branch information
Showing
23 changed files
with
157 additions
and
106 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
23 changes: 0 additions & 23 deletions
23
samples/containers/android/src/main/java/com/squareup/sample/container/BackButtonScreen.kt
This file was deleted.
Oops, something went wrong.
31 changes: 0 additions & 31 deletions
31
...s/containers/android/src/main/java/com/squareup/sample/container/BackButtonViewFactory.kt
This file was deleted.
Oops, something went wrong.
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
43 changes: 43 additions & 0 deletions
43
workflow-ui/core-android/src/main/java/com/squareup/workflow1/ui/BackButtonScreen.kt
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.squareup.workflow1.ui | ||
|
||
/** | ||
* Adds optional back button handling to a [wrapped] rendering, possibly overriding that | ||
* the wrapped rendering's own back button handler. | ||
* | ||
* @param override If `true`, [onBackPressed] is set as the | ||
* [backPressedHandler][android.view.View.backPressedHandler] after | ||
* the [wrapped] rendering's view is built / updated, effectively overriding it. | ||
* If false, [onBackPressed] is set afterward, to allow the wrapped rendering to | ||
* take precedence if it sets a `backPressedHandler` of its own . | ||
* Defaults to `false`. | ||
* | ||
* @param onBackPressed The function to fire when the device back button | ||
* is pressed, or null to set no handler -- or clear a handler that was set previously. | ||
* Defaults to `null`. | ||
*/ | ||
@WorkflowUiExperimentalApi | ||
public class BackButtonScreen<W : Any>( | ||
public val wrapped: W, | ||
public val override: Boolean = false, | ||
public val onBackPressed: (() -> Unit)? = null | ||
) : AndroidViewRendering<BackButtonScreen<*>> { | ||
override val viewFactory: ViewFactory<BackButtonScreen<*>> = DecorativeViewFactory( | ||
type = BackButtonScreen::class, | ||
map = { outer -> outer.wrapped }, | ||
doShowRendering = { view, innerShowRendering, outerRendering, viewEnvironment -> | ||
if (!outerRendering.override) { | ||
// Place our handler before invoking innerShowRendering, so that | ||
// its later calls to view.backPressedHandler will take precedence | ||
// over ours. | ||
view.backPressedHandler = outerRendering.onBackPressed | ||
} | ||
|
||
innerShowRendering.invoke(outerRendering.wrapped, viewEnvironment) | ||
|
||
if (outerRendering.override) { | ||
// Place our handler after invoking innerShowRendering, so that ours wins. | ||
view.backPressedHandler = outerRendering.onBackPressed | ||
} | ||
} | ||
) | ||
} |
Oops, something went wrong.