Tôi muốn một ScrollView để bắt đầu tất cả các cách ở phía dưới. Phương pháp nào?
Tôi muốn một ScrollView để bắt đầu tất cả các cách ở phía dưới. Phương pháp nào?
Câu trả lời:
scroll.fullScroll(View.FOCUS_DOWN)
cũng nên làm việc.
Đặt cái này vào scroll.Post(Runnable run)
Mã Kotlin
scrollView.post {
scrollView.fullScroll(View.FOCUS_DOWN)
}
bạn nên chạy mã bên trong scroll.post như thế này:
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
scroll.scrollTo(0, scroll.getHeight());
để nhảy xuống dưới hoặc scroll.smoothScrollTo(0, scroll.getHeight());
để cuộn mượt hơn
scrollView.post { scrollView.fullScroll(View.FOCUS_DOWN) }
scroll.fullScroll(View.FOCUS_DOWN)
sẽ dẫn đến sự thay đổi của trọng tâm. Điều đó sẽ mang lại một số hành vi kỳ lạ khi có nhiều hơn một chế độ xem có thể tập trung, ví dụ: hai EditText. Có một cách khác cho câu hỏi này.
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);
Điều này hoạt động tốt.
Gia hạn Kotlin
fun ScrollView.scrollToBottom() {
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY+ height)
smoothScrollBy(0, delta)
}
Đôi khi scrollView.post không hoạt động
scrollView.post(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
NHƯNG nếu bạn sử dụng scrollView.postDelayed, nó chắc chắn sẽ hoạt động
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
},1000);
Điều làm việc tốt nhất cho tôi là
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());
}
});
Tôi gia tăng để làm việc hoàn hảo.
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();
}
Ghi chú
Câu trả lời này là một cách giải quyết cho các phiên bản Android thực sự cũ. Ngày nay postDelayed
không còn lỗi đó nữa và bạn nên sử dụng nó.
postDelayed
:)
tôi đã thử thành công
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.smoothScrollTo(0, scrollView.getHeight());
}
}, 1000);
Khi chế độ xem chưa được tải, bạn không thể cuộn. Bạn có thể thực hiện 'sau' với một bài đăng hoặc cuộc gọi ngủ như trên, nhưng điều này không phải là rất thanh lịch.
Tốt hơn là lập kế hoạch cuộn và thực hiện nó trên onLayout () tiếp theo. Mã ví dụ ở đây:
Một điều cần xem xét là những gì KHÔNG được thiết lập. Hãy chắc chắn rằng các điều khiển con của bạn, đặc biệt là các điều khiển EditText, không có bộ thuộc tính RequestF Focus. Đây có thể là một trong những thuộc tính được giải thích cuối cùng trên bố cục và nó sẽ ghi đè cài đặt trọng lực trên bố mẹ của nó (bố cục hoặc ScrollView).
Đây là một số cách khác để cuộn xuống dưới cùng
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()
}
Sử dụng
Nếu bạn đã xem xong
my_scroll_view.scrollToBottom()
Nếu cuộn xem của bạn chưa hoàn thành được đặt ra (ví dụ: bạn cuộn xuống dưới cùng trong onCreate
phương thức Hoạt động ...)
my_scroll_view.post {
my_scroll_view.scrollToBottom()
}
Không chính xác câu trả lời cho câu hỏi, nhưng tôi cần phải cuộn xuống ngay khi một EditText có trọng tâm. Tuy nhiên, câu trả lời được chấp nhận sẽ khiến ET cũng mất tập trung ngay lập tức (với ScrollView tôi giả định).
Cách giải quyết của tôi là như sau:
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();
}
}
});
Tôi thực sự thấy rằng việc gọi fullScroll hai lần thực hiện thủ thuật:
myScrollView.fullScroll(View.FOCUS_DOWN);
myScrollView.post(new Runnable() {
@Override
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});
Nó có thể có liên quan đến việc kích hoạt phương thức post () ngay sau khi thực hiện cuộn đầu tiên (không thành công). Tôi nghĩ rằng hành vi này xảy ra sau bất kỳ cuộc gọi phương thức nào trước đây trên myScrollView, vì vậy bạn có thể thử thay thế phương thức fullScroll () đầu tiên bằng bất kỳ điều gì khác có thể liên quan đến bạn.
Sử dụng có một cách tuyệt vời khác để làm điều này với các coroutines của Kotlin. Ưu điểm của việc sử dụng coroutine trái ngược với Handler với runnable (post / postDelayed) là nó không kích hoạt một luồng đắt tiền để thực hiện một hành động bị trì hoãn.
launch(UI){
delay(300)
scrollView.fullScroll(View.FOCUS_DOWN)
}
Điều quan trọng là chỉ định HandlerContext của coroutine là UI nếu không hành động bị trì hoãn có thể không được gọi từ luồng UI.
Một lý do scroll.fullScroll(View.FOCUS_DOWN)
có thể giải thích tại sao có thể không hoạt động ngay cả khi được bao bọc .post()
là chế độ xem không được đặt ra. Trong trường hợp này, View.doOnLayout () có thể là một lựa chọn tốt hơn:
scroll.doOnLayout(){
scroll.fullScroll(View.FOCUS_DOWN)
}
Hoặc, một cái gì đó chi tiết hơn cho những linh hồn dũng cảm: https://chris.banes.dev/2019/12/03/suspending-view/