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