티스토리 뷰

반응형

Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.

Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.

 

아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.

Detect end of ScrollView

ScrollView의 끝을 감지하기

 문제 내용 

I have an app, that has an Activity that uses a ScrollView. I need to detect when user gets to the bottom of the ScrollView. I did some googleing and I found this page where is explained. But, in the example, that guys extends ScrollView. As I said, I need to extend Activity.

제 앱은 ScrollView를 사용하는 Activity가 있습니다. 사용자가 ScrollView의 맨 아래로 이동할 때 감지해야합니다. 구글링을 해보니 이 페이지에서 설명된 내용을 찾았습니다. 그러나 예제에서는 ScrollView를 확장하고 있습니다. 제가 말한대로 Activity를 확장해야합니다.

 

So, I said "ok, let's try to make a custom class extending ScrollView, override the onScrollChanged() method, detect the end of the scroll, and act accordingly".

그래서 "커스텀 클래스를 만들어 ScrollView를 확장하고 onScrollChanged() 메소드를 재정의하고 스크롤의 끝을 감지한 후 그에 따라 조치를 취해보자"고 생각했습니다.

 

I did, but in this line:

저는 한 줄에서요.
scroll = (ScrollViewExt) findViewById(R.id.scrollView1);

 

it throws a java.lang.ClassCastException. I changed the <ScrollView> tags in my XML but, obviously, it doesn't work. My questions are: Why, if ScrollViewExt extends ScrollView, throws to my face a ClassCastException? is there any way to detect end of scrolling without messing too much?

그러나 이 줄에서 java.lang.ClassCastException 오류가 발생합니다. XML에서 태그를 변경했지만, 당연히 작동하지 않습니다. 제 질문은 다음과 같습니다. ScrollViewExt가 ScrollView를 확장하면 왜 ClassCastException이 발생하는 건가요? 스크롤링의 끝을 감지하는 방법은 덜 복잡하게 수정할 수 있는 방법이 있나요?

 

Thank you people.

감사합니다.

 

EDIT: As promised, here is the piece of my XML that matters:

수정: 약속한 대로, 여기 중요한 XML 부분입니다:
<ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >


        <WebView
            android:id="@+id/textterms"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_horizontal"
            android:textColor="@android:color/black" />

    </ScrollView>

 

I changed it from TextView to WebView to be able of justifying the text inside. What i want to achieve is the "Accept button doesn't activate until the terms of the contract are fully read" thing. My extended class is called ScrollViewExt. If i change the tag ScrollView for ScrollViewExt it throws an

제가 변경한 부분은 텍스트를 정렬하기 위해 TextView 대신 WebView로 변경했습니다. 목표는 "계약 조건이 모두 읽힐 때까지 동의 버튼이 활성화되지 않도록"하는 것입니다. 저의 확장 클래스는 ScrollViewExt입니다. ScrollView 태그를 ScrollViewExt로 변경하면 java.lang.ClassCastException 예외가 발생합니다.
android.view.InflateException: Binary XML file line #44: Error inflating class ScrollViewExt

 

because it doesn't understand the tag ScrollViewEx. I don't think it has a solution...

이유는 ScrollViewEx 태그를 이해하지 못하기 때문입니다. 이것에 대한 해결책은 없다고 생각합니다.

 

Thanks for your answers!

답변 감사합니다!

 

 

 

 높은 점수를 받은 Solution 

Did it!

이제 성공했습니다!

 

Aside of the fix Alexandre kindly provide me, I had to create an Interface:

알렉산드르가 친절하게 제공해 준 수정 사항 외에도, 인터페이스를 생성해야 했습니다.
public interface ScrollViewListener {
    void onScrollChanged(ScrollViewExt scrollView, 
                         int x, int y, int oldx, int oldy);
}

 

Then, i had to override the OnScrollChanged method from ScrollView in my ScrollViewExt:

그런 다음 ScrollViewExt에서 ScrollView의 OnScrollChanged 메서드를 오버라이드해야했습니다.
public class ScrollViewExt extends ScrollView {
    private ScrollViewListener scrollViewListener = null;
    public ScrollViewExt(Context context) {
        super(context);
    }

    public ScrollViewExt(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public ScrollViewExt(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }
}

 

Now, as Alexandre said, put the package name in the XML tag (my fault), make my Activity class implement the interface created before, and then, put it all together:

이제 Alexandre가 말한대로 XML 태그에 패키지 이름을 넣고, 이전에 만든 인터페이스를 Activity 클래스에서 구현한 다음, 모두 함께 넣어주면 됩니다.
scroll = (ScrollViewExt) findViewById(R.id.scrollView1);
scroll.setScrollViewListener(this);

 

And in the method OnScrollChanged, from the interface...

그리고 인터페이스의 OnScrollChanged 메서드에서...
@Override
public void onScrollChanged(ScrollViewExt scrollView, int x, int y, int oldx, int oldy) {
    // We take the last son in the scrollview
    View view = (View) scrollView.getChildAt(scrollView.getChildCount() - 1);
    int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));

    // if diff is zero, then the bottom has been reached
    if (diff == 0) {
        // do stuff
    }
}

 

And it worked!

잘 작동했습니다!

 

Thank you very much for your help, Alexandre!

알렉산드레님, 정말 감사합니다!

 

 

 

 가장 최근 달린 Solution 

I went through the solutions on the internet. Mostly solutions didn't work in the project I'm working on. Following solutions work fine for me.

인터넷에서 제시된 해결책들을 찾아보았지만, 대부분 내가 작업 중인 프로젝트에서는 동작하지 않았습니다. 하지만 아래의 해결책들은 제게 잘 동작했습니다.

 

Using onScrollChangeListener (works on API 23):

onScrollChangeListener를 사용하기(API 23에서 작동함):
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

                int bottom =   (scrollView.getChildAt(scrollView.getChildCount() - 1)).getHeight()-scrollView.getHeight()-scrollY;

                if(scrollY==0){
                    //top detected
                }
                if(bottom==0){
                    //bottom detected
                }
            }
        });
    }

 

using scrollChangeListener on TreeObserver

TreeObserver의 scrollChangeListener 사용하기
 scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            int bottom =   (scrollView.getChildAt(scrollView.getChildCount() - 1)).getHeight()-scrollView.getHeight()-scrollView.getScrollY();

            if(scrollView.getScrollY()==0){
                //top detected
            }
            if(bottom==0) {
                //bottom detected
            }
        }
    });

 

Hope this solution helps :)

이 솔루션이 도움이 되길 바랍니다 :)

 

 

 

출처 : https://stackoverflow.com/questions/10316743/detect-end-of-scrollview

반응형
댓글
공지사항
최근에 올라온 글