Getting view coordinates relative to parent ScrollView

I used to have the following ScrollViewand layout. Its scrolling to the selected visible code works.

<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);
    }
}

Note. getHitRectwill return the coordinate one level to the parent. So the above code will work.

However, when it comes to a slightly complicated case. The above code no longer works.

<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>

In my code, if I come across Info View 1 - 3, I need to take into account LinearLayout 0 and LinearLayout 1 getHitRect. When it comes to Info View 4-6, I need to take into account LinearLayout 0 and LinearLayout 2 getHitRect.

Things look bulky. Is there any way for me to get the coordinate of the view relative to the very top ScrollView?

+5
1

. . . .

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
--------------------

getLocationInWindow

26 , . , , 26 = 146 - 120. , ActionBar StatusBar.

getLocationOnScreen

, getLocationInWindow

getLocalVisibleRect

, , . , . , y (485), y.

+9

All Articles