Skip to content

Commit

Permalink
Merge pull request #1352 from morrisseyai/jm/extend-for-custom-webview
Browse files Browse the repository at this point in the history
[WebView] Extend the WebView composable to allow for customized (subclasses of) WebViews
  • Loading branch information
bentrengrove committed Sep 25, 2022
2 parents b2f6d43 + 534fe9e commit 3b711d0
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 7 deletions.
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

0 comments on commit 3b711d0

Please sign in to comment.