[Android] Expose view - #446
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
e0a0dbe to
20c3336
Compare
4f70c63 to
a7833d1
Compare
20c3336 to
8a96e85
Compare
| * connectivity. Its parent owns presentation state, geometry, and dismissal gestures. Call | ||
| * [destroy] when the view is permanently removed so the underlying WebView is released promptly. | ||
| */ | ||
| @SuppressLint("ViewConstructor") |
There was a problem hiding this comment.
CheckoutView intentionally lacks Android’s standard XML-inflatable constructors:
- View(context)
- View(context, attrs)
- View(context, attrs, defStyleAttr)
CheckoutView instead requires runtime state immediately:
CheckoutView(context, checkoutUrl, listener, protocolClient)
Without the suppression, lint warns because subclasses of View are normally expected to support XML inflation.
The practical consequence is that this will not work:
<com.shopify.checkoutkit.CheckoutView ... />
But direct construction and Compose’s AndroidView(factory = …) work normally. The annotation only silences that specific static-analysis warning; it changes no runtime behaviour.
| preloadCache.invalidate() | ||
| null | ||
| } | ||
| check(Looper.myLooper() == Looper.getMainLooper()) { |
There was a problem hiding this comment.
This is internal..
The responsibility is on the caller to run call on the main thread.
Rationale - the whole CheckoutView is UI construction. The whole thing should be on the UI thread, not just this internal WebView creation part.
Annotating the constructors for the View with @mainthread
Compose's AndroidView.factory already runs on the UI thread
| CheckoutWebView(activity as Context, webMessageTransport).apply { | ||
| loadCheckout(url) | ||
| } | ||
| return cachedView ?: run { |
There was a problem hiding this comment.
small refactor to avoid the non-null assert
8a96e85 to
128e067
Compare

What changes are you making?
Introduces
CheckoutView, a new publicFrameLayoutsubclass that lets host apps embed Shopify checkout inside their own presentation container (e.g. a Jetpack ComposeModalBottomSheet) rather than relying solely on the imperativeShopifyCheckoutKit.presentAPI.CheckoutViewowns theThe host retains full control over sheet geometry, scrim, drag handle, snap points, and dismissal gestures. The view can be constructed directly for View-system and Java hosts, or created via the
CheckoutView.createKotlin builder that accepts the sameCheckoutPresentationDSL used bypresent.Key behavioral details:
onCancelis invoked by the close button and system back (which navigates WebView history first when possible); the host is responsible for routing sheet-gesture dismissals through the same cancellation path.onFailasks the host to remove its presentation rather than attempting to dismiss an unknown parent.onFailis invoked and the view remains inert instead of crashing.destroy()is idempotent and must be called when the view is permanently removed.AndroidView.onReleaseis the recommended Compose integration point. The view also destroys itself when its nearestLifecycleOwneris destroyed.CheckoutViewmust be created for a new checkout URL.Checkout chrome (toolbar, progress bar, loading background, close button) is extracted from
CheckoutBottomSheetinto a newcheckout_view_content.xmllayout owned byCheckoutView.CheckoutBottomSheetnow hosts aCheckoutViewinside a plainFrameLayoutcontainer, removing duplicated chrome logic.CheckoutWebView.checkoutViewForis refactored to run on the calling thread (must be main) and transport attachment is moved out of the constructor so a failed feature check can cleanly destroy the partially constructed WebView.CheckoutBottomSheet.start()now returns aBooleanindicating whether presentation succeeded, allowingShopifyCheckoutKitto clean up its lifecycle observer on failure without relying on a caught exception.The demo app's cart screen is updated to demonstrate the embedded flow using
ModalBottomSheet+AndroidView, andCartViewModel.checkoutConfigurationis extracted so the same callback block can be shared between the imperative and embedded paths.How to test
CheckoutKitAndroidDemo).ModalBottomSheetviaCheckoutView.onCancelis invoked and the sheet closes.ShopifyCheckoutKit.presentflow (used elsewhere in the app) continues to work unchanged../gradlew :lib:test— newCheckoutViewTestand updatedInteropTestcover construction, preload consumption, lifecycle destruction, back navigation, cancel deduplication, and Java interop.Before you merge
Important
platforms/swift/README.mdand/orplatforms/android/README.md)Releasing a new Swift version?
ShopifyCheckoutKit.podspecplatforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swiftplatforms/swift/README.md(major version only)Releasing a new Embedded Checkout Protocol version?
embeddedCheckoutProtocolAndroidinplatforms/android/gradle/libs.versions.tomlprotocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.apiif the public API changedReleasing a new Android version?
checkoutKitAndroidinplatforms/android/gradle/libs.versions.tomlplatforms/android/README.mdTip
See the Contributing documentation for the full release process per platform.