Word Search Game: ¿Cómo seleccionar varios elementos en un GridView arrastrando?(Androide)
select drag (1)
AQUÍ ESTÁN LOS DETALLES DEL PROGRAMA: así que estoy creando un juego de búsqueda de palabras, como cuando hay un montón de letras dispuestas en un cuadrado, y tienes que buscar y seleccionar las palabras que van vertical, horizontal o diagonalmente. Estoy usando una matriz de cadenas para la placa y usando un ArrayAdapter para almacenar esta matriz de cadenas en una vista de cuadrícula, que es el elemento base del diseño de mi actividad principal.
AQUÍ ESTÁ LA PREGUNTA: ¿Cómo lo hago para que los usuarios puedan arrastrar el dedo sobre su selección, seleccionando todas las letras de la palabra sin tener que levantar el dedo varias veces? Y quiero que lo más destacado de la palabra seleccionada sea permanecer en la pantalla si el jugador seleccionó una palabra, y quiero que el resaltado sobre las letras desaparezca cuando el usuario levante su dedo de la pantalla si no seleccionó correctamente una palabra .
Llegué tarde a esta pregunta pero me encontré con un problema similar recientemente. Decidí crear mi propia biblioteca de vista de tabla personalizada para solucionar este problema. Agrega más flexibilidad a lo que puede hacer y conduce a una implementación más directa.
Aquí hay algunos fragmentos de código que muestran cómo funciona. En primer lugar, es fácil dibujar la cuadrícula de la tabla en el método onDraw()
una vista personalizada:
@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);
}
}
Si tiene un conjunto de cadenas String[][]
, aquí puede configurar las letras, suponiendo que las vistas para cada tesela ya se hayan colocado en el tablero:
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]);
}
}
Entonces necesitas un trabajo más complejo para manejar el toque y arrastrar los mosaicos de la placa para seleccionar las palabras:
@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;
}
Los métodos isTileValid()
e isTileAllowed()
aseguran de que el mosaico que el usuario está intentando seleccionar está en una dirección permitida y no se ha seleccionado previamente. Finalmente, getTilesBetween()
devuelve todos los mosaicos válidos entre el primer mosaico que tocó el usuario y el que está tocando actualmente.
¡Espero eso ayude!