Android WebView 스크롤 리스너 만들기

James_·2022년 10월 13일
0

웹뷰에서 스크롤을 감지하여 모션레이아웃을 실행해야하는 상황이 생기면서 검색을 해보면서 해결했던 것을 기록하고자 합니다.

리스너는 총 세가지를 만듭니다.

  • 더이상 스크롤 할 수 없고 맨 하단에 닿았을 경우
  • 스크롤 업
  • 스크롤 다운

구현

먼저 웹뷰를 상속받은 커스텀 뷰를 만들어줍니다.

class CustomWebView @JvmOverloads constructor(
    context: Context,attrs:AttributeSet?=null,defStyleAttr:Int = 0
):WebView(context,attrs, defStyleAttr)

맨 하단 스크롤 리스너


interface CustomWebViewListener{
    fun bottomEndReached(isEnd:Boolean)
    fun onScrollDown()
    fun onScrollUp()
}
private var bottomReached = false
private var listener:CustomWebViewListener?=null

fun setScrollListener(mListener: CustomWebViewListener){
        try{
            listener = mListener
        }catch (e:ClassCastException){
            e.printStackTrace()
            throw ClassCastException()
        }
    }

인터페이스를 만들고 리스너 세터,그리고 클래스 변수로 선언해줍니다.
그리고 onScrollChanged를 override해줍니다.

    override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
        if(this.computeVerticalScrollRange() <= (this.computeVerticalScrollOffset() +
                    this.computeVerticalScrollExtent() + this.paddingOffset)) {
            if(!bottomReached) {
                bottomReached = true
                listener?.bottomEndReached(true)
            }
        } else {
            if(bottomReached) {
                bottomReached = false
                listener?.bottomEndReached(false)
            }
        }
        super.onScrollChanged(l, t, oldl, oldt)
    }

스크롤업, 스크롤 다운

override fun onTouchEvent(event: MotionEvent?): Boolean {
        when(event?.action){
            MotionEvent.ACTION_DOWN -> {
                oldY = event.y
            }

            MotionEvent.ACTION_MOVE ->{
                if(event.y > oldY){
                    listener?.onScrollDown()
                }

                if(event.y < oldY){
                    listener?.onScrollUp()
                }
            }
        }
        return super.onTouchEvent(event)
    }

onTouchEvent를 override해줍니다.
클래스 변수인 oldY를 현재 Y랑 비교하여 리스너를 실행해줍니다.

binding.wv.setScrollListener(object:CustomWebViewListener{
            override fun bottomEndReached(isEnd: Boolean) {
                binding.btn.btn.isEnabled = isEnd
            }

            override fun onScrollDown() {
                Timber.d("on Scroll down")
                binding.root.transitionToStart()
            }

            override fun onScrollUp() {
                binding.root.transitionToEnd()
            }
        } )

액티비티나 프래그먼트에서 익명 객체로 리스너를 생성해주면 정상적으로 동작하게 됩니다.
추가적으로 모션레이아웃을 xml이 아닌 코드에서 실행하려면 transitionToStart or end를 실행해주면 됩니다.

profile
Android 개발자

0개의 댓글