Làm cách nào để cuộn lên trên cùng của bố cục ScrollView dài?


162

Đối với một phần của ứng dụng của tôi, người dùng được cung cấp một danh sách các tên và được yêu cầu nhóm chúng khi chúng thấy phù hợp.

(Lưu ý, mã ListView đã được sao chép nguyên văn từ hướng dẫn Chế độ xem Android. Tôi chưa tùy chỉnh nó theo nhu cầu của mình, tôi chỉ đang cố gắng tìm ra cách để thực hiện công việc này.)

Bố cục cơ bản là một linearLayout, chứa ScrollView (được gọi là "GroupsScrollView" trong mã bên dưới), chứa RelativeLayout. Tôi có một số nút và văn bản, và sau đó ListView của tôi bên dưới đó, hiển thị danh sách các tên. Tất cả điều này cao hơn khu vực màn hình có thể nhìn thấy, vì vậy người dùng được phép cuộn theo chiều dọc để xem tất cả.

Tất cả đều hoạt động tốt, ngoại trừ khi trang tải, nó luôn được cuộn trước lên đầu ListView của tôi - ở giữa trang. Văn bản và các nút tôi đã tạo cho người dùng biết những gì cần làm không thể nhìn thấy.

Tôi có thể lấy màn hình và cuộn lên, nó hoạt động rất tốt, nhưng tôi muốn màn hình tải đã được cuộn lên trên cùng. Người dùng không cần phải cuộn LÊN để xem đầu trang mới tải. Nhưng tất cả mọi thứ tôi đã cố gắng để lập trình cuộn lên trên cùng của màn hình đã thất bại.

Đây là phương pháp onCreate của tôi:

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.groups);

    mainScrollView = (ScrollView)findViewById(R.id.groupsScrollView);

    //get the Bundle out of the Intent...
    Bundle extras = getIntent().getExtras();
    mNames = extras.getStringArray("mNames");

    setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, mNames));

    ListView lv = getListView();
    lv.setTextFilterEnabled(true);

    //This is the line I'm having issues with
    mainScrollView.pageScroll(View.FOCUS_UP);

    lv.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
            int position, long id) {
          // When clicked, show a toast with the TextView text
          Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
              Toast.LENGTH_SHORT).show();
        }
      });
}

Dòng "mainScrollView.pageScroll (View.FOCUS_UP); là sự cố. Nó không gây ra lỗi, nhưng dường như không làm gì cả. Tôi đã thử scrollTo (0,0), scrollDirection (View.FOCUS_UP ), và mọi thứ khác tôi có thể nghĩ ra.

Vì tôi không gặp lỗi nên tôi phải giả sử rằng các lệnh cuộn này đang thực sự hoạt động, nhưng chúng đang cuộn lên phía trên ListView, thay vì trên cùng của ScrollView hoặc RelativeLayout có chứa nó. Điều này dường như được xác nhận bằng mô tả riêng của Google về phương thức scrollTo (int x, int y) trong đó họ nói "Phiên bản này cũng kẹp việc cuộn vào giới hạn của con chúng tôi.".

Vì vậy, để đặt câu hỏi dài hơn nữa, làm cách nào để tôi tải một loạt lượt xem trên màn hình có trong ScrollView và sau đó lập trình cuộn toàn bộ nội dung lên đầu trang để người dùng có thể tương tác với nó?

Cảm ơn!

Câu trả lời:


264

Thử

mainScrollView.fullScroll(ScrollView.FOCUS_UP);

nó nên hoạt động


Làm việc cho tôi cũng. : D
Muntasir Aonik

1
Tôi thấy ScrollView # fullScroll () thay đổi trọng tâm hiện tại. Tôi đã thử nghiệm với EditText.
ảo

175

Có cùng một vấn đề, có lẽ một số loại lỗi.

Ngay cả fullScroll(ScrollView.FOCUS_UP)câu trả lời khác cũng không hoạt động.
Điều duy nhất làm việc cho tôi là gọi scroll_view.smoothScrollTo(0,0)ngay sau khi hộp thoại được hiển thị.


Điều này làm việc ban đầu, nhưng sau đó khi tôi cố gắng làm đi làm lại, cách tiếp cận này không cho kết quả khả quan.
JaydeepW

16
tôi giải quyết từ scroll_view.smoothScrollTo (0,0), khi chúng tôi có listview bên cạnh scrollview tại thời điểm đó fullScroll (ScrollView.FOCUS_UP) sẽ không hoạt động.
Kirtikumar A.

1
scroll_view.smoothScrollTo (0,0) làm việc tốt hơn đối với tôi so với mainScrollView.fullScroll (ScrollView.FOCUS_UP); CẢM ƠN!
marienke

2
Trên hầu hết các thiết bị fullScroll (ScrollView.FOCUS_UP) đã hoạt động, nhưng trên Nexus 5 và các thiết bị có kích thước văn bản tăng lên - fullSscroll di chuyển dưới thanh hành động, smoothScrollTo (0,0) hoạt động tốt hơn trên tất cả các thiết bị.
jt-gilkeson

Điều này cũng có lợi thế hơn fullScroll()ở chỗ nó giữ cho mục được chọn vẫn được chọn sau khi di chuyển. Với fullScroll(), mục đầu tiên trong cuộn xem được chọn lại mỗi lần trong trường hợp của tôi, độc lập với mục đã chọn trước khi cuộn di chuyển lên trên.
GeertVc

97

tôi đã có cùng một vấn đề và điều này đã khắc phục nó. Hy vọng nó sẽ giúp bạn.

listView.setFocusable(false);

3
Đây là giải pháp chính xác cho lưới xem cũng. Nó xảy ra khi bạn có nhiều hơn một thành phần xem trong cùng một nhóm chế độ xem, đặc biệt là một chế độ xem khác ở đầu danh sách hoặc chế độ xem lưới. Vì bộ điều hợp thông báo cho giao diện người dùng, nên chế độ xem được tạo lại và cuộn lên phần tử đầu tiên. Chỉ cần gọi listView.setF Focusable (false) / GridView.setF Focusable (false). Nếu bạn làm điều đó từ tệp xml, nó sẽ không hoạt động.
omersem

Giải pháp này cũng hoạt động trong trường hợp của tôi, tôi đã có RecyclerView bên trong NestedScrollView để nó tự động cuộn xuống. Cảm ơn, anh bạn!
Nilesh Rathore

Tôi đã phải thêm cái này trước khi cài đặt Adaptor nhưng sau đó nó hoạt động như một bùa mê. Cảm ơn
Cộng đồng

giải thích hoàn hảo !!
Borja López

Cảm ơn bạn cả Miguel và đặc biệt là omersem cho lời giải thích, đặc biệt là phần về cách nó wont làm việc nếu đặt trong XML, điều này đã cứu tôi một số nhức đầu
buradd

53

scrollViewObject.fullScroll(ScrollView.FOCUS_UP)Điều này hoạt động tốt, nhưng chỉ có vấn đề với dòng này là, khi dữ liệu được điền vào scrollViewObject, đã được gọi ngay lập tức. Bạn phải đợi vài mili giây cho đến khi dữ liệu được điền. Hãy thử mã này:

scrollViewObject.postDelayed(new Runnable() {
    @Override
    public void run() {
        scroll.fullScroll(ScrollView.FOCUS_UP);
    }
}, 600);

HOẶC LÀ

 scrollViewObject.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        scrollViewObject.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        scrollViewObject.fullScroll(View.FOCUS_UP);
    }
});

Tôi đã xử lý vấn đề tương tự trong đó scrollview được cho là đang cuộn xuống cuối trang, sửa nó ngay!
Bộ lạc máy

1
Thay vì đoán số "ma thuật" x số mili giây bạn phải chờ, các đối tượng Xem cung cấp một phương thức bài đăng (Runnable) mà bạn có thể sử dụng để đăng bài có thể chạy được khi tiện ích hiển thị trên UI.
Ryan

@Ryan: bài đăng (Runnable) luôn không hoạt động với tôi trên Nexus 5 (Genymotion)
Dika

bài đăng (Runnable) có thể không hoạt động vì nếu bạn tìm nạp dữ liệu sau khi xem bước thông tin, khi lần đầu tiên cuộn lên hoạt động và sau đó dữ liệu được đưa vào chế độ xem. Vì vậy, bạn nên sử dụng postDelayed (Runnable, dummyMillis) hoặc bạn nên sử dụng scroll.fullScroll (ScrollView.FOCUS_UP) sau khi xử lý dữ liệu.
oguzhan

Giải pháp đầu tiên của bạn trong đó bạn đưa ra millis tĩnh là một cách tiếp cận tồi.
Malwinder Singh

35

Vấn đề chính đối với tất cả các giải pháp hợp lệ này là bạn đang cố gắng di chuyển cuộn lên khi nó chưa được vẽ trên màn hình.

Bạn cần đợi cho đến khi chế độ xem cuộn trên màn hình, sau đó di chuyển nó lên với bất kỳ giải pháp nào trong số này. Đây là giải pháp tốt hơn so với sau ngày, vì bạn không bận tâm về sự chậm trễ.

    // Wait until my scrollView is ready
    scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            // Ready, move up
            scrollView.fullScroll(View.FOCUS_UP);
        }
    });

7
Giải pháp hay - Đừng quên xóa Trình nghe toàn cầu khi kết thúc onGlobalLayoutphương thức gọi scrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Nilhcem

30

Rất dễ

    ScrollView scroll = (ScrollView) findViewById(R.id.addresses_scroll);
    scroll.setFocusableInTouchMode(true);
    scroll.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);

3
đối với tôi nó không hoạt động (dòng thứ 3), giải pháp là: scroll.fullScroll (View.FOCUS_UP); (bao gồm 2 dòng đầu tiên của bạn)
medskill

@medskill, Xin chào, bạn đã viết những thứ này trong tệp xml của mình chưa? Tôi tin rằng điều này chỉ hoạt động trong onCreate().
biết đến

@ im UnknownJ.Kimu Làm việc cho tôi trong tệp xml
Paglian

Điều này làm việc cho tôi. Bạn cần cả dòng thứ hai và thứ ba. Nó không hoạt động trong XML đối với tôi.
ET

2
Tôi sẽ hôn bạn nếu tôi có thể! Đã dành 1-2 giờ cho việc này. Cái tốt nhất khi chờ hai lượt xem tải và không muốn tập trung vào chúng. Đã thêm nó vào onResume ().
John T

24

Tôi gặp phải vấn đề tương tự Khi tôi đang sử dụng Scrollview bên trong View Flipper hoặc Dialog trường hợp đó scrollViewObject.fullScroll(ScrollView.FOCUS_UP)trả về sai vì vậy trường hợp đó scrollViewObject.smoothScrollTo(0, 0) được xử lý cho tôi

Cuộn tiêu điểm hàng đầu


19
 final ScrollView scrollview = (ScrollView)findViewById(R.id.selected_place_layout_scrollview);

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

9
runOnUiThread( new Runnable(){
   @Override
   public void run(){
      mainScrollView.fullScroll(ScrollView.FOCUS_UP);
   }
}

9

Điều này làm việc cho tôi

scroll_view.smoothScrollTo(0,0); // scroll to top of screen

6

Đây là lực lượng cuộn cho scrollview :

            scrollView.post(new Runnable() {
                @Override
                public void run() {
                    scrollView.scrollTo(0, 0);
                    scrollView.pageScroll(View.FOCUS_UP);
                    scrollView.smoothScrollTo(0,0);
                }
            });

4
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        // Ready, move up
        scrollView.fullScroll(View.FOCUS_UP);
    }
});

1

Tôi đã sửa vấn đề của mình trong Kotlin như thế này:

scrollview.isFocusableInTouchMode = true
scrollview.fullScroll(View.FOCUS_UP)
scrollview.smoothScrollTo(0,0)

0
@SuppressWarnings({ "deprecation", "unchecked" })
public void swipeTopToBottom(AppiumDriver<MobileElement> driver) 
                    throws InterruptedException {
       Dimension dimensions = driver.manage().window().getSize();
        Double screenHeightStart = dimensions.getHeight() * 0.30;
        int scrollStart = screenHeightStart.intValue();
        System.out.println("s="+scrollStart);
        Double screenHeightEnd = dimensions.getHeight()*0.90;
        int scrollEnd = screenHeightEnd.intValue();
        driver.swipe(0,scrollStart,0,scrollEnd,2000);
        CommonUtils.threadWait(driver, 3000);
    }

điều này sẽ chạy chắc chắn,
Ajeet Gour

Vui lòng cung cấp một lời giải thích ngắn gọn về cách câu trả lời này giải quyết vấn đề.
Ayberk Özgür
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.