ฉันต้องการให้ ScrollView เริ่มต้นจนสุดทาง วิธีใด?
ฉันต้องการให้ ScrollView เริ่มต้นจนสุดทาง วิธีใด?
คำตอบ:
scroll.fullScroll(View.FOCUS_DOWN)
ควรทำงานเช่นกัน
ใส่สิ่งนี้ใน scroll.Post(Runnable run)
รหัส Kotlin
scrollView.post {
scrollView.fullScroll(View.FOCUS_DOWN)
}
คุณควรเรียกใช้รหัสภายใน scroll.post ดังนี้:
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
scroll.scrollTo(0, scroll.getHeight());
เพื่อข้ามไปยังด้านล่างหรือscroll.smoothScrollTo(0, scroll.getHeight());
เพื่อการเลื่อนที่นุ่มนวลขึ้น
scrollView.post { scrollView.fullScroll(View.FOCUS_DOWN) }
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);
มันใช้งานได้ดี
Kotlin Extension
fun ScrollView.scrollToBottom() {
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY+ height)
smoothScrollBy(0, delta)
}
บางครั้ง scrollView.post ไม่ทำงาน
scrollView.post(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
แต่ถ้าคุณใช้ scrollView.post ล่าช้ามันจะใช้งานได้อย่างแน่นอน
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
},1000);
สิ่งที่ดีที่สุดสำหรับฉันคือ
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());
}
});
ฉันเพิ่มขึ้นเพื่อทำงานอย่างสมบูรณ์
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
ไม่มีข้อผิดพลาดนั้นอีกแล้วและคุณควรใช้มัน
postDelayed
:)
ฉันพยายามประสบความสำเร็จ
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.smoothScrollTo(0, scrollView.getHeight());
}
}, 1000);
เมื่อยังไม่ได้โหลดมุมมองคุณจะไม่สามารถเลื่อนได้ คุณสามารถทำได้ด้วยการ 'โพสต์' หรือโพสต์การโทรตามที่กล่าวไว้ข้างต้น
มันจะดีกว่าที่จะวางแผนการเลื่อนและทำใน onLayout () ต่อไป รหัสตัวอย่างที่นี่:
สิ่งหนึ่งที่ควรพิจารณาคือสิ่งที่ไม่ควรตั้งค่า ทำให้แน่ใจว่าคอนโทรลย่อยของคุณโดยเฉพาะคอนโทรล EditText ไม่มีชุดคุณสมบัติ RequestFocus นี่อาจเป็นหนึ่งในคุณสมบัติที่ตีความล่าสุดในโครงร่างและมันจะแทนที่การตั้งค่าแรงโน้มถ่วงบนพาเรนต์ (รูปแบบหรือ ScrollView)
นี่คือวิธีอื่นในการเลื่อนไปด้านล่าง
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()
}
ไม่ใช่คำตอบของคำถาม แต่ฉันต้องเลื่อนลงทันทีที่ 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();
}
}
});
ฉันจริง ๆ แล้วพบว่าการโทรแบบเต็มสเกล
myScrollView.fullScroll(View.FOCUS_DOWN);
myScrollView.post(new Runnable() {
@Override
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});
อาจมีบางอย่างเกี่ยวข้องกับการเปิดใช้งานวิธีการโพสต์ () หลังจากดำเนินการเลื่อนครั้งแรก (ไม่สำเร็จ) ฉันคิดว่าพฤติกรรมนี้เกิดขึ้นหลังจากการเรียกใช้เมธอดก่อนหน้านี้บน myScrollView ดังนั้นคุณสามารถลองเปลี่ยนเมธอด fullScroll () เป็นครั้งแรกด้วยสิ่งอื่นที่อาจเกี่ยวข้องกับคุณ
การใช้มีวิธีที่ยอดเยี่ยมอีกวิธีหนึ่งในการทำเช่นนี้กับ Kotlin coroutines ข้อดีของการใช้ coroutine ซึ่งตรงกันข้ามกับตัวจัดการที่มี runnable (post / postDelayed) คือมันไม่ได้ทำให้เธรดมีราคาแพงขึ้นเพื่อดำเนินการล่าช้า
launch(UI){
delay(300)
scrollView.fullScroll(View.FOCUS_DOWN)
}
สิ่งสำคัญคือต้องระบุ HandlerContext ของ coroutine เป็น UI มิฉะนั้นการดำเนินการล่าช้าอาจไม่ถูกเรียกจากเธรด UI
ในกรณีเหล่านั้นใช้เพียงscroll.scrollTo (0, sc.getBottom ())ไม่ทำงานใช้มันโดยใช้ scroll.post
ตัวอย่าง:
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
เหตุผลหนึ่งที่เป็นไปได้ว่าทำไมscroll.fullScroll(View.FOCUS_DOWN)
อาจไม่ทำงานแม้จะอยู่ใน.post()
นั้นคือมุมมองไม่ได้ถูกจัดวางไว้ ในกรณีนี้View.doOnLayout ()อาจเป็นตัวเลือกที่ดีกว่า:
scroll.doOnLayout(){
scroll.fullScroll(View.FOCUS_DOWN)
}
หรือมีบางสิ่งที่อธิบายเพิ่มเติมเกี่ยวกับวิญญาณผู้กล้าหาญ: https://chris.banes.dev/2019/12/03/suspending-views/