본문 바로가기
Android/Dev

ScrollView 사용시 스크롤 중인지 판단하여 작업 제한하기

by featherwing 2019. 3. 17.
반응형

스크롤 뷰를 사용할 때 스크롤 상태를 확인해야 할 경우가 있습니다.

 

스크롤 뷰 내에 클릭 리스너가 있는 객체가 있을 경우

 

스크롤 할때 해당 객체가 클릭되는 경우가 발생하기 때문입니다.

 

이때, 스크롤 중인지  아닌지를 확인하여, 스크롤 중이라면 클릭을 제한해야 

 

스크롤 중에 클릭되더라도 객체의 클릭리스너나 터치 리스너가 작동하지 않습니다.

 

 

돌아다니는 많은 예제를 보면 CustomScrollView를 만들어 내부에서 OnScrollStoppedListener를 구현하는 방법이나

 

getViewTreeObserver()를 통해 OnScrollChangedListener를 달아서 내부에서 Y 스크롤의 포지션값 비교를 통한 방법이 있는데 

 

전자의 경우는 사용자가 스크롤뷰에서 fling 제스쳐를 주는 등 예상치 못한 이벤트를 줄 때 제대로 작동하지 않는 경우가 발생하고

 

후자의 경우에는 스크롤뷰의 Top이나 Bottom으로 갔을때는 Y 스크롤의 포지션값이 원하는대로 반환되지 않아 제대로 작동하지 않는 경우가

 

발생하였습니다.

 

 

이하의 방법은 스크롤뷰에 온 터치 리스너를 달고, 모션 이벤트 감지를 통해서 사용자가 스크롤뷰를 스크롤 하는지 아닌지 확인하는 방법입니다.  

 

 

boolean scrollStop;



mScrollView.setOnTouchListener(new View.OnTouchListener() {

            @Override

            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {

                    case MotionEvent.ACTION_SCROLL:

                    case MotionEvent.ACTION_MOVE:

                        scrollStop = false;

                        break;



                    case MotionEvent.ACTION_DOWN:

                        break;



                    case MotionEvent.ACTION_CANCEL:

                    case MotionEvent.ACTION_UP:



                        Handler mHandler = new Handler();

                        mHandler.postDelayed(new Runnable() {

                            public void run() {

                                scrollStop = true;

                            }

                        }, 400);



                        break;

                }

                return false;

            }

        } );

 

MotionEvent.ACTION_UP, MotionEvent.ACTION_DOWN는 사용자가 손가락으로 화면을 터치 했을 때나 터치를 땠을때 변화하는 값으로 

 

좀 더 자세한 내용은 구글 개발자 문서의 MotionEvent항목을 확인 해 주세요.

 

 

 

스크롤뷰 내부의 객체가 가진 작업은 아래와 같이 if(scrollStop) 일 때에만 실행 되도록 해주면 됩니다.

if(scrollStop) {

//TODO 원하는 작업

}
 

스크롤 뷰의 스크롤상태를 정해 줄 boolean 값인 scrollStop을 설정 해 주고 달아준 온터치리스너가 사용자의 모션 이벤트에 따라 scrollStop의 값을 설정 해 줍니다.

 
 

 

스크롤 뷰에서 문제가 되는 경우는 스크롤 중에  스크롤뷰 내부의 개체가 클릭되어 작업이 실행되는 경우이므로

 

사용자가 스크롤을 시작하는   MotionEvent.ACTION_MOVE 에는 딜레이 없이 바로 scrollStop을 false로 설정 해 주어 

 

내부에서 클릭이나 터치 이벤트가 발생할 경우에도 실행되지 않도록 해주고

 

 

사용자가 스크롤을 중료하는 MotionEvent.CANCEL, MotionEvent.ACTION_UP 이후에는 

 

핸들러로 적절한 딜레이를 준 뒤 ScrollStop을 true로 설정하여 스크롤 직후에는 사용자가 손가락을 뗄 때 오작업이 나지 않도록 설정하여

 

딜레이 이후에만 내부에 클릭이나 터치 이벤트를 주었을 때  작업이 실행될 수 있도록 해줍니다.

 

 

 

반응형

댓글