Android : ScrollView 강제로 맨 아래


답변:


274

scroll.fullScroll(View.FOCUS_DOWN) 또한 작동해야합니다.

이것을 넣어 scroll.Post(Runnable run)

코 틀린 코드

scrollView.post {
   scrollView.fullScroll(View.FOCUS_DOWN)
}

6
그것은 아무것도하지 않는 것 같습니다, 어떤 제안? 나는 onCreate에서 시도하고 나중에 버튼의 onClick에서 시도했습니다.
RichardJohnn

방향을 바꾸는 데 효과가없는 것 같습니다. 그렇지 않으면 작동합니다.
Prashant

1
레이아웃 크기가 호출하기 직전에 변경된 경우에는 작동하지 않습니다. 대신 게시해야합니다.
MLProgrammer-CiM

2
이것과 아래는 완전히 팽창 할 수있는 시간을 줄 때까지 작동하지 않으며 단지 ademar 답변을 단순화합니다. scrollView.postDelayed (new Runnable () {@Public void run () 재정의 {scrollView.fullScroll (View.FOCUS_UP // Or Down);}}, 1000);
EngineSense

scroll.fullScroll (View.FOCUS_DOWN)은 포커스 변경으로 이어집니다. 두 개의 EditText와 같이 포커스 가능한 뷰가 둘 이상있을 때 이상한 동작이 발생합니다. 하단에서 제공하는 다른 솔루션을 확인하십시오.
peacepassion

332

다음과 같이 scroll.post 내부에서 코드를 실행해야합니다.

scroll.post(new Runnable() {            
    @Override
    public void run() {
           scroll.fullScroll(View.FOCUS_DOWN);              
    }
});

4
포커스 현재 요소를 잃지 않는 방법이 있습니다. 이렇게하면 현재 요소의 포커스를 잃게됩니다 (
스크롤 뷰

2
레이아웃이 아직 측정 및 레이아웃되지 않은 경우에만 필요합니다 (예 : onCreate에서 실행하는 경우). 버튼을 누르는 것과 같은 경우에는 .post ()가 필요하지 않습니다.
Patrick Boos

12
ScrollView에 초점을 맞추지 않으려면 scroll.scrollTo(0, scroll.getHeight());아래쪽으로 이동하거나 scroll.smoothScrollTo(0, scroll.getHeight());부드러운 스크롤을 사용하십시오
yuval

이 코드는 가능한 메모리 누수가 아닌가? 활동 (스크롤)보기에 대한 참조를 보유하는 익명의 Runnable이 작성됩니다. 런너 블이 작업을 실행하는 동안 액티비티가 소멸되면 스크롤 뷰에 대한 참조가 누출됩니다.
Jenever

에서 코 틀린 :scrollView.post { scrollView.fullScroll(View.FOCUS_DOWN) }
알버트 빌라 칼보

94

scroll.fullScroll(View.FOCUS_DOWN)초점의 변화로 이어질 것입니다. 두 개의 EditText와 같이 둘 이상의 포커스 가능한 뷰가있는 경우 이상한 동작이 발생합니다. 이 질문에는 다른 방법이 있습니다.

    View lastChild = scrollLayout.getChildAt(scrollLayout.getChildCount() - 1);
    int bottom = lastChild.getBottom() + scrollLayout.getPaddingBottom();
    int sy = scrollLayout.getScrollY();
    int sh = scrollLayout.getHeight();
    int delta = bottom - (sy + sh);

    scrollLayout.smoothScrollBy(0, delta);

이것은 잘 작동합니다.

코 틀린 확장

fun ScrollView.scrollToBottom() {
    val lastChild = getChildAt(childCount - 1)
    val bottom = lastChild.bottom + paddingBottom
    val delta = bottom - (scrollY+ height)        
    smoothScrollBy(0, delta)
}

더 이상 시간을 낭비 할 필요가 없었습니다. 내가 필요한 것
Alexandre G

6
더 많은 투표를해야합니다. 가장 좋은 답변입니다.
Eric Lange

1
이것이 가장 좋은 대답입니다.
void pointer

1
이 페이지의 다른 모든 것을 시도했습니다. 이것이 유일하게 작동했으며 EditText가 포커스를 잃지 않습니다. 감사합니다.
Joel

키보드가 표시된 상태에서 아래로 스크롤해야하는 경우이 코드를 이 라이브러리 와 결합하십시오 . 매력처럼 작동합니다.
wonsuc

47

때때로 scrollView.post가 작동하지 않습니다

 scrollView.post(new Runnable() {
        @Override
        public void run() {
            scrollView.fullScroll(ScrollView.FOCUS_DOWN);
        }
    });

그러나 scrollView.postDelayed를 사용하면 확실히 작동합니다.

 scrollView.postDelayed(new Runnable() {
        @Override
        public void run() {
            scrollView.fullScroll(ScrollView.FOCUS_DOWN);
        }
    },1000);

식별 주셔서 감사합니다. postDelayed가 더 나은 솔루션입니다.
Prashant

@Prashant :) :) :)
Ajay Shrestha

1
활동을 마칠 때 Runnable을 폐기해야한다는 것을 기억하십시오
FabioR

38

나에게 가장 효과가 있었던 것은

scroll_view.post(new Runnable() {
     @Override
     public void run() {
         // This method works but animates the scrolling 
         // which looks weird on first load
         // scroll_view.fullScroll(View.FOCUS_DOWN);

         // This method works even better because there are no animations.
         scroll_view.scrollTo(0, scroll_view.getBottom());
     }
});

나는 이것을 시도했지만 여기의 알고리즘은 잘못되었습니다. 하단에서 내 답변을 확인하십시오.
peacepassion

28

나는 완벽하게 작동하도록 증분합니다.

    private void sendScroll(){
        final Handler handler = new Handler();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {Thread.sleep(100);} catch (InterruptedException e) {}
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.fullScroll(View.FOCUS_DOWN);
                    }
                });
            }
        }).start();
    }

노트

이 답변은 이전 버전의 Android에 대한 해결 방법입니다. 오늘날 postDelayed에는 더 이상 버그가 없으므로 사용해야합니다.


3
2 이상은 아니지만 이것은 내 전화 (LG JellyBean 4.1.2 Optimus G)에서 잘 작동합니다.
영재

9
scrollView.postDelayed (runnable, 100)를 사용하지 않는 이유는 무엇입니까?
매트 울프

1
당시 @MattWolfe는 일부 이전 버전의 Android에서는 작동하지 않습니다. 그러나 오늘이 답변은 더 이상 사용되지 않습니다.
ademar111190

4
신의 사랑을 위해 scrollView.postDelayed (runnable, 100)를 사용하십시오! :)
Alex Lockwood

1
@AlexLockwood 메모를 추가했습니다. 사람들이 다음을 사용하기를 바랍니다 postDelayed:)
ademar111190

4

나는 그것을 성공적으로 시도했다.

scrollView.postDelayed(new Runnable() {
    @Override
    public void run() {
        scrollView.smoothScrollTo(0, scrollView.getHeight());
    }
}, 1000);

3

뷰가 아직로드되지 않으면 스크롤 할 수 없습니다. 위와 같이 게시물 또는 수면 통화로 '나중에'할 수 있지만 이는 그리 우아하지 않습니다.

스크롤을 계획하고 다음 onLayout ()에서 수행하는 것이 좋습니다. 예제 코드는 다음과 같습니다.

https://stackoverflow.com/a/10209457/1310343


3

고려해야 할 한 가지는 설정하지 않는 것입니다. 자녀 컨트롤, 특히 EditText 컨트롤에 RequestFocus 속성이 설정되어 있지 않은지 확인하십시오. 이것은 레이아웃에서 마지막으로 해석 된 속성 중 하나 일 수 있으며 부모 (레이아웃 또는 ScrollView)의 중력 설정을 무시합니다.


3

아래로 스크롤하는 다른 방법이 있습니다.

fun ScrollView.scrollToBottom() {
    // use this for scroll immediately
    scrollTo(0, this.getChildAt(0).height) 

    // or this for smooth scroll
    //smoothScrollBy(0, this.getChildAt(0).height)

    // or this for **very** smooth scroll
    //ObjectAnimator.ofInt(this, "scrollY", this.getChildAt(0).height).setDuration(2000).start()
}

사용

스크롤보기가 이미 배치되어 있다면

my_scroll_view.scrollToBottom()

스크롤보기가 완료되지 않은 경우 (예 : 활동 onCreate방법 에서 맨 아래로 스크롤 )

my_scroll_view.post { 
   my_scroll_view.scrollToBottom()          
}

1

질문에 대한 정확한 대답은 아니지만 EditText가 포커스를 얻으면 아래로 스크롤해야했습니다. 그러나 받아 들여진 대답은 ET도 (ScrollView로 가정) 초점을 즉시 잃게합니다.

내 해결 방법은 다음과 같습니다.

emailEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus){
            Toast.makeText(getActivity(), "got the focus", Toast.LENGTH_LONG).show();
            scrollView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    scrollView.fullScroll(ScrollView.FOCUS_DOWN);
                }
            }, 200);
        }else {
            Toast.makeText(getActivity(), "lost the focus", Toast.LENGTH_LONG).show();
        }
    }
});

1

실제로 fullScroll을 두 번 호출하면 트릭이 수행됩니다.

myScrollView.fullScroll(View.FOCUS_DOWN);

myScrollView.post(new Runnable() {
    @Override
    public void run() {
        myScrollView.fullScroll(View.FOCUS_DOWN);
    }
});

첫 번째 (실패한) 스크롤을 수행 한 직후 post () 메소드의 활성화와 관련이있을 수 있습니다. 이 동작은 myScrollView에서 이전에 메소드를 호출 한 후에 발생하므로 첫 번째 fullScroll () 메소드를 관련이있는 다른 것으로 대체 할 수 있습니다.


0

Kotlin 코 루틴 으로이 작업을 수행하는 또 다른 멋진 방법이 있습니다. 실행 가능 파일 (post / postDelayed)을 가진 처리기에 반대되는 코 루틴을 사용하면 지연된 작업을 실행하기 위해 값 비싼 스레드가 실행되지 않는다는 장점이 있습니다.

launch(UI){
    delay(300)
    scrollView.fullScroll(View.FOCUS_DOWN)
}

코 루틴의 HandlerContext를 UI로 지정하는 것이 중요합니다. 그렇지 않으면 지연된 조치가 UI 스레드에서 호출되지 않을 수 있습니다.


0

이 경우에는 scroll.scrollTo (0, sc.getBottom ()) 이 작동하지 않습니다. scroll.post를 사용 하십시오.

예:

scroll.post(new Runnable() {
  @Override
  public void run() {
  scroll.fullScroll(View.FOCUS_DOWN);
  } 
});

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.