Ответ 1
scroll.fullScroll(View.FOCUS_DOWN)
также должен работать.
Поместите это в scroll.Post(Runnable run)
Код Котлина
scrollView.post {
scrollView.fullScroll(View.FOCUS_DOWN)
}
Мне хотелось бы, чтобы 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.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
больше не имеет этой ошибки, и вы должны использовать ее.
Когда представление еще не загружено, вы не можете прокручивать. Вы можете сделать это "позже" с вызовом почты или сна, как указано выше, но это не очень элегантно.
Лучше планировать свиток и делать это на следующем onLayout(). Пример кода здесь:
Одна вещь, которую следует учитывать, - это то, что НЕ установить. Убедитесь, что ваши дочерние элементы управления, особенно элементы управления EditText, не имеют свойства свойства RequestFocus. Это может быть одно из последних интерпретируемых свойств на макете, и оно будет отменять настройки гравитации у его родителей (макет или ScrollView).
Не совсем ответ на вопрос, но мне нужно было прокрутить вниз, как только 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() на что-либо еще, что может быть связано с вами.
Вот еще несколько способов прокрутки вниз
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()
Если ваше прокручиваемое представление не закончено (например: вы прокрутите вниз в методе Activity onCreate
...)
my_scroll_view.post {
my_scroll_view.scrollToBottom()
}
Использование есть еще один крутой способ сделать это с сопрограммами Kotlin. Преимущество использования сопрограммы по сравнению с обработчиком с работоспособным (post/postDelayed) состоит в том, что он не запускает дорогой поток для выполнения отложенного действия.
launch(UI){
delay(300)
scrollView.fullScroll(View.FOCUS_DOWN)
}
Важно указать сопрограмму HandlerContext в качестве пользовательского интерфейса, в противном случае отложенное действие не может быть вызвано из потока пользовательского интерфейса.
В этих случаях использовалось только scroll.scrollTo(0, sc.getBottom()) не работают, используйте его с помощью scroll.post
Пример:
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});