Saya ingin ScrollView memulai dari jauh ke bawah. Ada metode?
Saya ingin ScrollView memulai dari jauh ke bawah. Ada metode?
Jawaban:
scroll.fullScroll(View.FOCUS_DOWN)
juga harus bekerja.
Masukkan ini ke dalam a scroll.Post(Runnable run)
Kode Kotlin
scrollView.post {
scrollView.fullScroll(View.FOCUS_DOWN)
}
Anda harus menjalankan kode di dalam scroll.post seperti ini:
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
scroll.scrollTo(0, scroll.getHeight());
untuk melompat ke bawah, atau scroll.smoothScrollTo(0, scroll.getHeight());
untuk scroll yang lebih halus
scrollView.post { scrollView.fullScroll(View.FOCUS_DOWN) }
scroll.fullScroll(View.FOCUS_DOWN)
akan mengarah pada perubahan fokus. Itu akan membawa beberapa perilaku aneh ketika ada lebih dari satu tampilan yang bisa fokus, misalnya dua EditText. Ada cara lain untuk pertanyaan ini.
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);
Ini bekerja dengan baik.
Perpanjangan Kotlin
fun ScrollView.scrollToBottom() {
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY+ height)
smoothScrollBy(0, delta)
}
Terkadang scrollView.post tidak berfungsi
scrollView.post(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
TETAPI jika Anda menggunakan scrollView.postDelayed, itu pasti akan berfungsi
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
},1000);
Apa yang paling berhasil bagi saya adalah
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());
}
});
Saya menambahkan untuk bekerja dengan sempurna.
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();
}
Catatan
Jawaban ini merupakan solusi untuk Android versi lama. Hari postDelayed
ini tidak ada lagi bug dan Anda harus menggunakannya.
postDelayed
:)
Saya mencoba yang berhasil.
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.smoothScrollTo(0, scrollView.getHeight());
}
}, 1000);
Saat tampilan belum dimuat, Anda tidak dapat menggulir. Anda dapat melakukannya 'nanti' dengan postingan atau panggilan tidur seperti di atas, tetapi ini tidak terlalu elegan.
Lebih baik untuk merencanakan gulir dan melakukannya pada onLayout berikutnya (). Contoh kode di sini:
Satu hal yang perlu dipertimbangkan adalah apa yang TIDAK diatur. Pastikan kontrol anak Anda, terutama kontrol EditText, tidak memiliki properti RequestFocus yang ditetapkan. Ini mungkin salah satu properti yang ditafsirkan terakhir pada tata letak dan itu akan menimpa pengaturan gravitasi pada orang tuanya (tata letak atau ScrollView).
Berikut ini beberapa cara lain untuk menggulir ke bawah
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()
}
Menggunakan
Jika Anda scrollview sudah ditata
my_scroll_view.scrollToBottom()
Jika scrollview Anda belum selesai ditata (mis: Anda gulir ke bawah dalam onCreate
metode Aktivitas ...)
my_scroll_view.post {
my_scroll_view.scrollToBottom()
}
Bukan jawaban untuk pertanyaan itu, tetapi saya perlu menggulir ke bawah segera setelah EditText mendapatkan fokus. Namun jawaban yang diterima akan membuat ET juga kehilangan fokus segera (menurut saya ScrollView).
Solusi saya adalah sebagai berikut:
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();
}
}
});
Saya benar-benar menemukan bahwa memanggil fullScroll dua kali berhasil:
myScrollView.fullScroll(View.FOCUS_DOWN);
myScrollView.post(new Runnable() {
@Override
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});
Mungkin ada hubungannya dengan aktivasi metode post () setelah melakukan scroll pertama (tidak berhasil). Saya pikir perilaku ini terjadi setelah pemanggilan metode sebelumnya pada myScrollView, jadi Anda dapat mencoba mengganti metode fullScroll () pertama dengan hal lain yang mungkin relevan bagi Anda.
Menggunakan ada cara keren lain untuk melakukan ini dengan coroutine Kotlin. Keuntungan menggunakan coroutine yang bertentangan dengan Handler dengan runnable (post / postDelayed) adalah tidak menjalankan utas mahal untuk melakukan tindakan yang tertunda.
launch(UI){
delay(300)
scrollView.fullScroll(View.FOCUS_DOWN)
}
Penting untuk menentukan HandlerContext coroutine sebagai UI jika tidak, tindakan yang tertunda mungkin tidak dipanggil dari utas UI.
Salah satu kemungkinan alasan mengapa scroll.fullScroll(View.FOCUS_DOWN)
mungkin tidak berfungsi bahkan dibungkus .post()
adalah karena tampilan tidak ditata. Dalam hal ini, View.doOnLayout () bisa menjadi opsi yang lebih baik:
scroll.doOnLayout(){
scroll.fullScroll(View.FOCUS_DOWN)
}
Atau, sesuatu yang lebih rumit untuk jiwa-jiwa pemberani: https://chris.banes.dev/2019/12/03/suspending-views/