Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WebView] Extend the WebView composable to allow for customized (subclasses of) WebViews #1352

Merged
merged 2 commits into from Sep 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -61,7 +61,7 @@ A library which provides a way to use Android Drawables as Jetpack Compose Paint
### ⬇️ [Swipe to Refresh](./swiperefresh/)
A library that provides a layout implementing the swipe-to-refresh UX pattern, similar to Android's [SwipeRefreshLayout](https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout).

### 🌏 [Web](./web/)
### 🌏 [Web](./webview/)
A wrapper around WebView for basic WebView support in Jetpack Compose.

### 📜 [Adaptive](./adaptive/)
Expand Down
11 changes: 11 additions & 0 deletions docs/webview.md
Expand Up @@ -45,6 +45,17 @@ WebView(
)
```

### Using a subclass of WebView

If you want to use a subclass of `WebView`, or simply require more control over its instantiation, you can provide a factory.

```kotlin
WebView(
...
factory = { context -> CustomWebView(context) }
)
```

## Download

[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-webview)](https://search.maven.org/search?q=g:com.google.accompanist)
Expand Down
2 changes: 1 addition & 1 deletion web/api/current.api
Expand Up @@ -75,7 +75,7 @@ package com.google.accompanist.web {
}

public final class WebViewKt {
method @androidx.compose.runtime.Composable public static void WebView(com.google.accompanist.web.WebViewState state, optional androidx.compose.ui.Modifier modifier, optional boolean captureBackPresses, optional com.google.accompanist.web.WebViewNavigator navigator, optional kotlin.jvm.functions.Function1<? super android.webkit.WebView,kotlin.Unit> onCreated, optional kotlin.jvm.functions.Function1<? super android.webkit.WebView,kotlin.Unit> onDispose, optional com.google.accompanist.web.AccompanistWebViewClient client, optional com.google.accompanist.web.AccompanistWebChromeClient chromeClient);
method @androidx.compose.runtime.Composable public static void WebView(com.google.accompanist.web.WebViewState state, optional androidx.compose.ui.Modifier modifier, optional boolean captureBackPresses, optional com.google.accompanist.web.WebViewNavigator navigator, optional kotlin.jvm.functions.Function1<? super android.webkit.WebView,kotlin.Unit> onCreated, optional kotlin.jvm.functions.Function1<? super android.webkit.WebView,kotlin.Unit> onDispose, optional com.google.accompanist.web.AccompanistWebViewClient client, optional com.google.accompanist.web.AccompanistWebChromeClient chromeClient, optional kotlin.jvm.functions.Function1<? super android.content.Context,? extends android.webkit.WebView>? factory);
method @androidx.compose.runtime.Composable public static com.google.accompanist.web.WebViewNavigator rememberWebViewNavigator(optional kotlinx.coroutines.CoroutineScope coroutineScope);
method @androidx.compose.runtime.Composable public static com.google.accompanist.web.WebViewState rememberWebViewState(String url, optional java.util.Map<java.lang.String,java.lang.String> additionalHttpHeaders);
method @androidx.compose.runtime.Composable public static com.google.accompanist.web.WebViewState rememberWebViewStateWithHTMLData(String data, optional String? baseUrl);
Expand Down
28 changes: 25 additions & 3 deletions web/src/androidTest/kotlin/com/google/accompanist/web/WebTest.kt
Expand Up @@ -16,6 +16,7 @@

package com.google.accompanist.web

import android.content.Context
import android.graphics.Bitmap
import android.webkit.WebView
import androidx.compose.material.MaterialTheme
Expand Down Expand Up @@ -619,6 +620,22 @@ class WebTest {

private val webNode: SemanticsNodeInteraction
get() = rule.onNodeWithTag(WebViewTag)

@Test
fun testWebViewFactoryUsedIfSupplied() {
lateinit var constructedWebView: WebView

rule.setContent {
WebTestContent(
rememberWebViewState(url = LINK_URL),
idleResource,
onCreated = { constructedWebView = it },
factory = { context -> CustomWebView(context) }
)
}

assertThat(constructedWebView).isInstanceOf(CustomWebView::class.java)
}
}

private const val LINK_ID = "link"
Expand All @@ -638,9 +655,11 @@ private fun WebTestContent(
webViewState: WebViewState,
idlingResource: WebViewIdlingResource,
navigator: WebViewNavigator = rememberWebViewNavigator(),
onCreated: (WebView) -> Unit = { it.settings.javaScriptEnabled = true },
onDispose: (WebView) -> Unit = {},
client: AccompanistWebViewClient = remember { AccompanistWebViewClient() },
chromeClient: AccompanistWebChromeClient = remember { AccompanistWebChromeClient() }
chromeClient: AccompanistWebChromeClient = remember { AccompanistWebChromeClient() },
factory: ((Context) -> WebView)? = null
) {
idlingResource.webviewLoading = webViewState.loadingState !is LoadingState.Finished

Expand All @@ -649,10 +668,11 @@ private fun WebTestContent(
state = webViewState,
modifier = Modifier.testTag(WebViewTag),
navigator = navigator,
onCreated = { it.settings.javaScriptEnabled = true },
onCreated = onCreated,
onDispose = onDispose,
client = client,
chromeClient = chromeClient
chromeClient = chromeClient,
factory = factory
)
}
}
Expand All @@ -663,3 +683,5 @@ private class WebViewIdlingResource : IdlingResource {
override val isIdleNow: Boolean
get() = !webviewLoading
}

private class CustomWebView(context: Context) : WebView(context)
7 changes: 5 additions & 2 deletions web/src/main/java/com/google/accompanist/web/WebView.kt
Expand Up @@ -16,6 +16,7 @@

package com.google.accompanist.web

import android.content.Context
import android.graphics.Bitmap
import android.view.ViewGroup
import android.webkit.WebChromeClient
Expand Down Expand Up @@ -62,6 +63,7 @@ import kotlinx.coroutines.withContext
* subsequently overwritten after this lambda is called.
* @param client Provides access to WebViewClient via subclassing
* @param chromeClient Provides access to WebChromeClient via subclassing
* @param factory An optional WebView factory for using a custom subclass of WebView
* @sample com.google.accompanist.sample.webview.BasicWebViewSample
*/
@Composable
Expand All @@ -73,7 +75,8 @@ fun WebView(
onCreated: (WebView) -> Unit = {},
onDispose: (WebView) -> Unit = {},
client: AccompanistWebViewClient = remember { AccompanistWebViewClient() },
chromeClient: AccompanistWebChromeClient = remember { AccompanistWebChromeClient() }
chromeClient: AccompanistWebChromeClient = remember { AccompanistWebChromeClient() },
factory: ((Context) -> WebView)? = null
) {
var webView by remember { mutableStateOf<WebView?>(null) }

Expand Down Expand Up @@ -104,7 +107,7 @@ fun WebView(

AndroidView(
factory = { context ->
WebView(context).apply {
(factory?.invoke(context) ?: WebView(context)).apply {
onCreated(this)

layoutParams = ViewGroup.LayoutParams(
Expand Down