하이브리드앱 프로젝트 하다가 WebView에 SwipeRefreshLayout RefleshControll 적용 하려고 했음.....

메인페이지는 정상적으로 WebView Scroll Y축 값이 스크롤 할때마다 변경되면서 잘 동작했는데

popupview 형식의 페이지에서는 WebView Scroll Y축 값이 스크롤을 해도 0으로만 나오는 거임.

 

getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        ViewTreeObserver observer = getViewTreeObserver();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            observer.removeOnGlobalLayoutListener(this);
        } else {
            observer.removeGlobalOnLayoutListener(this);
        }

        DLog.i(new Exception(), "addOnGlobalLayoutListener onGlobalLayout()");

        observer.addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
            @Override
            public void onScrollChanged() {

                if (webView.getScrollY()==0) {  // <= popup view 에서는 스크롤해도 무조건 0값만 나옴
                    setEnabled(true);
                    DLog.i(new Exception(), "onScrollChanged setEnabled true : " + getScrollY() + " / " + webView.getScrollY());
                } else {
                    setEnabled(false);
                    DLog.i(new Exception(), "onScrollChanged setEnabled false : " + getScrollY() + " / " + webView.getScrollY());
                }
            }
        });
    }
});

 

별짓 다해봤는데 안됨. 그래서 자바스크립트를 WebView에 evaluateJavascript로 아래 자바 스크립트 삽입해서 해결했음.

element.classList.contains('all-menu-container') 이게 팝업뷰의 컨테이너 이름을 찾아서 팝업뷰인지 확인하면됨.

팝업뷰 컨테이너 이름은 퍼블리셔나 웹개발자한테 알려달라고 하던지 아니면 브라우저에서 디버깅해서 알아내면됨. 

onPageFinished 에서 자바스크립트 적용하면됨.

javascript: (function() {
    var lastScrollTop = 0;
    window.addEventListener('scroll', (event) => {
        var scrollTop = 0;
        if (event.srcElement.documentElement == null) {
            let element = event.target;
            while (element) {
            	// 팝업뷰 일 경우
                if (element && element.classList && 
                   (element.classList.contains('all-menu-container') ||  // <= 메인 메뉴 popupview 컨테이너 이름
                   element.classList.contains('mo-modal__container--wrapper'))) { // <= 그외 popupview 컨테이너 공통wrapper 컨테이너 이름
                    scrollTop = event.srcElement.scrollTop;
                    if (scrollTop !== lastScrollTop) {
                        lastScrollTop = scrollTop;
                        android.onWebViewScrollChanged(scrollTop); // <= 앱 인터페이스로 스크롤 위치값 전송하는 부분
                    }
                    console.log('popupScrollTop : ' + lastScrollTop);
                    break;
                }
                element = element.parentNode;
            }
        } else {
        	// 그 외 페이지
            scrollTop = event.srcElement.documentElement.scrollTop;
            if (scrollTop !== lastScrollTop) {
                lastScrollTop = scrollTop;
                android.onWebViewScrollChanged(scrollTop); // <= 앱 인터페이스로 스크롤 위치값 전송하는 부분
            }
            console.log('mainScrollTop : ' + lastScrollTop);
        }
    }
    , true);
}
)();

 

// Popup View Page 에서 스크롤 Y 축 0으로 고정되서 자바스크립트로 스크롤 Y 축 별도로 받아서 처리
webview.evaluateJavascript("javascript:(function() {" +
        "var lastScrollTop = 0;" +
        "window.addEventListener('scroll', (event) => {" +
        "    var scrollTop = 0;" +
        "    if ( event.srcElement.documentElement == null ) {" +
                // Popup Page View
        "       let element = event.target;" +
        "       while (element) {" +
        "          if (element && element.classList && " +
        "              (element.classList.contains('all-menu-container') || " +            // 메인 메뉴 팝업
        "               element.classList.contains('mo-modal__container--wrapper'))) {" +  // 공통 모달 팝업

        "              scrollTop = event.srcElement.scrollTop;" +
        "              if (scrollTop !== lastScrollTop) {" +
        "                  lastScrollTop = scrollTop;" +
        "                  android.onWebViewScrollChanged(scrollTop);" + // Android 메서드 호출
        "              }" +
        "              console.log('popupScrollTop : ' + lastScrollTop);" +
        "              break;" +
        "          }" +
        "          element = element.parentNode;" +
        "       }" +
        "    } else {" +
                // Main Page View 외 기타 페이지
        "       scrollTop = event.srcElement.documentElement.scrollTop;" +
        "       if (scrollTop !== lastScrollTop) {" +
        "           lastScrollTop = scrollTop;" +
        "           android.onWebViewScrollChanged(scrollTop);" + // Android 메서드 호출
        "       }" +
        "       console.log('mainScrollTop : ' + lastScrollTop);" +
        "    }" +
        " }, true);" +
        "})();", null);

 

 

웹뷰 자바스크립트 인터페이스

/**
 * Todo : 웹뷰 스크롤 이벤트
 */
@JavascriptInterface
public void onWebViewScrollChanged(final int scrollY) {

    if (scrollY == 0) {
        if (getIWebview().isEnabled() == false) {
            ((Activity)getContext()).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    getIWebview().setEnabled(true);
                    DLog.i(new Exception(), "Refresh setEnabled : " + getIWebview().isEnabled() );
                }
            });
        }
    } else {
        if (getIWebview().isEnabled() == true) {
            ((Activity)getContext()).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    getIWebview().setEnabled(false);
                    DLog.i(new Exception(), "Refresh setEnabled : " + getIWebview().isEnabled() );
                }
            });
        }
    }

}

+ Recent posts