到目前为止,我已经搜索了几个小时,但没有找到任何合适的解决方案来解决我的问题。
摆弄我的Android应用程序并尝试制作数独游戏。
TableLayout由9个TableRows组成,每个TableRows包含9个TextView。 因此,9 * 9网格包含81个TextView,每个TextView都有一个OnTouchListener:
final OnTouchListener cellTouch = new OnTouchListener() {
public boolean onTouch(View v, MotionEvent e) {
Log.d("TOUCH", "id: "+v.getId() + " "+e.toString());
final int action = e.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN: {
// set background to different colour
// set background back if this is different TextView
break;
}
case MotionEvent.ACTION_MOVE: {
break;
}
}
return true;
}
};
OnTouch会在每个单独的TextView上被触发,但在触摸一个并且移动轨迹球后会发生以下情况:
但是,我想要的是OnTouch在其他TextView上触发并突出显示它们。 我创建单元格的方式如下所示:
TextView cellLabel = (TextView) inflater.inflate(R.layout.sudoku_cell, tr, false);
cellLabel.setId(curCellId);
cellLabel.setText(""+ curCellId);
cellLabel.setOnTouchListener(cellTouch);
cellLabel.setOnFocusChangeListener(cellFocus);
cellLabel.setOnClickListener(cellClick);
cellLabel.setFocusable(true);
cellLabel.setClickable(true);
cellLabel.setFocusableInTouchMode(true);
每个单元格:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="35dp"
android:layout_weight="1"
android:textSize="18dp"
android:textColor="#FFFFFF"
android:gravity="center"
android:background="@layout/border"
/>
我一直在尝试这么多不同的事情。比如确定TextView指针在顶部,但运气不好。
希望你们任何一个人都有自己的想法。谢谢你的时间。亲切的问候。
修改
搜索函数循环遍历TextView [] []并找到合适的单元格。但是,仅适用于行。如果我从一行切换到另一行则不起作用。
private TextView getCell (View v, MotionEvent e) {
float x = e.getX();
float y = e.getY();
for (int i = 0; i < GRID_HEIGHT; i++) {
for (int j = 0; j < GRID_WIDTH; j++) {
TextView tv = tvGrid[i][j];
Rect rectView = new Rect(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
if(rectView.contains((int)x, (int)y)) {
return tv;
}
}
}
return null;
}
答案 0 :(得分:3)
这是我自己尝试的代码:
布局只是一个包含3个TableRows的TableLayout,每个TableRow包含3个带有ID的文本视图,如t1,t2,..,t9
活动:
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;
}
});
}
}
当然,这是一个快速的样本变体。您可以将最后选择的视图存储在单独的字段中(在移动时取消选择),当找到指针下方的元素时,只需break
循环节省一些时间。
答案 1 :(得分:0)
您是否尝试过以下操作:
获取所有文本视图的原始坐标并将其存储在地图中,其中键为TextView(或id),值为Rect的坐标和空间。
在tableview上设置ontouchlistener,然后,当用户移动或触摸某些内容时,您可以获取指针的原始坐标,遍历地图条目并查找当前位于
P.S。这是第一个出现在我脑海中的想法。我非常确定android可以提供更优雅的解决方案。
答案 2 :(得分:0)
现在就像魅力一样。非常感谢:&gt;
编辑:添加了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
}
}