Compose) Jetpack Compose로 WebView 띄우기

2ast·2025년 3월 13일

Compose에서 WebView 띄우기

compose에서는 웹뷰를 아주 간단히 띄울 수 있다.

@Composable
fun CustomWebView(
    url: String,
) {
  AndroidView(factory = {
    val myWebView = WebView(it)
    
    myWebView.apply {
      layoutParams = ViewGroup.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT
      )
    }
  }, update = {
      it.loadUrl(url)
  })
}

이렇게만 작성해두어도 CustomWebView에 url을 넘겨 간단히 웹뷰를 띄울 수 있다. 하지만 실제로 그럴싸한 웹뷰 사용성을 보이려면 몇가지 작업을 더 해주어야한다.

WebViewClient 할당

위 코드를 그대로 실행할 경우 compose application에서 웹뷰가 로드되는게 아니라 스마트폰 브라우저 앱이 실행되며 새창으로 url이 로드되는 경험을 했다. 서치 결과 WebViewClient를 할당해주어야한다는 사실을 알아냈다.

@Composable
fun CustomWebView(
    url: String,
) {
  AndroidView(factory = {
    val myWebView = WebView(it)
    // 스마트폰 browser로 실행되는게 아니라 인앱에서 웹뷰를 띄우기 위해 WebViewClient 할당
    myWebView.webViewClient = CustomWebViewClient()
    
    myWebView.apply {
      layoutParams = ViewGroup.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT
      )
    }
  }, update = {
      it.loadUrl(url)
  })
}

class CustomWebViewClient : WebViewClient() {
  // TODO Something
}

WebView Settings

webview를 사용할 때 기본적으로 넣어주는 웹뷰 셋팅들이 있다. 이부분은 각자 프로젝트에 맞게 설정해주면 된다.

@Composable
fun CustomWebView(
    url: String,
) {
  AndroidView(factory = {
    val myWebView = WebView(it)
    // 스마트폰 browser로 실행되는게 아니라 인앱에서 웹뷰를 띄우기 위해 WebViewClient 할당
    myWebView.webViewClient = CustomWebViewClient()
    
    // webview 설정
    myWebView.settings.apply {
      domStorageEnabled = true
      mixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW
      loadsImagesAutomatically = true
      cacheMode = WebSettings.LOAD_DEFAULT
      textZoom = 100
      mediaPlaybackRequiresUserGesture = false
    }
            
    myWebView.apply {
      layoutParams = ViewGroup.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT
      )
    }
  }, update = {
      it.loadUrl(url)
  })
}

class CustomWebViewClient : WebViewClient() {
  // TODO Something
}

Android BackHandler 설정

Android 기기는 기본적으로 뒤로가기 버튼을 누를 수 있다. 만약 WebView에 따로 BackHandler 설정을 해주지 않는다면 물리버튼을 눌렀을 때 브라우저의 뒤로가기가 아니라 navigation의 뒤로가기나 앱 종료 등 기본 동작이 실행되게 된다.

나는 webview에서 뒤로가기가 가능하다면 webview의 뒤로가기 실행, 만약 그렇지 않다면 navigation의 뒤로가기를 실행하도록 구성해주었다.

@Composable
fun CustomWebView(
    url: String,
    navigationGoBack: () -> Unit
) {
    // webView에 접근하기 위해 state로 선언해주었다.
    var webView: WebView? by remember { mutableStateOf(null) }


    val onPressedBack = {
        if (webView?.canGoBack() == true) {
            webView?.goBack()
        } else {
            navigationGoBack()
        }
    }
    
    BackHandler(enabled = true) {
        onPressedBack()
    }
    
    AndroidView(factory = {
      val myWebView = WebView(it)
      ...
      myWebView.apply {
        ...
        webView = this
      }
    }
}

BackHandler를 Composable의 최상단에서만 선언 가능하기 때문에 AndroidView 하위에서 선언하는 webView 객체에 접근하기 위해 state로 선언해서 초기화 후 할당해주었다.

profile
React-Native 개발블로그

0개의 댓글