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