3
votes

Inside a RelativeLayout; I have a TableLayout in a ScrollView, and a horizontal LinearLayout. My view is working fine: as the table scrolls in the background, the LinearLayout is static in the foreground. What I now need, is to know exactly where the table and the LinearLayout are intersecting during scrolling.

Since the LinearLayout is static, I know where it is at all time, say y=50pixel. Supposing I have TextViews inside the TableLayout. So as the table scrolls, I want to know which TextView (i.e. tableRow) is intersecting/hidden by the LinearLayout.

2
It's also a good answer if all I get is whether a TableRow is above or below the line.Cote Mounyo
Can you post your layout file? And if possible, add the code where you inflate/initialize this view.Vikram

2 Answers

0
votes

Have you tried using View.getLocationOnScreen() on the table rows?

0
votes

I have a horizontal line at y-offset = 310 pixel. As I scroll my tableLayout, which is inside a ScrollView, I want to know which row of the table is intersecting my horizontal line.

You could use the View.getLocationInWindow() method. Initially you'd need to see which row intersects the line and then using a custom ScrollView, follow the scrolling:

// in the onCreate:
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(
            new OnGlobalLayoutListener() {

                @Override
                public void onGlobalLayout() {
                    int[] loc = new int[2];
                    ll.getLocationInWindow(loc);
                    scrollView.setYIntersection(loc[1]);
                    ViewGroup table = (ViewGroup) scrollView.getChildAt(0);
                    // find out which row initially intersects our line so
                    // we can initialize mCrossedRow and position
                    for (int i = 0; i < table.getChildCount(); i++) {
                        final View row = table.getChildAt(i);
                        row.getLocationInWindow(loc);
                        if (loc[1] <= scrollView.getYIntersection()
                                && loc[1] + row.getHeight() >= scrollView
                                        .getYIntersection()) {
                            scrollView.setCurrIntersection(row, i);
                            row.setBackgroundColor(Color.RED);
                            break;
                        }
                    }
                    scrollView.getViewTreeObserver()
                            .removeOnGlobalLayoutListener(this);
                }
            });

With the custom ScrollView being:

public class CustomScrollView extends ScrollView {

    /**
     * This will be the current intersected row.
     */
    private View mCrossedRow;
    /**
     * The row position of the intersected row, mCrossedRow.
     */
    private int mRowOrder;
    /**
     * The y value of the intersecting line.
     */
    private int mLine;
    /**
     * Used as a temporary holder for the location retrieval.
     */
    private int[] mLocHelper = new int[2];

    public CustomScrollView(Context context) {
        super(context);
    }

    public void setYIntersection(int y) {
        mLine = y;
    }

    public int getYIntersection() {
        return mLine;
    }

    public void setCurrIntersection(View row, int childPosition) {
        mCrossedRow = row;
        mRowOrder = childPosition;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        // this will be called every time the user scrolls so we need to
        // keep updating the position and see if the crossed row still
        // intersects the line otherwise move it to the next row.
        mCrossedRow.getLocationInWindow(mLocHelper);
        if (mLocHelper[1] <= mLine
                && mLocHelper[1] + mCrossedRow.getHeight() >= mLine) {
            // do nothing, we're still in the same row
        } else {
            if (t - oldt > 0) {
                // going down so increase the row position
                mRowOrder++;
            } else {
                // going up so decrease the row position
                mRowOrder--;
            }
            // visual effect, the intersecting row will have a red
            // background and all other rows will have a white background.
            // You could setup a listener here to get notified that a new
            // row intersects the line.
            mCrossedRow.setBackgroundColor(Color.WHITE);
            mCrossedRow = ((ViewGroup) getChildAt(0)).getChildAt(mRowOrder);
            mCrossedRow.setBackgroundColor(Color.RED);
        }
    }
}