我想要一个ScrollView从底部开始。任何方法吗?
当前回答
当视图尚未加载时,您不能滚动。你可以“稍后”用上面的post或sleep call来做这件事,但这不是很优雅。
最好计划滚动并在下一个onLayout()中执行。示例代码如下:
https://stackoverflow.com/a/10209457/1310343
其他回答
scroll.fullScroll(View.FOCUS_DOWN)将导致焦点的改变。当有多个可聚焦视图(例如两个EditText)时,这将带来一些奇怪的行为。这个问题还有另一种解答方法。
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);
这很有效。
芬兰湾的科特林扩展
fun ScrollView.scrollToBottom() {
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY+ height)
smoothScrollBy(0, delta)
}
实际上,我发现调用fullScroll两次是有效果的:
myScrollView.fullScroll(View.FOCUS_DOWN);
myScrollView.post(new Runnable() {
@Override
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});
这可能与在执行第一次(不成功的)滚动之后激活post()方法有关。我认为这种行为发生在任何之前的方法调用myScrollView之后,所以你可以尝试用其他任何可能与你相关的方法来替换第一个fullScroll()方法。
这里有一些滚动到底部的其他方法
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()
}
使用
如果你的滚动视图已经布局
my_scroll_view.scrollToBottom()
如果你的滚动视图没有完成布局(例如:你滚动到底部的活动onCreate方法…)
my_scroll_view.post {
my_scroll_view.scrollToBottom()
}
所有答案的组合对我来说很管用:
扩展函数PostDelayed
private fun ScrollView.postDelayed(
time: Long = 325, // ms
block: ScrollView.() -> Unit
) {
postDelayed({block()}, time)
}
扩展函数measureScrollHeight
fun ScrollView.measureScrollHeight(): Int {
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY+ height)
return delta
}
扩展函数滚动底部
fun ScrollView.scrollToBottom() {
postDelayed {
smoothScrollBy(0, measureScrollHeight())
}
}
注意,最小延迟应该至少325毫秒,否则滚动将会有bug(不是滚动到整个底部)。当前高度和底部之间的增量越大,延迟时间就应该越大。
为什么scroll.fullScroll(view . focus_down)即使包装在.post()中也不能工作的一个可能的原因是视图没有被布局。在这种情况下,View.doOnLayout()可能是一个更好的选择:
scroll.doOnLayout(){
scroll.fullScroll(View.FOCUS_DOWN)
}
或者,为勇敢的灵魂提供更详细的信息:https://chris.banes.dev/2019/12/03/suspending-views/
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件