Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
174 views
in Technique[技术] by (71.8m points)

java - How do I properly use an setOnItemClickListener?

Lets start with new to android I am.

I have a GridView setup as a grid and I'm using it to represent a board for a little board game app that I'm making. I have setup a "setOnItemClickListener" for my GridView that functions, at least for the Toast and set ImageResource I put in there for a test.

I don't know how to call my methods from other classes inside of the ClickListener to control what happens when touches occur. There doesn't appear to be a name or anything to use in conjunction with other methods. 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.

I can't change my objects to final so I need a way to run a little game loop that will be calling all the methods on objects from other classes that I require by communicating with that setOnItemClickListener.

Here is the part of my code that has the Listener:

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

The Toast and two ImageView img lines inside the listener are only for testing to see if it would work and it does for those task. I need a way to use the Listener in other places of my code though.

For an example, on the first touch, I would like to call a method I have created that will determine if the item selected is an eligible unit to move, and if so swap the image at that position with a new image. So it would look something like this I would imagine - gv.onTouchEvent1.checkPiece(player1, position); - Where checkPiece will get position from the ClickListener and perform it's function.

Any setOnItemClickListener tutorial suggestions would be nice.

----------------EDIT WITH MY SOLUTION--------------------------------

The only way I was able to make it work was by using a counter inside the onItemClick... that would allow me to control which method was called depending on what count was on using if statements along with a loop. This is still a work in progress so has some junk that I will delete later on, but this shows basically what I needed:

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

It just seems strange to me to have so much code going on in the onItemClick. My original intention was to call a method that pretty much contained everything that I ended up putting in the onClick, since I couldn't figure out how to differentiate touch events on their location alone.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I wouldn't call myself a newcomer

Ummmm...

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.

That is because the objects in question are either parameters to setOnItemClickListener() or are local variables, as opposed to being data members of the class where your play() method resides.

Bear in mind that OnItemClickListener is an interface, and so you do not need to use an anonymous inner class as you presently are. For example, you could implement this interface on the Activity that (presumably) is hosting the play() method.

Anonymous inner classes are a powerful, but expert, Java technique. I have taught many Android courses, and there are lots of experienced Java developers who do not recognize, let alone use, anonymous inner classes. Given your relative experience level, I would recommend that you avoid their use for the time being wherever possible.

Here is the part of my code that has the Listener

You are calling setOnItemClickListener() in a loop. This is probably not what you want.

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

No, you don't. You may need to have the listener do other things from its onItemClick() method, but the listener itself, as an object, is only going to be used in this one place, barring some seriously strange coding.

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

Or implement checkPiece() on the Activity that is (presumably) hosting all of this code, in which case you just call it.

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

To be completely blunt, your problems have little to do with Android and everything to do with Java. Feel free to ask java syntax and related questions here on StackOverflow, but do so with the tag (perhaps in addition to the tag) if it is likely to be related more to Java and less regarding Android's classes and methods.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...