Same issue as ScrollView .scrollTo not working? Saving ScrollView position on rotation
I dynamically add items to scrollView in onCreate. I try the following after all items were added:
// no effect
ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);
// no effect
ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);
mainScroll.post(new Runnable() {
public void run(){
ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);
mainScroll.scrollTo(0, 0);
}
});
// works like a charm
ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);
mainScroll.postDelayed(new Runnable() {
public void run(){
ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);
mainScroll.scrollTo(0, 0);
}
}, 30);
I conclude that there is some event like 'DOM-ready'? Are there any callbacks?
You don't need to extend the ScrollView and create your own as per the answer provided by David Daudelin for the this question .
Get the ViewTreeObserver
of the ScrollView
and add an OnGlobalLayoutListener
to the ViewTreeObserver
. Then call the ScrollView.scrollTo(x,y)
method from the onGlobalLayout()
method of the OnGlobalLayoutListener
. Code:
ScrollView mainScroll = (ScrollView) findViewById(R.id.average_scroll_mainScroll);
ViewTreeObserver vto = scrollView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
mainScroll.scrollTo(0, 0);
}
});
This works for me, replace scrollView.scrollTo()
to
scrollView.post(new Runnable() {
@Override
public void run() {
scrollView.scrollTo(0, ScrollViewYPosition);//0 is x position
}
});
I was helped by Vasily Kabunov 's answer in
ScrollView .scrollTo not working? Saving ScrollView position on rotation
When you do some changes to a ScrollView, it takes a while for it to replicate the layout changes to the display list and notify the ScrollView that it is, indeed, allowed to scroll to a position.
I've managed to get it working by extending ScrollView
with a ScrollView of my own, and adding a method that adds the OnGlobalLayoutListener
(as suggested by MH) as needed and scrolls there later. It's a bit more automated than applying it to every case you need it (but then you need to use the new ScrollView
). Anyway, this is the relevant code:
public class ZScrollView extends ScrollView {
// Properties
private int desiredScrollX = -1;
private int desiredScrollY = -1;
private OnGlobalLayoutListener gol;
// ================================================================================================================
// CONSTRUCTOR ----------------------------------------------------------------------------------------------------
public ZScrollView(Context __context) {
super(__context);
}
public ZScrollView(Context __context, AttributeSet __attrs) {
super(__context, __attrs);
}
public ZScrollView(Context __context, AttributeSet __attrs, int __defStyle) {
super(__context, __attrs, __defStyle);
}
// ================================================================================================================
// PUBLIC INTERFACE -----------------------------------------------------------------------------------------------
public void scrollToWithGuarantees(int __x, int __y) {
// REALLY Scrolls to a position
// When adding items to a scrollView, you can't immediately scroll to it - it takes a while
// for the new addition to cycle back and update the scrollView's max scroll... so we have
// to wait and re-set as necessary
scrollTo(__x, __y);
desiredScrollX = -1;
desiredScrollY = -1;
if (getScrollX() != __x || getScrollY() != __y) {
// Didn't scroll properly: will create an event to try scrolling again later
if (getScrollX() != __x) desiredScrollX = __x;
if (getScrollY() != __y) desiredScrollY = __y;
if (gol == null) {
gol = new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int nx = desiredScrollX == -1 ? getScrollX() : desiredScrollX;
int ny = desiredScrollY == -1 ? getScrollY() : desiredScrollY;
desiredScrollX = -1;
desiredScrollY = -1;
scrollTo(nx, ny);
}
};
getViewTreeObserver().addOnGlobalLayoutListener(gol);
}
}
}
}
Very useful for me since I wanted to scroll to a given View inside a ScrollView right after having added it.
Try this it works: (kotlin)
myScrollView.post(Runnable { myScrollView.scrollTo(0, scrollValue) })
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.