我有一个很长的带有滚动视图的活动。它是一个包含用户必须填写的各种字段的表单。我在表单的中间有一个复选框,当用户选中它时,我想滚动到视图的特定部分。是否有办法以编程方式滚动到EditText对象(或任何其他视图对象)?
此外,我知道这是可能的使用X和Y坐标,但我想避免这样做,因为形式可能会从用户到用户的变化。
我有一个很长的带有滚动视图的活动。它是一个包含用户必须填写的各种字段的表单。我在表单的中间有一个复选框,当用户选中它时,我想滚动到视图的特定部分。是否有办法以编程方式滚动到EditText对象(或任何其他视图对象)?
此外,我知道这是可能的使用X和Y坐标,但我想避免这样做,因为形式可能会从用户到用户的变化。
当前回答
这对我来说很管用:
targetView.getParent().requestChildFocus(targetView,targetView);
RequestChildFocus(查看子视图,查看焦点)
child -这个ViewParent的想要聚焦的子对象。该视图将包含聚焦视图。它并不一定是真正有焦点的观点。
focused -实际上具有焦点的child的后代视图
其他回答
将postDelayed添加到视图中,这样getTop()就不会返回0。
binding.scrollViewLogin.postDelayed({
val scrollTo = binding.textInputLayoutFirstName.top
binding.scrollViewLogin.isSmoothScrollingEnabled = true
binding.scrollViewLogin.smoothScrollTo(0, scrollTo)
}, 400
)
还要确保视图是scrollView的直接子视图,否则你会得到getTop()为零。示例:嵌入在TextInputLayout中的edittext的getTop()将返回0。在这种情况下,我们需要计算TextInputLayout的getTop()它是ScrollView的直接子。
<ScrollView>
<TextInputLayout>
<EditText/>
</TextInputLayout>
</ScrollView>
我基于WarrenFaith的答案做了一个小工具方法,这段代码也考虑了视图是否已经在滚动视图中可见,不需要滚动。
public static void scrollToView(final ScrollView scrollView, final View view) {
// View needs a focus
view.requestFocus();
// Determine if scroll needs to happen
final Rect scrollBounds = new Rect();
scrollView.getHitRect(scrollBounds);
if (!view.getLocalVisibleRect(scrollBounds)) {
new Handler().post(new Runnable() {
@Override
public void run() {
scrollView.smoothScrollTo(0, view.getBottom());
}
});
}
}
我的解决方案是:
int[] spinnerLocation = {0,0};
spinner.getLocationOnScreen(spinnerLocation);
int[] scrollLocation = {0, 0};
scrollView.getLocationInWindow(scrollLocation);
int y = scrollView.getScrollY();
scrollView.smoothScrollTo(0, y + spinnerLocation[1] - scrollLocation[1]);
你可以像这样使用ObjectAnimator:
ObjectAnimator.ofInt(yourScrollView, "scrollY", yourView.getTop()).setDuration(1500).start();
参考资料:https://stackoverflow.com/a/6438240/2624806
接下来的工作要好得多。
mObservableScrollView.post(new Runnable() {
public void run() {
mObservableScrollView.fullScroll([View_FOCUS][1]);
}
});