From e9898d9188599ad655265489a7bf9cbc4eb514f3 Mon Sep 17 00:00:00 2001 From: Jay Ohms Date: Thu, 16 May 2024 06:24:48 -0400 Subject: [PATCH] Subclass AppCompatActivity directly so the public API is cleaner. We alreeady require apps to implement AppCompatActivity, so it gives the library more control if we own it directly. --- .../navigation/activities/HotwireActivity.kt | 20 +++++++++++-------- .../activities/HotwireActivityDelegate.kt | 7 +++---- .../core/navigation/routing/BrowserRoute.kt | 2 +- .../navigation/routing/BrowserTabRoute.kt | 4 ++-- .../session/SessionNavHostFragment.kt | 4 ++-- .../dev/hotwire/demo/main/MainActivity.kt | 7 +------ docs/QUICK-START.md | 11 ++++------ 7 files changed, 25 insertions(+), 30 deletions(-) diff --git a/core/src/main/kotlin/dev/hotwire/core/navigation/activities/HotwireActivity.kt b/core/src/main/kotlin/dev/hotwire/core/navigation/activities/HotwireActivity.kt index a974825..0b0ae97 100644 --- a/core/src/main/kotlin/dev/hotwire/core/navigation/activities/HotwireActivity.kt +++ b/core/src/main/kotlin/dev/hotwire/core/navigation/activities/HotwireActivity.kt @@ -1,16 +1,20 @@ package dev.hotwire.core.navigation.activities +import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import dev.hotwire.core.navigation.session.SessionConfiguration -import dev.hotwire.core.navigation.session.SessionNavHostFragment /** - * Interface that should be implemented by any Activity using Turbo. Ensures that the - * Activity provides a [HotwireActivityDelegate] so the framework can initialize the - * [SessionNavHostFragment] hosted in your Activity's layout resource. + * Activity that should be implemented by any Activity using Hotwire. */ -interface HotwireActivity { - val delegate: HotwireActivityDelegate - val appCompatActivity: AppCompatActivity - fun sessionConfigurations(): List +abstract class HotwireActivity : AppCompatActivity() { + lateinit var delegate: HotwireActivityDelegate + private set + + abstract fun sessionConfigurations(): List + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + delegate = HotwireActivityDelegate(this) + } } diff --git a/core/src/main/kotlin/dev/hotwire/core/navigation/activities/HotwireActivityDelegate.kt b/core/src/main/kotlin/dev/hotwire/core/navigation/activities/HotwireActivityDelegate.kt index eacd3b4..fe46916 100644 --- a/core/src/main/kotlin/dev/hotwire/core/navigation/activities/HotwireActivityDelegate.kt +++ b/core/src/main/kotlin/dev/hotwire/core/navigation/activities/HotwireActivityDelegate.kt @@ -21,7 +21,6 @@ import dev.hotwire.core.turbo.visit.VisitOptions */ @Suppress("unused", "MemberVisibilityCanBePrivate") class HotwireActivityDelegate(val activity: HotwireActivity) { - private val appCompatActivity = activity.appCompatActivity private val navHostFragments = mutableMapOf() private val onBackPressedCallback = object : OnBackPressedCallback(enabled = true) { @@ -41,9 +40,9 @@ class HotwireActivityDelegate(val activity: HotwireActivity) { * handles Fragment navigation with the back button. */ init { - appCompatActivity.lifecycle.addObserver(HotwireActivityObserver()) - appCompatActivity.onBackPressedDispatcher.addCallback( - owner = appCompatActivity, + activity.lifecycle.addObserver(HotwireActivityObserver()) + activity.onBackPressedDispatcher.addCallback( + owner = activity, onBackPressedCallback = onBackPressedCallback ) } diff --git a/core/src/main/kotlin/dev/hotwire/core/navigation/routing/BrowserRoute.kt b/core/src/main/kotlin/dev/hotwire/core/navigation/routing/BrowserRoute.kt index 6d8bac2..29f8e25 100644 --- a/core/src/main/kotlin/dev/hotwire/core/navigation/routing/BrowserRoute.kt +++ b/core/src/main/kotlin/dev/hotwire/core/navigation/routing/BrowserRoute.kt @@ -27,7 +27,7 @@ class BrowserRoute : Router.Route { val intent = Intent(Intent.ACTION_VIEW, location.toUri()) try { - activity.appCompatActivity.startActivity(intent) + activity.startActivity(intent) } catch (e: ActivityNotFoundException) { logError("BrowserRoute", e) } diff --git a/core/src/main/kotlin/dev/hotwire/core/navigation/routing/BrowserTabRoute.kt b/core/src/main/kotlin/dev/hotwire/core/navigation/routing/BrowserTabRoute.kt index 7b8dc3c..b07f625 100644 --- a/core/src/main/kotlin/dev/hotwire/core/navigation/routing/BrowserTabRoute.kt +++ b/core/src/main/kotlin/dev/hotwire/core/navigation/routing/BrowserTabRoute.kt @@ -25,7 +25,7 @@ class BrowserTabRoute : Router.Route { sessionConfiguration: SessionConfiguration, activity: HotwireActivity ) { - val color = activity.appCompatActivity.colorFromThemeAttr(R.attr.colorSurface) + val color = activity.colorFromThemeAttr(R.attr.colorSurface) val colorParams = CustomTabColorSchemeParams.Builder() .setToolbarColor(color) .setNavigationBarColor(color) @@ -37,6 +37,6 @@ class BrowserTabRoute : Router.Route { .setUrlBarHidingEnabled(false) .setDefaultColorSchemeParams(colorParams) .build() - .launchUrl(activity.appCompatActivity, location.toUri()) + .launchUrl(activity, location.toUri()) } } diff --git a/core/src/main/kotlin/dev/hotwire/core/navigation/session/SessionNavHostFragment.kt b/core/src/main/kotlin/dev/hotwire/core/navigation/session/SessionNavHostFragment.kt index 1ff8a38..0a1db70 100644 --- a/core/src/main/kotlin/dev/hotwire/core/navigation/session/SessionNavHostFragment.kt +++ b/core/src/main/kotlin/dev/hotwire/core/navigation/session/SessionNavHostFragment.kt @@ -43,8 +43,8 @@ open class SessionNavHostFragment : NavHostFragment() { internal fun createNewSession() { session = Session( sessionName = sessionConfiguration.name, - activity = activity.appCompatActivity, - webView = onCreateWebView(activity.appCompatActivity) + activity = activity, + webView = onCreateWebView(activity) ) onSessionCreated() } diff --git a/demo/src/main/kotlin/dev/hotwire/demo/main/MainActivity.kt b/demo/src/main/kotlin/dev/hotwire/demo/main/MainActivity.kt index 100a05c..0113e96 100644 --- a/demo/src/main/kotlin/dev/hotwire/demo/main/MainActivity.kt +++ b/demo/src/main/kotlin/dev/hotwire/demo/main/MainActivity.kt @@ -1,17 +1,12 @@ package dev.hotwire.demo.main import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity import dev.hotwire.core.navigation.activities.HotwireActivity -import dev.hotwire.core.navigation.activities.HotwireActivityDelegate import dev.hotwire.core.navigation.session.SessionConfiguration import dev.hotwire.demo.R import dev.hotwire.demo.Urls -class MainActivity : AppCompatActivity(), HotwireActivity { - override val delegate by lazy { HotwireActivityDelegate(this) } - override val appCompatActivity = this - +class MainActivity : HotwireActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) diff --git a/docs/QUICK-START.md b/docs/QUICK-START.md index d49d3f9..f335188 100644 --- a/docs/QUICK-START.md +++ b/docs/QUICK-START.md @@ -47,11 +47,11 @@ Android Jetpack provides a [`FragmentContainerView`](https://developer.android.c Refer to the demo [`activity_main.xml`](../demo/src/main/res/layout/activity_main.xml) for an example. -### Implement the HotwireActivity interface +### Implement the HotwireActivity abstract class -A Hotwire `Activity` is straightforward and needs to implement the [`HotwireActivity`](../core/src/main/kotlin/dev/hotwire/core/turbo/activities/HotwireActivity.kt) interface in order to provide a [`HotwireActivityDelegate`](../core/src/main/kotlin/dev/hotwire/core/turbo/delegates/HotwireActivityDelegate.kt) and `Session` configuration information. +A Hotwire `Activity` is straightforward and needs to subclass the [`HotwireActivity`](../core/src/main/kotlin/dev/hotwire/core/turbo/activities/HotwireActivity.kt) class in order to provide `Session` configuration information. -Your Activity should extend Android Jetpack's [`AppCompatActivity`](https://developer.android.com/reference/androidx/appcompat/app/AppCompatActivity). +`HotwireActivity` extends Android Jetpack's [`AppCompatActivity`](https://developer.android.com/reference/androidx/appcompat/app/AppCompatActivity). You'll need to provide at least one `SessionConfiguration` instance (one for each `SessionNavHostFragment` that exists in our Activity layout). This includes: - The `name` of the `Session` (this is arbitrary and helpful for debugging purposes, but each must be unique in your app) @@ -62,10 +62,7 @@ In its simplest form, your Activity will look like: **`MainActivity.kt`:** ```kotlin -class MainActivity : AppCompatActivity(), HotwireActivity { - override val delegate by lazy { HotwireActivityDelegate(this) } - override val appCompatActivity = this - +class MainActivity : HotwireActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)