Tôi có thể cuộn ScrollView theo chương trình trong Android không?


145

Có cách nào để cuộn một ScrollViewchương trình đến một vị trí nhất định không?

Tôi đã tạo ra động TableLayoutđược đặt trong a ScrollView. Vì vậy, tôi muốn rằng trên một hành động cụ thể (như nhấp vào Nút, v.v.), hàng cụ thể sẽ tự động cuộn đến vị trí trên cùng.

Có thể không?

Câu trả lời:


165
ScrollView sv = (ScrollView)findViewById(R.id.scrl);
sv.scrollTo(0, sv.getBottom());

hoặc là

sv.scrollTo(5, 10);


43
Kết hợp câu trả lời của ercu và một nhận xét về nó, cách tốt nhất dường như là:mScrollView.post(new Runnable() { public void run() { mScrollView.fullScroll(View.FOCUS_DOWN); } });
sparrowt

2
scrollTo () sẽ không tạo ra ham muốn. Một người nên đi với fullScroll ()
Amit Yadav

3
Cuộn đẹp hơn với hiệu ứng tự nhiên: sv.smoothScrollTo (5, 10)
ivan.panasiuk

205

Câu trả lời từ Pragna không hoạt động luôn, hãy thử điều này:

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.scrollTo(0, mScrollView.getBottom());
        } 
});

hoặc là

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
        } 
});

nếu bạn muốn cuộn để bắt đầu

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.fullScroll(mScrollView.FOCUS_UP);
        } 
});

28
Tôi đã sử dụng mScrollView.fullScroll(mScrollView.FOCUS_DOWN);với thành công.
amcc

3
Tôi có thể xác nhận phát hiện của Vanthel. mScrollView.fullScroll trong một bài đăng có thể chạy được.
AlanKley

1
Thông minh ! Thật vậy, không có Runnable, nó đã không hoạt động. Bây giờ, nó hoạt động! :)
Regis_AG

5
@HiteshDhamshaniya Nếu bạn muốn cuộn trơn tru, hãy thử mScrollView.smoothScrollTo(0, mScrollView.getBottom());.
Mike Ortiz

1
Tại sao nó cần postở đây?
Nói dối

35

Tôi muốn scrollView cuộn trực tiếp sau onCreateView () (không phải sau khi nhấp vào nút). Để làm cho nó hoạt động, tôi cần sử dụng ViewTreeObserver:

mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mScrollView.post(new Runnable() {
                public void run() {
                    mScrollView.fullScroll(View.FOCUS_DOWN);
                }
            });
        }
    });

Nhưng hãy cẩn thận rằng cái này sẽ được gọi mỗi khi có thứ gì đó được bố trí (ví dụ: nếu bạn đặt chế độ xem vô hình hoặc tương tự) vì vậy đừng quên xóa trình nghe này nếu bạn không cần nó nữa:

public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) trên SDK Lvl <16

hoặc là

public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) trong SDK Lvl> = 16


23

Có rất nhiều câu trả lời hay ở đây, nhưng tôi chỉ muốn thêm một điều. Đôi khi, bạn muốn cuộn ScrollView của mình sang chế độ xem cụ thể của bố cục, thay vì cuộn toàn bộ lên trên cùng hoặc dưới cùng.

Một ví dụ đơn giản: trong biểu mẫu đăng ký, nếu người dùng chạm vào nút "Đăng ký" khi văn bản chỉnh sửa của biểu mẫu không được điền, bạn muốn cuộn đến văn bản chỉnh sửa cụ thể đó để nói với người dùng rằng anh ta phải điền vào trường đó.

Trong trường hợp đó, bạn có thể làm một cái gì đó như thế:

scrollView.post(new Runnable() { 
        public void run() { 
             scrollView.scrollTo(0, editText.getBottom());
        } 
});

hoặc, nếu bạn muốn cuộn trơn tru thay vì cuộn tức thì:

scrollView.post(new Runnable() { 
            public void run() { 
                 scrollView.smoothScrollTo(0, editText.getBottom());
            } 
    });

Rõ ràng bạn có thể sử dụng bất kỳ loại chế độ xem nào thay vì Chỉnh sửa văn bản. Lưu ý rằng getBottom () trả về tọa độ của chế độ xem dựa trên bố cục chính của nó, vì vậy tất cả các chế độ xem được sử dụng trong ScrollView chỉ nên có cha mẹ (ví dụ: Bố cục tuyến tính).

Nếu bạn có nhiều cha mẹ bên trong con của ScrollView, giải pháp duy nhất tôi tìm thấy là gọi requestChildF Focus trên chế độ xem chính:

editText.getParent().requestChildFocus(editText, editText);

nhưng trong trường hợp này bạn không thể có một cuộn trơn tru.

Tôi hy vọng câu trả lời này có thể giúp một người có cùng vấn đề.


1
@ John Vui mừng vì nó đã giúp bạn :)
Mattia Ruggiero

20

Sử dụng một cái gì đó như thế này:

mScrollView.scrollBy(10, 10);

hoặc là

mScrollView.scrollTo(10, 10);


8

Nếu bạn muốn cuộn ngay lập tức thì bạn có thể sử dụng:

ScrollView scroll= (ScrollView)findViewById(R.id.scroll);
scroll.scrollTo(0, scroll.getBottom());

            OR

scroll.fullScroll(View.FOCUS_DOWN);

            OR

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

Hoặc nếu bạn muốn cuộn trơn tru và chậm rãi để bạn có thể sử dụng điều này:

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();
    }

những gì mà catchkhối làm gì?
John Sardinha

1
Bắt khối là bắt ngoại lệ trong khi cuộn nếu tìm thấy bất kỳ.
Maddy

5

** để cuộn lên chiều cao mong muốn. Tôi đã đưa ra một số giải pháp tốt **

                scrollView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.scrollBy(0, childView.getHeight());
                    }
                }, 100);

4

Tôi đã làm việc này để cuộn xuống dưới cùng của ScrollView (bên trong có TextView):

(Tôi đặt cái này lên một phương thức cập nhật TextView)

final ScrollView myScrollView = (ScrollView) findViewById(R.id.myScroller);
    myScrollView.post(new Runnable() {
    public void run() {
        myScrollView.fullScroll(View.FOCUS_DOWN);
    }
});

4

Vâng, bạn có thể.

Hãy nói rằng bạn có một Layoutvà bên trong đó, bạn có nhiều Views. Vì vậy, nếu bạn muốn cuộn đến bất kỳ Viewchương trình nào , bạn phải viết đoạn mã sau:

Ví dụ:

content_main.xml

<ScrollView
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/txtView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>
</ScrollView>

MainActivity.java

ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
Button btn = (Button) findViewById(R.id.ivEventBanner);
TextView txtView = (TextView) findViewById(R.id.ivEditBannerImage);

Nếu bạn muốn cuộn đến một cụ thể View, giả sử txtview , trong trường hợp này, chỉ cần viết:

scrollView.smoothScrollTo(txtView.getScrollX(),txtView.getScrollY());

Và bạn đã hoàn thành.


3

Lưu ý: nếu bạn đã có trong một chủ đề, bạn phải tạo một chủ đề bài viết mới, hoặc nó không cuộn chiều cao mới cho đến khi kết thúc đầy đủ (đối với tôi). Ví dụ:

void LogMe(final String s){
    runOnUiThread(new Runnable() {
        public void run() {
            connectionLog.setText(connectionLog.getText() + "\n" + s);
            final ScrollView sv = (ScrollView)connectLayout.findViewById(R.id.scrollView);
            sv.post(new Runnable() {
                public void run() {
                    sv.fullScroll(sv.FOCUS_DOWN);
                    /*
                    sv.scrollTo(0,sv.getBottom());
                    sv.scrollBy(0,sv.getHeight());*/
                }
            });
        }
    });
}

3

Thêm một câu trả lời khác không liên quan đến tọa độ.

Điều này sẽ mang lại chế độ xem mong muốn của bạn để tập trung (nhưng không đến vị trí trên cùng):

  yourView.getParent().requestChildFocus(yourView,yourView);

công khai void RequestChildF Focus (Xem con, Xem tập trung)

đứa trẻ - Đứa trẻ của ViewParent này muốn tập trung. Chế độ xem này sẽ chứa chế độ xem tập trung. Nó không nhất thiết là quan điểm thực sự có trọng tâm.

tập trung - Quan điểm là hậu duệ của trẻ em thực sự có trọng tâm


Chính xác những gì tôi cần, cảm ơn bạn. Yêu cầu đầu tiên tập trung cho bạn xem cuộn và sau đó scrollView.smoothScrollTo (0, scrollView.getChildAt (0) .getBottom ());
Vulovic Vukasin

3

chỉ cần cuộn trang:

ScrollView sv = (ScrollView) findViewById(your_scroll_view);
sv.pageScroll(View.FOCUS_DOWN);

2

Mọi người đều đăng những câu trả lời phức tạp như vậy.

Tôi tìm thấy một câu trả lời dễ dàng, để cuộn xuống phía dưới, độc đáo:

final ScrollView myScroller = (ScrollView) findViewById(R.id.myScrollerView);

// Scroll views can only have 1 child, so get the first child's bottom,
// which should be the full size of the whole content inside the ScrollView
myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );

Và, nếu cần, bạn có thể đặt dòng mã thứ hai, ở trên, vào một runnable:

myScroller.post( new Runnable() {
    @Override
    public void run() {
        myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );
    }
}

Tôi đã mất nhiều nghiên cứu và chơi xung quanh để tìm ra giải pháp đơn giản này. Tôi hy vọng nó cũng giúp bạn! :)


1

Tôi đã sử dụng Runnable với sv.fullScroll (View.FOCUS_DOWN); Nó hoạt động hoàn hảo cho vấn đề tức thời, nhưng phương pháp đó khiến ScrollView lấy Focus từ toàn bộ màn hình, nếu bạn thực hiện AutoScroll đó mỗi lần, sẽ không có EditText nào có thể nhận thông tin từ người dùng, giải pháp của tôi là sử dụng một mã khác dưới runnable:

sv.scrollTo (0, sv.getBottom () + sv.getScrollY ());

làm cho giống nhau mà không mất tập trung vào quan điểm quan trọng

lời chào hỏi.


0

nó làm việc cho tôi

mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mScrollView.post(new Runnable() {
                public void run() {
                    mScrollView.fullScroll(View.FOCUS_DOWN);
                }
            });
        }
    });

0
private int totalHeight = 0;

ViewTreeObserver ScrollTr = loutMain.getViewTreeObserver();
ScrollTr.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            loutMain.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        } else {
            loutMain.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
        TotalHeight = loutMain.getMeasuredHeight();

    }
});

scrollMain.smoothScrollTo(0, totalHeight);

0
I had to create Interface

public interface ScrollViewListener {
    void onScrollChanged(ScrollViewExt scrollView, 
                         int x, int y, int oldx, int oldy);
}    

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;

public class CustomScrollView extends ScrollView {
    private ScrollViewListener scrollViewListener = null;
    public ScrollViewExt(Context context) {
        super(context);
    }

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

    public CustomScrollView (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);
        }
    }
}




<"Your Package name ".CustomScrollView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusableInTouchMode="true"
    android:scrollbars="vertical">

    private CustomScrollView scrollView;

scrollView = (CustomScrollView)mView.findViewById(R.id.scrollView);
        scrollView.setScrollViewListener(this);


    @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
            //TODO keshav gers
            pausePlayer();
            videoFullScreenPlayer.setVisibility(View.GONE);

        }
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.