Ich möchte, dass eine ScrollView ganz unten beginnt. Irgendwelche Methoden?
Ich möchte, dass eine ScrollView ganz unten beginnt. Irgendwelche Methoden?
Antworten:
scroll.fullScroll(View.FOCUS_DOWN)
sollte auch funktionieren.
Setzen Sie dies in ein scroll.Post(Runnable run)
Kotlin Code
scrollView.post {
scrollView.fullScroll(View.FOCUS_DOWN)
}
Sie sollten den Code in der scroll.post wie folgt ausführen:
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
scroll.scrollTo(0, scroll.getHeight());
um nach unten zu springen, oder scroll.smoothScrollTo(0, scroll.getHeight());
für eine glattere Schriftrolle
scrollView.post { scrollView.fullScroll(View.FOCUS_DOWN) }
scroll.fullScroll(View.FOCUS_DOWN)
wird zu einer Änderung des Fokus führen. Dies führt zu einem merkwürdigen Verhalten, wenn mehr als eine fokussierbare Ansicht vorhanden ist, z. B. zwei EditText. Es gibt einen anderen Weg für diese Frage.
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);
Das funktioniert gut.
Kotlin-Erweiterung
fun ScrollView.scrollToBottom() {
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY+ height)
smoothScrollBy(0, delta)
}
Manchmal funktioniert scrollView.post nicht
scrollView.post(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
ABER wenn Sie scrollView.postDelayed verwenden, wird es definitiv funktionieren
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
},1000);
Was für mich am besten funktioniert hat, ist
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());
}
});
Ich erhöhe, um perfekt zu arbeiten.
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();
}
Hinweis
Diese Antwort ist eine Problemumgehung für wirklich alte Versionen von Android. Heute postDelayed
hat der nicht mehr diesen Bug und du solltest ihn benutzen.
postDelayed
:)
Ich habe das erfolgreich versucht.
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.smoothScrollTo(0, scrollView.getHeight());
}
}, 1000);
Wenn die Ansicht noch nicht geladen ist, können Sie nicht scrollen. Sie können es "später" mit einem Post- oder Schlafanruf wie oben tun, aber dies ist nicht sehr elegant.
Es ist besser, die Schriftrolle zu planen und beim nächsten onLayout () auszuführen. Beispielcode hier:
Eine zu berücksichtigende Sache ist, was NICHT eingestellt werden soll. Stellen Sie sicher, dass für Ihre untergeordneten Steuerelemente, insbesondere für EditText-Steuerelemente, die RequestFocus-Eigenschaft nicht festgelegt ist. Dies ist möglicherweise eine der zuletzt interpretierten Eigenschaften des Layouts und überschreibt die Schwerkrafteinstellungen der übergeordneten Elemente (Layout oder ScrollView).
Hier sind einige andere Möglichkeiten, um nach unten zu scrollen
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()
}
Verwenden von
Wenn Sie die Bildlaufansicht bereits angelegt haben
my_scroll_view.scrollToBottom()
Wenn Ihre Bildlaufansicht nicht fertig angelegt ist (z. B.: Sie scrollen in der Aktivitätsmethode nach unten onCreate
...)
my_scroll_view.post {
my_scroll_view.scrollToBottom()
}
Nicht genau die Antwort auf die Frage, aber ich musste nach unten scrollen, sobald ein EditText den Fokus bekam. Die akzeptierte Antwort würde jedoch dazu führen, dass der ET auch sofort den Fokus verliert (auf die ScrollView, nehme ich an).
Meine Problemumgehung war folgende:
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();
}
}
});
Ich habe tatsächlich festgestellt, dass das zweimalige Aufrufen von fullScroll den Trick macht:
myScrollView.fullScroll(View.FOCUS_DOWN);
myScrollView.post(new Runnable() {
@Override
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});
Dies hat möglicherweise etwas mit der Aktivierung der post () -Methode direkt nach dem ersten (nicht erfolgreichen) Bildlauf zu tun. Ich denke, dieses Verhalten tritt nach jedem vorherigen Methodenaufruf in myScrollView auf, sodass Sie versuchen können, die erste fullScroll () -Methode durch etwas anderes zu ersetzen, das für Sie relevant sein könnte.
Es gibt eine andere coole Möglichkeit, dies mit Kotlin-Coroutinen zu tun. Der Vorteil der Verwendung einer Coroutine im Gegensatz zu einem Handler mit einer ausführbaren Datei (post / postDelayed) besteht darin, dass kein teurer Thread zum Ausführen einer verzögerten Aktion gestartet wird.
launch(UI){
delay(300)
scrollView.fullScroll(View.FOCUS_DOWN)
}
Es ist wichtig, den HandlerContext der Coroutine als Benutzeroberfläche anzugeben, da sonst die verzögerte Aktion möglicherweise nicht vom UI-Thread aufgerufen wird.
Ein möglicher Grund, warum scroll.fullScroll(View.FOCUS_DOWN)
möglicherweise nicht einmal eingepackt funktioniert, .post()
ist, dass die Ansicht nicht angelegt ist. In diesem Fall könnte View.doOnLayout () eine bessere Option sein:
scroll.doOnLayout(){
scroll.fullScroll(View.FOCUS_DOWN)
}
Oder etwas Ausführlicheres für die tapferen Seelen: https://chris.banes.dev/2019/12/03/suspending-views/