OnTouchListener For Multiple TextViews Inside TableRow
Solution 1:
Here's the code I tried myself:
The layout is just a TableLayout with 3 TableRows, and each TableRow contains 3 TextViews with ids like t1, t2, .., t9
And the activity:
public class ImgActivity extends Activity {
protected Map<View, Rect> cells = new HashMap<View, Rect>();
protected boolean hasCoordinatesPopulated;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TableLayout table = (TableLayout) findViewById(R.id.table);
table.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (!hasCoordinatesPopulated) {
View view = table.findViewById(R.id.t1);
Rect rect = getRawCoordinatesRect(view);
cells.put(view, rect);
view = table.findViewById(R.id.t2);
rect = getRawCoordinatesRect(view);
cells.put(view, rect);
view = table.findViewById(R.id.t3);
rect = getRawCoordinatesRect(view);
cells.put(view, rect);
view = table.findViewById(R.id.t4);
rect = getRawCoordinatesRect(view);
cells.put(view, rect);
view = table.findViewById(R.id.t5);
rect = getRawCoordinatesRect(view);
cells.put(view, rect);
view = table.findViewById(R.id.t6);
rect = getRawCoordinatesRect(view);
cells.put(view, rect);
view = table.findViewById(R.id.t7);
rect = getRawCoordinatesRect(view);
cells.put(view, rect);
view = table.findViewById(R.id.t8);
rect = getRawCoordinatesRect(view);
cells.put(view, rect);
view = table.findViewById(R.id.t9);
rect = getRawCoordinatesRect(view);
cells.put(view, rect);
hasCoordinatesPopulated = true;
}
}
private Rect getRawCoordinatesRect(final View view) {
int[] coords = new int[2];
view.getLocationOnScreen(coords);
Rect rect = new Rect();
rect.left = coords[0];
rect.top = coords[1];
rect.right = rect.left + view.getWidth();
rect.bottom = rect.top + view.getHeight();
return rect;
}
});
table.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(final View v, final MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
final int x = (int) event.getRawX();
final int y = (int) event.getRawY();
for (final Entry<View, Rect> entry : cells.entrySet()) {
final View view = entry.getKey();
final Rect rect = entry.getValue();
if (rect.contains(x, y)) {
view.setBackgroundColor(Color.CYAN);
} else {
view.setBackgroundColor(Color.TRANSPARENT);
}
}
return true;
}
return false;
}
});
}
}
Of course it's a quick sample variant. You can store your last selected view in a separate field (to deselect on move) and when element below the pointer is found, just break
the loop saving some time.
Solution 2:
Have you tried the following:
Get raw coordinates of all your textviews and storing them in a map with key being your TextView (or id) and value being Rect of it's coordinates and space it takes.
Set an ontouchlistener on your tableview, and then, when user moves, or touches something, you can get raw coordinates of the pointer, iterate through your map entries and find TextView currently below
?
P.S. This is first idea that popped in my mind. I'm pretty sure android can provide a more elegant solution.
Solution 3:
Works like a charm now. Thanks a bunch :>
EDIT: added handleCell()
// Initialization
grid.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
public void onGlobalLayout() {
if (!populatedCells) {
handlePopulate();
populatedCells = true;
}
}
});
private void handlePopulate () {
int curCellId = 0;
for (int i = 0; i < GRID_HEIGHT; i++) {
for (int j = 0; j < GRID_WIDTH; j++) {
TextView tv = (TextView) findViewById(curCellId);
Rect rect = getRawCoordinatesRect(tv);
Log.d("RECT", "id: "+tv.getId()+" "+rect.toString());
cells.put(tv, rect);
curCellId++;
}
}
}
// Listener
final OnTouchListener cellTouch = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent e) {
final int action = e.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE: {
handleCell(v,e);
break;
}
}
return true;
}
};
private TextView getCell (View v, MotionEvent e) {
int x = (int) e.getRawX();
int y = (int) e.getRawY();
for (final Entry<View, Rect> entry : cells.entrySet()) {
final View view = entry.getKey();
final Rect rect = entry.getValue();
if(rect.contains(x, y)) {
return (TextView) view;
}
}
return null;
}
private void handleCell (View v, MotionEvent e) {
TextView cell = getCell(v, e);
if (cell != null) {
cell.setBackgroundResource(R.layout.border_cell_current);
curCell = (TextView) cell;
// do something
}
}
Post a Comment for "OnTouchListener For Multiple TextViews Inside TableRow"