For me, all the previous answers did not work:
Even after calling scrollPane.layout()
multiple times, the scroll pane still had an areaHeight
(scrollHeight
) of -2, 0, or sth else. Only later during subsequent layout calls the correct height would be set, causing an animation where the content would slide in from the top.
The only option that fixed it for my use case (scrolling to bottom initially after adding all the initial content) was to override the ScrollPane.layout()
and scroll to bottom after each layout change:
open class BottomScrollingScrollPane(actor: Actor?, skin: Skin, style: String): ScrollPane(actor, skin, style) {
override fun layout() {
super.layout()
scrollTo(0f, 0f, 0f, 0f)
updateVisualScroll()
}
}
... and optionally, if you use libktx:
@Scene2dDsl
@OptIn(ExperimentalContracts::class)
inline fun <S> KWidget<S>.bottomScrollingScrollPane(
style: String = defaultStyle,
skin: Skin = Scene2DSkin.defaultSkin,
init: KBottomScrollingScrollPane.(S) -> Unit = {}
): KBottomScrollingScrollPane {
contract { callsInPlace(init, InvocationKind.EXACTLY_ONCE) }
return actor(KBottomScrollingScrollPane(skin, style), init)
}
class KBottomScrollingScrollPane(skin: Skin, style: String) : BottomScrollingScrollPane(null, skin, style), KGroup {
override fun addActor(actor: Actor?) {
this.actor == null || throw IllegalStateException("ScrollPane may store only a single child.")
this.actor = actor
}
}
One side effect is scrolling down again after each layout change, resize etc., but that's fine for me as the layout is very short-lived anyway.