Android 文字搜索游戏:如何通过拖动在GridView中选择多个项目?(安卓)

Android 文字搜索游戏:如何通过拖动在GridView中选择多个项目?(安卓),android,select,gridview,word,drag,Android,Select,Gridview,Word,Drag,以下是程序的详细信息:因此我正在创建一个单词搜索游戏,比如有一堆字母排列在一个正方形中,你必须找到并选择垂直、水平或对角的单词。我正在为线路板使用字符串数组,并使用ArrayAdapter将该字符串数组存储在gridview中,gridview是我主要活动布局的基本元素 这里有一个问题:我该如何做,以便用户可以将手指拖动到所选内容上,选择单词中的所有字母,而无需将手指多次抬离屏幕?我希望所选单词上的突出显示要么留在屏幕上,要么就是播放器选择了一个单词,如果用户没有正确选择单词,我希望当用户从屏幕

以下是程序的详细信息:因此我正在创建一个单词搜索游戏,比如有一堆字母排列在一个正方形中,你必须找到并选择垂直、水平或对角的单词。我正在为线路板使用字符串数组,并使用ArrayAdapter将该字符串数组存储在gridview中,gridview是我主要活动布局的基本元素


这里有一个问题:我该如何做,以便用户可以将手指拖动到所选内容上,选择单词中的所有字母,而无需将手指多次抬离屏幕?我希望所选单词上的突出显示要么留在屏幕上,要么就是播放器选择了一个单词,如果用户没有正确选择单词,我希望当用户从屏幕上抬起手指时,字母上的突出显示消失。

我回答这个问题晚了,但最近遇到了类似的问题,我决定创建自己的自定义来解决这个问题。它为您所能做的事情增加了更多的灵活性,并带来了更直接的实现

下面是一些代码片段,展示了它是如何工作的。首先,在自定义视图的
onDraw()
方法上绘制电路板网格很容易:

@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);
    }
}
然后,您需要更复杂的工作来实际处理触摸,并在板瓷砖上拖动以选择单词:

@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;
}
@覆盖
公共布尔onTouchEvent(运动事件){
float X=event.getX();
float Y=event.getY();
int行=(int)(Y/getTileSize());
int col=(int)(X/getTileSize());
查看子对象=getChildAt(行、列);
//无效触摸时退出
如果(event.getActionMasked()!=MotionEvent.ACTION\u UP
&&(行>=getNumRows()
||col>=getNumCols()
||child==null){
返回true;
}
开关(event.getActionMasked()){
case MotionEvent.ACTION\u DOWN:
case MotionEvent.ACTION\u移动:
当前磁贴=新磁贴(行、列、子级);
如果(currentSelectedWord==null){
currentSelectedWord=新选定的Word(currentTile);
}如果(!currentTile.equals(currentSelectedWord.lastTile),则为else
&¤tSelectedWord.isTileValid(currentTile)){
如果(!currentSelectedWord.isTileAllowed(currentTile)){
//清除旧选择的状态
更新文件(currentSelectedWord.SelectedFiles、false、false);
//如果当前磁贴有效但不允许用于当前单词选择,
//启动与平铺匹配的新选择
currentSelectedWord=新建SelectedWord(currentSelectedWord.getInitialTile());
}
List tiles=gettiles中间(currentSelectedWord.lastTile,currentTile);
如果(tiles.size()>0){
currentSelectedWord.addTiles(瓷砖);
}
}
更新文件(currentSelectedWord.SelectedFiles,true、false);
打破
case MotionEvent.ACTION\u UP:
如果(currentSelectedWord!=null){
布尔值isValidSelection=(listener!=null&&listener.onWordSelected(currentSelectedWord.toBoardWord());
更新文件(currentSelectedWord.SelectedFiles、false、isValidSelection);
如果(isValidSelection){
selectedWords.add(当前selectedword);
}
currentSelectedWord=null;
}
打破
违约:
返回false;
}
返回true;
}
方法
isTileValid()
isTileAllowed()
确保用户尝试选择的磁贴位于允许的方向,并且以前没有选择过。最后,
getTilesBetween()
返回用户触摸的第一个磁贴和当前正在触摸的磁贴之间的所有有效磁贴


希望有帮助

哈哈哈谢谢,我希望我现在能记住这些东西,不记得我最后做了什么。也许我会试着重新开始。
@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;
}