ScrollView に何らかの変更を加えると、レイアウトの変更が表示リストに複製され、ScrollView に特定の位置までスクロールできることを通知するまでに時間がかかります。
独自の ScrollView で拡張し、必要に応じて (MH の提案に従って) を追加し、後でスクロールScrollView
するメソッドを追加することで、なんとか機能させることができました。OnGlobalLayoutListener
必要なすべてのケースに適用するよりも少し自動化されています (ただし、 new を使用する必要がありますScrollView
)。とにかく、これは関連するコードです:
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);
}
}
}
}
追加した直後に ScrollView 内の特定の View にスクロールしたかったので、私にとって非常に便利です。