java - 如何正确使用 setOnItemClickListener?

标签 java android android-gridview onitemclicklistener

让我们从我刚接触 Android 开始吧。

我有一个 GridView 设置作为网格,我用它来代表我正在制作的一个小棋盘游戏应用程序的棋盘。我已经为我的 GridView 设置了一个“setOnItemClickListener”,该功能至少对于 Toast 来说是有效的,并设置了我放入其中进行测试的 ImageResource。

我不知道如何从 ClickListener 内的其他类调用我的方法来控制触摸发生时发生的情况。似乎没有名称或任何可以与其他方法结合使用的内容。 当我尝试将代码放入 setOnItemClickListener 中时,但收到一条警告,指出我要从中调用方法的类的对象必须是最终对象才能在另一个方法的内部类中使用。

我无法将我的对象更改为最终对象,因此我需要一种方法来运行一个小游戏循环,该循环将通过与 setOnItemClickListener 通信来调用我需要的其他类中对象的所有方法。

这是我的代码中包含监听器的部分:

public View play(GridView gv) { 
    boolean p1turn = true;
    while (gameOver == false) {
        gv.setOnItemClickListener(new OnItemClickListener(){
            public void onItemClick(AdapterView<?> parent, View v, int position, long id){
                Toast.makeText(ctxt, "" + position, Toast.LENGTH_SHORT).show();
                ImageView img = (ImageView)v;
                img.setImageResource(R.drawable.paper1select);
            }
        });
        System.out.println("Why no get here??");
        return(gv);//IDK why but this is NEVER reached, almost like the oICL is an infinite loop???
    }
    return gv;
}

监听器内的 Toast 和两个 ImageView img 行仅用于测试它是否有效以及是否适用于这些任务。 不过,我需要一种在代码的其他位置使用监听器的方法。

例如,在第一次触摸时,我想调用我创建的一个方法,该方法将确定所选项目是否符合移动条件,如果是,则将该位置的图像与新图像交换。所以它看起来像我想象的那样 - gv.onTouchEvent1.checkPiece(player1,position); - checkPiece 将从 ClickListener 获取位置并执行其功能。

任何 setOnItemClickListener 教程建议都会很好。

----------------用我的解决方案编辑---------------------------------------- -----

我能够使其工作的唯一方法是在 onItemClick... 中使用计数器,这将允许我根据使用的计数来控制调用哪个方法if 语句和循环。这仍然是一项正在进行的工作,因此有一些垃圾我稍后会删除,但这基本上显示了我需要的内容:

public class MainActivity extends Activity {

/*
 * count used to keep track of which step of game-play we are on. pNum used
 * to track which player's turn it is.
 */
protected static int count = 0, pNum = 0, round = 0;

// Used to keep know that a step is done, in conjunction with count,
// redundant I believe. TRUE indicates "done".
protected static boolean choosePiece = false, chooseEmpty = false,
        verifyEmpty = false, selectEnemy = false, verifyEnemy = false;

// Used to track selected piece location.
protected static int selectedLocation;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final ImageAdapter iA = new ImageAdapter(this);

    GridView gridview = (GridView) findViewById(R.id.gridview);
    gridview.setAdapter(iA);

    final GameplayController gc = new GameplayController(this);

    // Create board model, add units to player's list.
    final UnitArray gameBoardModel = new UnitArray();

    gridview.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v,
                int position, long id) {

            while (count <= 6) {
                System.out.println("While loop cycle: " + round);
                /*
                 * First IF is for selecting piece to move.
                 */
                if (count == 0) {
                    System.out.println("IF 0 WAS HIT");
                    System.out.println("It is player " + pNum
                            + "s turn, round " + round);
                    choosePiece = gc.choosePiece(position, gameBoardModel,
                            (ImageView) v, pNum);
                    if (choosePiece == true) {
                        count++;
                    }
                    selectedLocation = position;
                    break;
                }
                /*
                 * Second IF is for selecting blank space to move to.
                 */
                if (count == 1 && choosePiece == true
                        && chooseEmpty == false) {
                    System.out.println("IF 1 WAS HIT");
                    chooseEmpty = gc.chooseEmpty(position, gameBoardModel,
                            (ImageView) v);
                    if (chooseEmpty == true) {
                        count++;
                    }
                    break;
                }
                /*
                 * Third IF is for verifying the blank selected and moving
                 * piece.
                 */
                if (count == 2 && verifyEmpty == false
                        && choosePiece == true && chooseEmpty == true) {
                    System.out.println("IF 2 WAS HIT");
                    verifyEmpty = gc.checkEmptyChoice(position);
                    if (verifyEmpty == true) {
                        gc.moveToEmpty(position, gameBoardModel,
                                (ImageView) v, selectedLocation);
                        count++;
                        iA.notifyDataSetChanged();
                        selectedLocation = position;
                    }
                    break;
                }
                /*
                 * Fourth IF is for selecting an enemy unit to attack.
                 */
                if (count == 3 && selectEnemy == false
                        && verifyEmpty == true && choosePiece == true
                        && chooseEmpty == true) {
                    System.out.println("IF 3 WAS HIT");
                    selectEnemy = gc.selectEnemy(position, gameBoardModel,
                            (ImageView) v);
                    if (selectEnemy == true) {
                        count++;
                    }
                    break;
                }

                /*
                 * Fifth IF is for verifying enemy unit to attack and then
                 * attacking.
                 */
                if (count == 4 && verifyEnemy == false
                        && selectEnemy == true && verifyEmpty == true
                        && choosePiece == true && chooseEmpty == true) {
                    System.out.println("IF 4 WAS HIT");
                    verifyEnemy = gc.verifyEnemySelected(position);
                    if (verifyEnemy) {
                        /*
                         * For clarity, position is enemy being attacked,
                         * selectedLocation is position of attacking unit.
                         */
                        gc.attackEnemy(position, gameBoardModel,
                                (ImageView) v, selectedLocation);

                        // RESET FOR NEXT PLAYER TURN.
                        iA.notifyDataSetChanged();
                        if (pNum == 0) {
                            pNum = 1;
                        } else {
                            pNum = 0;
                        }
                        iA.notifyDataSetChanged();
                        count = 0;
                        choosePiece = false;
                        chooseEmpty = false;
                        verifyEmpty = false;
                        selectEnemy = false;
                        verifyEnemy = false;
                        round++;
                    }
                    break;
                }
            }
        }
    });
}
...

onItemClick 中执行如此多的代码对我来说似乎很奇怪。我的初衷是调用一个几乎包含我最终放入 onClick 中的所有内容的方法,因为我无法弄清楚如何单独区分触摸事件的位置。

最佳答案

I wouldn't call myself a newcomer

嗯...

When I try to put my code inside the setOnItemClickListener but I get a warning saying that my Object, of the class I want to call the methods from, must be final to use in the inner class of another method.

这是因为相关对象要么是 setOnItemClickListener() 的参数,要么是局部变量,而不是 play() 所在类的数据成员方法驻留。

请记住,OnItemClickListener 是一个接口(interface),因此您不需要像现在一样使用匿名内部类。例如,您可以在(可能)托管 play() 方法的 Activity 上实现此接口(interface)。

匿名内部类是一种强大且专业的 Java 技术。我教授过许多 Android 类(class),并且有很多经验丰富的 Java 开发人员不认识匿名内部类,更不用说使用匿名内部类了。鉴于您的相对经验水平,我建议您暂时避免使用它们。

Here is the part of my code that has the Listener

您正在循环中调用setOnItemClickListener()。这可能不是您想要的。

I need a way to use the Listener in other places of my code though.

不,你不知道。您可能需要让监听器通过其 onItemClick() 方法执行其他操作,但监听器本身作为一个对象,只会在这一个地方使用,除非某些严重奇怪的编码。

So it would look something like this I would imagine - gv.onTouchEvent1.checkPiece(player1, position); -

或者在(可能)托管所有这些代码的 Activity 上实现 checkPiece(),在这种情况下,您只需调用它即可。

I have been learning Java for a year now, my first language

坦率地说,您的问题与 Android 无关,而与 Java 有关。请随意在 StackOverflow 上询问 java 语法和相关问题,但可以使用 来提问。标签(可能除了 标签),如果它可能与 Java 更多相关,而与 Android 的类和方法相关较少。

关于java - 如何正确使用 setOnItemClickListener?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16226125/

相关文章:

java - Android if 语句 - 如果字符串包含数组中的任何字符串

android - 在 TabLayout 中禁用选项卡的多点触控

java - 如何动态地将图像添加到 GridView?

android - 使用多列自定义布局在 Android 中显示产品列表

android - 无限项的无限滚动

java - 为什么我的 Jenkins 插件找不到我的 pom.xml 依赖项?

java - 使用 Jackson 将不同类型反序列化为单个字段

java - JSP MySQL 错误

java - 在 Activity 类中使用哪个上下文?

安卓多点触控