Bu soruya geç kaldım, ancak yakın zamanda benzer bir problemle karşılaştığımda, bu sorunu çözmek için kendi özel board view library'u oluşturmaya karar verdim. Yapabilecekleriniz için daha fazla esneklik sağlar ve daha basit bir uygulamaya yol açar.
İşte nasıl çalıştığını gösteren bazı kod parçacıkları. Birincisi, özel bir görünümün onDraw()
yöntemine tahta ızgara çizmek kolaydır:
burada zaten her bir parça için görüşlerini varsayarak, mektuplar gelmiş ayarlamasını olduğunu dizeleri bir
String[][]
dizisi varsa
@Override
protected void onDraw(Canvas canvas) {
for (int i = 0; i <= numRows; i++) {
//For custom grid sizes, y can't be equal the board size or the line drawn won't show
int y = Math.min(boardHeight - 1, i * tileSize);
canvas.drawLine(0, y, boardWidth, y, boardPaint);
}
for (int i = 0; i <= numCols; i++) {
//For custom grid sizes, x can't be equal the board size or the line drawn won't show
int x = Math.min(boardWidth - 1, i * tileSize);
canvas.drawLine(x, 0, x, boardHeight, boardPaint);
}
}
gemide yerleştirildi:
kelimeleri seçmek için aslında pano fayans üzerinde dokunma ve sürükleme işlemek için daha karmaşık çalışma gerekir Sonra
public void setLetterBoard(String[][] letterBoard) {
if (letterBoard.length != getNumRows()
|| letterBoard[0].length != getNumCols()) {
setBoardSize(letterBoard.length, letterBoard[0].length);
}
int row, col;
for (int i=0; i < getChildCount(); i++) {
row = i/getNumCols();
col = i % getNumCols();
LetterTileView child = (LetterTileView) getChildAt(i);
child.setLetter(letterBoard[row][col]);
}
}
:
@Override
public boolean onTouchEvent(MotionEvent event) {
float X = event.getX();
float Y = event.getY();
int row = (int) (Y/getTileSize());
int col = (int) (X/getTileSize());
View child = getChildAt(row, col);
//Exit on invalid touches
if (event.getActionMasked() != MotionEvent.ACTION_UP
&& (row >= getNumRows()
|| col >= getNumCols()
|| child == null)) {
return true;
}
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
Tile currentTile = new Tile(row, col, child);
if (currentSelectedWord == null) {
currentSelectedWord = new SelectedWord(currentTile);
} else if (!currentTile.equals(currentSelectedWord.lastTile)
&& currentSelectedWord.isTileValid(currentTile)) {
if (!currentSelectedWord.isTileAllowed(currentTile)) {
//Clear the status of the old selection
updateTiles(currentSelectedWord.selectedTiles, false, false);
//If the current tile is valid but not allowed for the current word selection,
//start a new selection that matches the tile
currentSelectedWord = new SelectedWord(currentSelectedWord.getInitialTile());
}
List<Tile> tiles = getTilesBetween(currentSelectedWord.lastTile, currentTile);
if (tiles.size() > 0) {
currentSelectedWord.addTiles(tiles);
}
}
updateTiles(currentSelectedWord.selectedTiles, true, false);
break;
case MotionEvent.ACTION_UP:
if (currentSelectedWord != null) {
boolean isValidSelection = (listener != null && listener.onWordSelected(currentSelectedWord.toBoardWord()));
updateTiles(currentSelectedWord.selectedTiles, false, isValidSelection);
if (isValidSelection) {
selectedWords.add(currentSelectedWord);
}
currentSelectedWord = null;
}
break;
default:
return false;
}
return true;
}
isTileValid()
ve isTileAllowed()
yöntemleri, kullanıcının seçmeye çalıştığı döşemenin izin verilen bir yönde olduğundan ve daha önce seçilmediğinden emin olun. Son olarak, getTilesBetween()
, geçerli olan tüm kiremitleri, kullanıcının dokunduğu ilk kiremit ile o anda dokunmakta olduğu arasındaki geri döndürür.
Umut eder!