Ik wil dat een ScrollView helemaal onderaan begint. Elke methode?
Antwoord 1, autoriteit 100%
je moet de code in de scroll.post als volgt uitvoeren:
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
Antwoord 2, autoriteit 91%
scroll.fullScroll(View.FOCUS_DOWN)
zou ook moeten werken.
Zet dit in een scroll.Post(Runnable run)
Kotlin-code
scrollView.post {
scrollView.fullScroll(View.FOCUS_DOWN)
}
Antwoord 3, autoriteit 33%
scroll.fullScroll(View.FOCUS_DOWN)
zal leiden tot de verandering van focus. Dat zal vreemd gedrag met zich meebrengen als er meer dan één focusbare weergaven zijn, bijvoorbeeld twee EditText. Er is een andere manier voor deze vraag.
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);
Dit werkt goed.
Kotlin-extensie
fun ScrollView.scrollToBottom() {
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY+ height)
smoothScrollBy(0, delta)
}
Antwoord 4, autoriteit 16%
Soms werkt scrollView.post niet
scrollView.post(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
MAAR als je scrollView.postDelayed gebruikt, zal het zeker werken
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
},1000);
Antwoord 5, autoriteit 11%
Wat voor mij het beste werkte, is
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());
}
});
Antwoord 6, autoriteit 8%
Ik verhoog om perfect te werken.
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();
}
Opmerking
Dit antwoord is een tijdelijke oplossing voor echt oude versies van Android. Vandaag de postDelayed
heeft die bug niet meer en je zou hem moeten gebruiken.
Antwoord 7
ik heb dat met succes geprobeerd.
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.smoothScrollTo(0, scrollView.getHeight());
}
}, 1000);
Antwoord 8
Als de weergave nog niet is geladen, kunt u niet scrollen. Je kunt het ‘later’ doen met een post- of slaapoproep zoals hierboven, maar dit is niet erg elegant.
Het is beter om de scroll te plannen en dit op de volgende onLayout() te doen. Voorbeeldcode hier:
https://stackoverflow.com/a/10209457/1310343
Antwoord 9
Eén ding om te overwegen is wat je NIET moet instellen. Zorg ervoor dat uw onderliggende besturingselementen, met name EditText-besturingselementen, niet de eigenschap RequestFocus hebben. Dit kan een van de laatst geïnterpreteerde eigenschappen in de lay-out zijn en het zal de zwaartekrachtinstellingen op zijn bovenliggende (de lay-out of ScrollView) overschrijven.
Antwoord 10
Hier zijn enkele andere manieren om naar beneden te 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()
}
Gebruik
Als je scrollview al opgemaakt hebt
my_scroll_view.scrollToBottom()
Als uw scrollview niet volledig is ingedeeld (bijv.: u scrolt naar beneden in de Activity onCreate
-methode …)
my_scroll_view.post {
my_scroll_view.scrollToBottom()
}
Antwoord 11
Niet bepaald het antwoord op de vraag, maar ik moest naar beneden scrollen zodra een EditText de focus kreeg. Het geaccepteerde antwoord zou er echter voor zorgen dat de ET ook meteen de focus verliest (naar de ScrollView neem ik aan).
Mijn oplossing was de volgende:
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();
}
}
});
Antwoord 12
Ik ontdekte dat het twee keer aanroepen van fullScroll voldoende is:
myScrollView.fullScroll(View.FOCUS_DOWN);
myScrollView.post(new Runnable() {
@Override
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});
Het kan iets te maken hebben met de activering van de post()-methode direct na het uitvoeren van de eerste (niet-geslaagde) scroll. Ik denk dat dit gedrag optreedt na een eerdere methodeaanroep op myScrollView, dus je kunt proberen de eerste fullScroll()-methode te vervangen door iets anders dat voor jou relevant kan zijn.
Antwoord 13
Er is nog een andere coole manier om dit te doen met Kotlin-coroutines. Het voordeel van het gebruik van een coroutine in tegenstelling tot een Handler met een uitvoerbaar (post/postDelayed) is dat het geen dure thread start om een vertraagde actie uit te voeren.
launch(UI){
delay(300)
scrollView.fullScroll(View.FOCUS_DOWN)
}
Het is belangrijk om de HandlerContext van de coroutine als UI op te geven, anders wordt de vertraagde actie mogelijk niet aangeroepen vanuit de UI-thread.
Antwoord 14
In dat geval werkt het gebruik van scroll.scrollTo(0, sc.getBottom())niet, gebruik het met scroll.post
Voorbeeld:
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
Antwoord 15
Een mogelijke reden waarom scroll.fullScroll(View.FOCUS_DOWN)
misschien niet werkt, zelfs niet verpakt in .post()
, is dat de weergave niet is ingedeeld. In dit geval View.doOnLayout()zou een betere optie kunnen zijn:
scroll.doOnLayout(){
scroll.fullScroll(View.FOCUS_DOWN)
}
Of iets uitgebreider voor de dappere zielen: https:// chris.banes.dev/2019/12/03/suspending-views/
Antwoord 16
Dit werkt direct. Zonder vertraging.
// wait for the scroll view to be laid out
scrollView.post(new Runnable() {
public void run() {
// then wait for the child of the scroll view (normally a LinearLayout) to be laid out
scrollView.getChildAt(0).post(new Runnable() {
public void run() {
// finally scroll without animation
scrollView.scrollTo(0, scrollView.getBottom());
}
}
}
}
Antwoord 17
Als uw minimale SDK 23 of hoger is, kunt u dit gebruiken:
View childView = findViewById(R.id.your_view_id_in_the_scroll_view)
if(childView != null){
scrollview.post(() -> scrollview.scrollToDescendant(childView));
}
Antwoord 18
Een combinatie van alle antwoorden deed de truc voor mij:
Uitbreidingsfunctie PostDelayed
private fun ScrollView.postDelayed(
time: Long = 325, // ms
block: ScrollView.() -> Unit
) {
postDelayed({block()}, time)
}
Uitbreiding Functie maatregelScrollHeight
fun ScrollView.measureScrollHeight(): Int {
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY+ height)
return delta
}
Uitbreidingsfunctie ScrolltoBottom
fun ScrollView.scrollToBottom() {
postDelayed {
smoothScrollBy(0, measureScrollHeight())
}
}
Houd er rekening mee dat de minimale vertraging minimaal 325 ms moet zijn, anders zal het scrollen buggy zijn (niet helemaal naar beneden scrollen). Hoe groter uw delta tussen de huidige hoogte en de bodem is, hoe groter de vertragingstijd zou moeten zijn.
Antwoord 19
Sommige mensen hier zeiden dat scrollView.post niet werkte.
Als je scrollView.postDelayed niet wilt gebruiken, is een andere optie om een listener te gebruiken. Dit is wat ik deed in een andere use-case:
ViewTreeObserver.OnPreDrawListener viewVisibilityChanged = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (my_view.getVisibility() == View.VISIBLE) {
scroll_view.smoothScrollTo(0, scroll_view.getHeight());
}
return true;
}
};
Je kunt het op deze manier aan je weergave toevoegen:
my_view.getViewTreeObserver().addOnPreDrawListener(viewVisibilityChanged);