Android/WebView

[Android] WebView에서 유투브 전체 화면을 올바르게 표시하는 방법

점냥 2023. 6. 10. 21:42
반응형

사진:  Unsplash 의 Marek Piwnicki

 

안녕하세요 점냥입니다 :)

 

요즘 특정 화면을 WebView로 대체하는 경우가 종종 생기고 있어요. 실제로 앱 개발자의 역할은 대부분 올바른 URL을 설정해 주고 간단한 기본 설정을 해주면 됩니다. 그런데 만약 WebView에서 유튜브 영상 또는 비디오를 보여주고 싶다면 추가적으로 앱 개발자가 해줘야 하는 설정이 있어요. 한번 알아보러 가실까요?

 

문제 상황

@SuppressLint("SetJavaScriptEnabled")
@Composable
fun YouTubeInWebViewScreen() {
    val state = rememberWebViewState("https://www.youtube.com/embed/OK986vgCMs8")

    WebView(
        state = state,
        modifier = Modifier.fillMaxWidth().height(300.dp),
        onCreated = { it.settings.javaScriptEnabled = true }
    )
}

accompanist의 webView 라이브러리를 사용했고, embed 된 youtube URL을 로딩했습니다. 그리고 결과물을 보면.

 

전체 화면이 작동하지 않음 ㅜㅜ

 

유튜브 영상은 올바르게 재생이 되지만 오른쪽 화면의 전체 화면 버튼을 눌러도 버튼의 클릭 액션은 없지만 전체화면으로 전환되지 않는 것을 확인할 수 있었습니다. ㅜㅜ

 

사실 이러한 문제는 유튜브뿐만 아니라 다른 비디오 영상도 마찬가지인데요. 앞으로 소개할 WebView의 Full Screen을 사용하는 웹 사이트에서 모두 발생할 수 있는 이슈 이기 때문에 같이 알아보면 좋을 것 같습니다 :)

 

WebView Full Screen 구현해 주기

유튜브 전체 화면 버튼을 누르면 WebView의 Full Screen 모드로 전환되었다고 클라이언트에게 액션을 전달하는데요. 별도로 앱 개발자가 처리해주지 않는다면 무시가 됩니다.

 

"그럼 어떻게 처리하나요?"

 

public void onShowCustomView(View view, CustomViewCallback callback) {};
...
public void onHideCustomView() {}

 

Full Screen 모드를 처리해 주기 위해서는 WebChromClient의 아래 두 함수를 오버라이드 해야 합니다.

 

onShowCustomView 구현하기

override fun onShowCustomView(view: View?, callback: CustomViewCallback?) {
        if (customView != null) { // 이미 Full Screen이 표시된 상황이라면 제거 이벤트 위로 전달
            callback?.onCustomViewHidden()
            return
        }

        customView = view // 제거할 때 참조하기 위해 변수에 저장
        windowManager.addView(customView, WindowManager.LayoutParams()) // Window에 풀 스크린 뷰 추가
}


iOS와 달리 Android의 경우 WebView가 Full Screen 모드로 전환될 때, Full Screen 화면의 정보를 가진 View가 WebChromClient onShowCustomView 콜백 함수의 매개변수로 전달이 됩니다. 해당 뷰는 표현하고자 하는 Full Screen의 뷰 정보를 담고 있으며 다행히도 전달받은 뷰를 화면에 표시하기만 하면 됩니다 :)

 

화면에 표시해 주는 방법은 다양한데요. xml에 비어있는 FrameLayout을 선언해 주고 추가해 주거나 Window에 직접 추가해도 됩니다. 화면의 구조나 스펙에 따라서 가장 알맞은 방법을 선택하면 되겠습니다! 

 

onHideCustomView

  override fun onHideCustomView() {
        super.onHideCustomView()
        windowManager.removeView(customView)
        customView = null
  }

 

WebChromClient의 onHideCustomView 콜백 함수는 Full Screen Mode를 종료하고자 할 때 콜백이 되는데요. 다음과 같은 상황에서 호출될 수 있습니다.

 

- onHideCustomView가 override가 되어 있다면, 사용자가 Back Button을 클릭했을 때 시스템에서 호출

- 웹 사이트 자체에서 Full Screen 모드를 종료하고 싶을 때

- onShowCustomView 매개변수로 전달된 CustomViewCallback를 직접 제어해서 onCustomViewHidden를 호출

 

이 함수에서 해야 할 역할은 훨씬 간단해요. 추가한 View Tree에서 제거해주기만 하면 됩니다.

 

전체 화면이 올바르게 동작하는 모습

 

Tips. 전체 화면으로 전환 시 가로 모드로 변경하기

    @Deprecated
    public void onShowCustomView(View view, int requestedOrientation,
            CustomViewCallback callback) {};

Deprecated 된 함수이긴 하지만 이처럼 전체 화면으로 전환하면서 가로 모드 혹은 세로 모드로 변경하고자 할 때 주의할 점이 있습니다.

가로 모드 혹은 세로 모드 전환은 configation 중 하나인 orientation 정보입니다. configation changed가 될 경우 Activity의 메모리를 제거하고 재생성됩니다.

 

그로 인해 WebView 자체가 reload 되면서 모든 정보가 초기화되는 현상으로 인해 전체 화면이 종료될 수 있습니다.

 

  <activity
            ...
            android:configChanges="orientation|screenSize"

그래서 configation changed 일 때 Activity를 재생성하지 않는다는 의미로 manifest에서 configChanges를 재정의하면 됩니다. 

 

 

이번 블로그에서 사용된 전체 코드는 이 Github 링크에서 확인할 수 있습니다!
https://github.com/jaeryo2357/posting_android_sample_code/pull/2

반응형