버튼 수집상

[안드로이드] ViewPager 내부 웹뷰 가로 스크롤 처리하기 본문

TIL - 안드로이드

[안드로이드] ViewPager 내부 웹뷰 가로 스크롤 처리하기

cocokaribou 2023. 6. 21. 13:29

배경

ViewPager 안쪽 웹뷰에서 가로로 스크롤되는 UI가 있을 때 뷰페이저 페이지가 넘어가는 현상이 있었다.

예시 화면

포인터를 보면 웹뷰의 가로 스크롤 영역을 드래그했을 때 바깥쪽 뷰페이저가 넘어간다.

웹뷰의 가로 스크롤을 따로 읽는 함수는 없어서

onTouchEvent 안에서 터치 좌표로 처리했다.

 

CustomWebView.kt

class CustomWebView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0
) : WebView(context, attrs, defStyle) {
    private var oldY = 0f
    private var oldX = 0f

    init {
        // 샘플 웹뷰 간단한 설정들
        loadUrl("http://sample-domain.com/")
        settings.apply {
            javaScriptEnabled = true
        }
        webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                return false
            }
        }
    }
    
    // 뷰페이저 스와이핑 풀기
    override fun onOverScrolled(scrollX: Int, scrollY: Int, clampedX: Boolean, clampedY: Boolean) {
        parent.requestDisallowInterceptTouchEvent(false)
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY)
    }

    override fun onTouchEvent(ev: MotionEvent): Boolean {
        if (ev.pointerCount > 1) {
            return true
        }
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                oldY = ev.y
                oldX = ev.x
            }
            MotionEvent.ACTION_MOVE -> {
                val diffY = abs(oldY - ev.y)
                val diffX = abs(oldX - ev.x)

                if (diffX > diffY) {
                    // 가로 스크롤일 때 뷰페이저 스와이핑 intercept
                    parent.requestDisallowInterceptTouchEvent(true)
                    // 세로 스크롤 고정
                    // ev.setLocation(ev.x, oldY)
                } else {
                    parent.requestDisallowInterceptTouchEvent(false)
                }
            }
        }
        return super.onTouchEvent(ev)
    }
}

 

웹뷰에 따라서는 가로 스크롤 할 때마다 세로 스크롤이 같이 움직이는 경우가 있었다.

주석처리된 세로 스크롤 고정 코드를 넣으면 어느정도 보정할 수 있다.

다만 가로 스크롤을 하는 도중에 손가락을 떼지 않고 위아래로 드래그했을 때 세로 스크롤이 드득거리는 현상이 있었다.

 

웹뷰에 위 코드를 추가하면 웹뷰의 가로 스크롤이 잘 되는 것을 확인할 수 있다.

 

추가

ViewPager 를 ViewPager2로,

FragmentStatePagerAdapter를 FragmentStateAdapter로 바꿔도 동일한 코드로 수정가능했다.

 

참고

https://akaisun.tistory.com/68

 

webview scroll detecting

프로젝트를 진행하던 중 웹뷰의 스크롤에 따라 toolbar를 collapse, expand를 하는 기능을 만들게 되었다. 안드로이드에서는 web view의 스크롤을 감지하는 Listener를 제공하는데 다음과 같다. webView.setOnSc

akaisun.tistory.com

https://sysdocu.tistory.com/1284

 

webview 에서 가로 스크롤 차단하기 (막기)

import android.view.MotionEvent; webView.setHorizontalScrollBarEnabled(false);webView.setVerticalScrollBarEnabled(false); webView.setOnTouchListener(new View.OnTouchListener() { float m_downX; float m_downY; public boolean onTouch(View v, MotionEvent event

sysdocu.tistory.com

https://iw90.tistory.com/238

 

Android Touch Intercept 사용하기

Android Touch Intercept 사용하기 1. 문제 상황 - ViewPager > RecyclerView > ViewPager 위와 같은 구조였습니다. 상위의 Viewpager Swipe 를 하려다 보니 안의 ViewPager 가 스크롤이 되는 상황 안의 ViewPager Swipe 를 막고

iw90.tistory.com

 

728x90