Я хотів би, щоб ScrollView починався повністю внизу. Якісь методи?
Я хотів би, щоб ScrollView починався повністю внизу. Якісь методи?
Відповіді:
scroll.fullScroll(View.FOCUS_DOWN)
також повинні працювати.
Покладіть це в scroll.Post(Runnable run)
Котлінський кодекс
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
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.postDelayed, це обов'язково спрацює
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
:)
Якщо представлення ще не завантажено, ви не можете прокручувати. Ви можете зробити це "пізніше" за допомогою посту чи дзвінка уві сні, як зазначено вище, але це не дуже елегантно.
Краще спланувати прокрутку і зробити це на наступному 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 отримав фокус. Однак прийнята відповідь змусить ЕТ також втратити фокус відразу (я припускаю 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();
}
}
});
Я фактично виявив, що виклик fullScroll двічі робить трюк:
myScrollView.fullScroll(View.FOCUS_DOWN);
myScrollView.post(new Runnable() {
@Override
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});
Це може бути пов'язане з активацією методу post () відразу після виконання першого (невдалого) прокрутки. Я думаю, що така поведінка виникає після будь-якого попереднього виклику методу на myScrollView, тому ви можете спробувати замінити перший метод fullScroll () будь-яким іншим, що може стосуватися вас.
Використовуючи ще один класний спосіб зробити це за допомогою процедур Котліна. Перевагою використання кореневої програми, на противагу обробнику, що працює з прогоном (post / postDelayed), є те, що воно не запускає дорогу нитку для виконання затримки.
launch(UI){
delay(300)
scrollView.fullScroll(View.FOCUS_DOWN)
}
Важливо вказати HandlerContext coroutine як інтерфейс користувача, інакше затримка дії не може бути викликана з потоку інтерфейсу користувача.
Однією з можливих причин, чому scroll.fullScroll(View.FOCUS_DOWN)
може не працювати навіть загорнутий, .post()
є те, що погляд не викладений. У цьому випадку View.doOnLayout () може бути кращим варіантом:
scroll.doOnLayout(){
scroll.fullScroll(View.FOCUS_DOWN)
}
Або щось більш досконале для сміливих душ: https://chris.banes.dev/2019/12/03/suspending-views/