본문 바로가기
Android

안드로이드 하이브리드앱 새창 Popup(팝업)창 띄우기 및 닫기

by 일용직 코딩노동자 2020. 1. 28.
728x90
반응형

하이브리드 앱을 진행하면서 Webview를 통해 페이지를 띄웁니다.

 

진행을 하다보면 스크립트(Javascript)딴에서 window.open으로 새창(팝업)을 띄웁니다.

 

이걸 안드로이드(네이티브)딴에서 뒤로가기나 다른 버튼을 통해 닫아줘야하는 경우가 생기는데요.

 

이걸 제어하는 방법에 대해서 포스팅해보겠습니다.

 

우선 일반적으로 Webview를 선언하겠지요

 

우선 Xml먼저 보실게요.

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical"
    android:id="@+id/rootview">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/webview_frame">

    <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/webview">
    </WebView>

    </FrameLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

 

이렇게 웹뷰를 구성했습니다.

 

일반적으로 웹뷰만 띄울거라면 FrameLayout없이 그냥 Webview만 있어도 가능합니다.

 

저희는 팝업을 띄울거기때문에 레이아웃을 하나 더 감쌋습니다.

 

간단한 구성들 먼저 하겠습니다.

public static FrameLayout mContainer;
public static WebView mWebView;
public static WebView mWebViewPop;
public WebSettings mWebSettings;

mContainer = (FrameLayout) findViewById(R.id.webview_frame);
mWebView =  findViewById(R.id.webview);
mWebViewPop = findViewById(R.id.webview);
mWebSettings = mWebView.getSettings();

mWebSettings.setJavaScriptEnabled(true); //자바스크립트 실행가능
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); // 자바스크립트가 window.open()을 사용가능

 

여기서 보셔야할것은 동일웹뷰인데 이름을 2개로 선언하여 따로 썻다는것과 프레임레이아웃 부분이에요.

 

보통 Webview만 쓰실거면 그냥 바로 loadUrl 하셔서 쓰셔도 무방합니다.

 

팝업을 띄울것이니,

 

@SuppressLint("SetJavaScriptEnabled")
    @Override
    public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
    // window.opener 시
    mWebViewPop = new WebView(view.getContext());
    mWebViewPop.getSettings().setJavaScriptEnabled(true);
    mWebViewPop.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    mWebViewPop.getSettings().setSupportMultipleWindows(true);
    mWebViewPop.getSettings().setDomStorageEnabled(true);
    mWebViewPop.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onCloseWindow(WebView window) {
        mContainer.removeView(window);
        window.destroy();
      }
    });

    mWebViewPop.setWebViewClient(new SslWebViewConnect());
    mWebViewPop.setLayoutParams(new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.MATCH_PARENT));
    mContainer.addView(mWebViewPop);
    WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
    transport.setWebView(mWebViewPop);
    resultMsg.sendToTarget();
    return true;
    }

이부분이 팝업을 띄우는 부분입니다.

 

위에서 선언한 웹뷰중에 mWebView는 일반 메인페이지들 보여주는 웹뷰입니다.

 

이 onCreateWindow에서는 mWebViewPop를 정의해줬습니다.

 

그리고 밑에보시면 mContainer.addView가 있습니다.

 

mContainer는 프레임레이아웃이죠.

 

그 레이아웃에 팝업을 띄운거라고 생각하시면됩니다.

 

이렇게하시면 팝업을 띄우시는데는 지장이없으실텐데, 문제는 이 팝업을 네이티브딴에서 어떻게 닫아주냐인데요.

 

저도 나무는보고 숲은 보지못해서 mWebViewPop만 가지고 엄청 삽질을 많이했습니다.

 

mWebViewPop.loadUrl("javascript:window.close();");

이 코드를 뒤로가기 or 버튼 등 이벤트하고싶은 곳에 넣어주시면.

 

onCloseWindow 오버라이드 함수가 호출됩니다.

 

웹개발자분과 상의를 잘하셔서 팝업부분이 어디인지 알아보셔서 적절한 위치에 코드를 넣어보세요.

 

뒤로가기부분 같은경우는 getUrl로 주소를 받아서 그 주소페이지에서만 작동하게끔 해 볼 수도 있습니다.

 

onCloseWindow 메소드 안에 

 

mContainer.removeView(window);
window.destroy();

코드가 있는데 여기서 removeView는 아에 뷰를 지우겠다는겁니다.

 

근데 여기서 window.destory를 해주지않으면 지워진것처럼 보이지만 실제로는 남아있어서,

 

다시 팝업을 여는 버튼을 눌렀을때 열리지않는 현상이 있습니다.

 

여기서 만약에 onCreateWindow가 그래도 호출이 되지않는다?

 

그렇다면 

mWebViewPop.setWebChromeClient(new WebChromeClient()

이부분을 의심해볼 필요가있습니다.

 

onCreateWindow안에 

 

onCloseWindow를 호출하기위한 

 

mWebViewPop.setWebChromeClient(new WebChromeClient() 가 존재하는데요.

 

만약에 

 

mWebViewPop.setWebChromeClient(new WebChromeClient()가 또 선언이 되어있다면 안되실수도있습니다.

 

예를들면 alert처리해주는 코드를 볼수가있습니다.

 

mWebViewPop.setWebChromeClient(new WebChromeClient()는 하나만 존재해야 하며 처리해줄 코드를 안에다가 다 합쳐서 해주세요.

 

mWebViewPop는 이제 팝업웹뷰의 웹뷰이고

 

메인웹뷰의 mWebView.setWebChromeClient(new WebChromeClinet() 도 하나만 존재하여야 합니다.

 

ㄱ ㅏ   ㄱ  푸시

ㅗ o    ㅗ  푸시 :D

궁금하신 사항은 댓글 남겨주세요. 

 

728x90
반응형

댓글