본문 바로가기
Project/안드로이드 프로젝트(ShareHouse)

Android Studio, JAVA] 스크롤뷰 내부의 뷰를 찾아 Smooth하게 Scroll 하기

by 김마리님 2020. 8. 12.

결과 :

사실 이 기능을 일반적으로 editText.requestFocus() 의 형태로 구현해도 별.. 문제는 없는데..

다만 좀.. 좀 슬픈게 이렇게 부드럽게 애니메이팅 되는 것이 아닌, 딱, 딱, 끊기는 형태로 아래로 내려간다. 

(스크롤링이 되지 않은, 포커싱으로 내려가는 것)

그래서 스크롤을 하려고 봤는데, 

 

리스너 안에 postDelayed라는 스레드를 만들고, 내부에서

scrollView.smoothScrollBy(int x, int y); 함수를 만들면 부드럽게 스크롤링이 가능했다.

 

이 함수의 문제점은,

1. getY 좌표는 현재 viewgroup 내에 찾는 view 가 없다면 찾지 못하므로 값을 찾지 못한다. 그러니까, 내가 찾아 내려갔으면 하는 뷰의 절대좌표가 필요하다.

2. 설령 절대좌표를 구했다고 해도,내가 y값만큼 내려가야하는데, 물론 뷰의 최상단에서만 스크롤링 하면 문제가 없다. 하지만, 최상단에서 스크롤링 하게 된다면, 목표치보다 훨씬 아래로 내려가는 문제점이 생긴다. 

 

그럼 이걸 어떻게 해결하느냐? 저~기 내가 가고 싶은, 선언한 뷰의 절대좌표를 먼저 구하고, 내가 보고 있는 부분의 상대좌표를 빼면, 남은 길이가 나오니까. 그 남은 길이만큼 스크롤링 하면 된다.

그럼 먼저 절대좌표를 구해보자.

 

절대좌표를 getLocationInWindow로 구한다. 이 값은 [int x,int y]의 두개의 값 배열로 값을 리턴하므로 먼저 배열을 선언하고 값을 넣는다.

                        int a []=new int[2];
                        tvConsulting.getLocationInWindow(a);

 

다음 상대좌표를 구하자.

스크롤 뷰의 현재 보고 있는 부분을 포인팅 하는 방법은 getGlobalVisibleRect로 구하면 된다.

                        Rect rect = new Rect();
                        Point p = new Point();
                        scrollView.getGlobalVisibleRect(rect, p);

p 내부에 x와 y. 둘 다 있으니 두려워하지 않아도 된다.

 

이 두개의 값을 가지고 빼면 간단하다. 이 때, y값만 구해야하니까, y는 절대좌표 배열 중 index가 1인걸 잊지 말자.

                        scrollView.smoothScrollBy(0,a[1]-p.y);

 

이제 리스너를 풀로 확인해볼까 :D 

        consultingButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                //scrollView.setScrollY(a[1]-p.y);
                scrollView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Rect rect = new Rect();
                        Point p = new Point();
                        scrollView.getGlobalVisibleRect(rect, p);

                        int a []=new int[2];
                        tvConsulting.getLocationInWindow(a);

                        scrollView.smoothScrollBy(0,a[1]-p.y);


                    }
                },400);

            }
        });

저 400이란 숫자는 무엇이냐, postDelayed의 두 번째 매개변수인데, 스크롤링의 지연시간을 얼마나 줄거냐고 묻는 값이다. 물론.. 매개변수의 값이 delayMills 인 만큼, 길면 길수록 부드러워지지만 시간이 느려진다.

반응형