Frage Wortsuchspiel: So wählen Sie mehrere Elemente in einer GridView durch Ziehen aus? (Android)


Hier sind die Programmdetails: Also erstelle ich ein Wortsuchspiel, zum Beispiel, wo ein paar Buchstaben in einem Quadrat angeordnet sind, und Sie müssen die Wörter finden und auswählen, die entweder vertikal, horizontal oder diagonal gehen. Ich verwende ein Array von Strings für die Platine und verwende ein ArrayAdapter, um dieses String-Array in einer Gridview zu speichern, die das Basiselement des Layouts meiner Hauptaktivität ist.

Hier ist die Frage: Wie stelle ich es so her, dass Benutzer ihren Finger über ihre Auswahl ziehen können, indem sie alle Buchstaben im Wort auswählen, ohne den Finger mehrmals vom Bildschirm abheben zu müssen? Und ich möchte, dass die Markierung über dem ausgewählten Wort entweder auf dem Bildschirm bleibt, der Spieler ein Wort ausgewählt hat, und ich möchte, dass die Markierung über den Buchstaben verschwindet, wenn der Benutzer seinen Finger vom Bildschirm hebt, wenn er ein Wort nicht richtig ausgewählt hat .


7
2017-08-01 00:49


Ursprung


Antworten:


Ich bin zu spät zu dieser Frage, aber in letzter Zeit bin ich auf ein ähnliches Problem gestoßen Brettansichts-Bibliothek um dieses Problem anzusprechen. Es bietet mehr Flexibilität für das, was Sie tun können, und es führt zu einer einfacheren Implementierung.

Hier sind einige Codeschnipsel, die zeigen, wie es funktioniert. Erstens ist es einfach, das Platinenraster auf einer benutzerdefinierten Ansicht zu zeichnen onDraw() Methode:

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

Wenn Sie eine haben String[][] Reihe von Strings, hier ist, wie Sie die Buchstaben setzen könnten, vorausgesetzt, die Ansichten für jede Kachel wurden bereits auf der Tafel platziert:

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

Dann brauchst du komplexere Arbeit, um die Berührung tatsächlich zu handhaben und über die Brettplättchen zu ziehen, um die Wörter auszuwählen:

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

Die Methoden isTileValid() und isTileAllowed() Vergewissern Sie sich, dass die Kachel, die der Benutzer auswählen möchte, in einer zulässigen Richtung liegt und nicht zuvor ausgewählt wurde. Endlich, das getTilesBetween() gebe alle gültigen Kacheln zwischen der ersten Kachel, die der Benutzer berührt hat, und derjenigen, die er gerade berührt, zurück.

Ich hoffe es hilft!


1
2018-02-05 10:40