以前,我有以下ScrollView
和布局。它的滚动直到选定的视图可见代码有效。
<ScrollView>
<LinearLayout>
<Info View 1/>
<Info View 2/>
<Info View 3/>
</LinearLayout>
</ScrollView>
private void initScrollView() {
if (this.selectedInfoView == null) {
// Nothing to scroll.
return;
}
ScrollView scrollView = (ScrollView)this.getView().findViewById(R.id.scrollView);
Rect rect = new Rect();
Rect scrollViewRect = new Rect();
selectedInfoView.getHitRect(rect);
scrollView.getDrawingRect(scrollViewRect);
int dy = rect.bottom - scrollViewRect.bottom;
if (dy > 0) {
scrollView.scrollBy(0, dy);
}
}
注意,getHitRect
会将坐标方面返回到父级的一级。因此,上面的代码将起作用。
然而,当涉及到稍微复杂的情况时。上面的代码不再有效。
<ScrollView>
<LinearLayout 0>
<TextView/>
<LinearLayout 1>
<Info View 1/>
<Info View 2/>
<Info View 3/>
</LinearLayout>
<TextView/>
<LinearLayout 2>
<Info View 4/>
<Info View 5/>
<Info View 6/>
</LinearLayout>
</LinearLayout>
</ScrollView>
在我的代码中,如果遇到 Info View 1 - 3 ,我需要考虑 LinearLayout 0 和 LinearLayout 1 getHitRect
。当来到 Info View 4 - 6 时,我需要考虑 LinearLayout 0 和 LinearLayout 2 的getHitRect
。< / p>
事情看起来很麻烦。有没有办法让我获得视图的坐标,相对于最顶层的ScrollView
?
答案 0 :(得分:9)
这是目前可行的代码。很麻烦。但它在这一刻起作用。我有一些意见。
private void initScrollView() {
if (this.selectedInfoView == null) {
// Nothing to scroll.
return;
}
ScrollView scrollView = (ScrollView)this.getView().findViewById(R.id.scrollView);
LinearLayout linearLayout = null;
if (this.selectedInfo instanceof Info0) {
linearLayout = (LinearLayout)this.getView().findViewById(R.id.linearLayout0);
} else {
assert(this.selectedInfo instanceof Info1);
linearLayout = (LinearLayout)this.getView().findViewById(R.id.linearLayout1);
}
Rect rect = new Rect();
Rect linearLayoutRect = new Rect();
Rect scrollViewRect = new Rect();
selectedInfoView.getHitRect(rect);
linearLayout.getHitRect(linearLayoutRect);
scrollView.getDrawingRect(scrollViewRect);
// Get coordinate relative to linear layout. See the note below.
int correct_expected_bottom_y = linearLayoutRect.top + rect.bottom;
int dy = correct_expected_bottom_y - scrollViewRect.bottom;
if (dy > 0) {
scrollView.scrollBy(0, dy);
}
}
我还使用getLocationInWindow
,getLocationOnScreen
和getLocalVisibleRect
进行了测试。他们都没有傻瓜证明。
(x,y - 宽度,高度)
--------------------
| | (?, 120) <-- correct expected bottom y
| | (0, 146) <-- from getLocationInWindow/ getLocationOnScreen
| | (0, 0 - 360, 72) <-- from getLocalVisibleRect
--------------------
| | (?, 193) <-- correct expected bottom y
| | (0, 219) <-- from getLocationInWindow/ getLocationOnScreen
| | (0, 0 - 360, 72) <-- from getLocalVisibleRect
--------------------
| | (?, 266) <-- correct expected bottom y
| | (0, 292) <-- from getLocationInWindow/ getLocationOnScreen
| | (0, 0 - 360, 72) <-- from getLocalVisibleRect
--------------------
| | (?, 339) <-- correct expected bottom y
| | (0, 365) <-- from getLocationInWindow/ getLocationOnScreen
| | (0, 0 - 360, 72) <-- from getLocalVisibleRect
--------------------
| | (?, 485) <-- correct expected bottom y
| [not visible] | (0, 511) <-- from getLocationInWindow/ getLocationOnScreen
| | (0, 413 - 360, 485) <-- from getLocalVisibleRect
--------------------
它总是比预期值多26个像素。例如,取第一行, 26 = 146 - 120 。我认为这可能是由ActionBar
或StatusBar
身高。
与getLocationInWindow
当行在屏幕上完全不可见时,它只获得与预期值相同的值。不知道为什么。查看最后一行,它与预期的底部y具有相同的底部y值(485)。
答案 1 :(得分:0)
不确定此功能是否在2013年可用,您现在可以像这样进行操作:
val bounds = Rect()
childView.getDrawingRect(bounds) // now bounds has the visible drawing coordinates of the view
parentViewGroup.offsetDescendantRectToMyCoords(childView, bounds) // now bounds has the view's coordinates according to the parentViewGroup
parentViewGroup
是层次结构中任何级别的childView
的父级。