-2

The error that I am getting is that within public void pressed, the variable i cannot be accessed unless the int is set as final. But, if I set it as final, the i++ becomes the error. I am stuck unless I can access the i variable from within my inline function. Is this possible?

for (int i = 0; i < level.myItems.size(); i++) {
    itemsInInventory[i].setButtonListener(new UIButtonListener() {
        public void pressed(UIButton button, Sprites sprite) {
            itemsInInventory[i].performAction();;
        }
    });
}
John Kugelman
  • 349,597
  • 67
  • 533
  • 578

2 Answers2

4

You can declare a final local variable inside the loop:

for(int i = 0; i < level.myItems.size(); i++){
    final int j = i;
    itemsInInventory[i].setButtonListener(new UIButtonListener(){
        public void pressed(UIButton button, Sprites sprite){
            itemsInInventory[j].performAction();
        }
    });
}

Or, better, since you just need the button, not i:

for(int i = 0; i < level.myItems.size(); i++){
    final UIButton btn = itemsInInventory[i];
    btn.setButtonListener(new UIButtonListener(){
        public void pressed(UIButton button, Sprites sprite){
            btn.performAction();
        }
    });
}

Or even better (since presumably the first argument to pressed is the button itself):

for(int i = 0; i < level.myItems.size(); i++){
    itemsInInventory[i].setButtonListener(new UIButtonListener(){
        public void pressed(UIButton button, Sprites sprite){
            button.performAction();
        }
    });
}

Note that with the last version, you don't need a separate UIButtonListener for each button. Just set them all to have the same listener and the listener will dispatch to the appropriate button automatically:

UIButtonListener listener = new UIButtonListener(){
    public void pressed(UIButton button, Sprites sprite){
        button.performAction();
    }
};
for(int i = 0; i < level.myItems.size(); i++){
    itemsInInventory[i].setButtonListener(listener);
}
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
1

The problem is that your variable's lifetime is tied to the for loop, but the object you're creating can live on forever. In order to do something like this, the variable needs to be final so the compiler knows that it can make a hidden copy of it inside the anonymous class. You can do this:

for(int i = 0; i < foo; i++) {
    final int index = i;
    ... anonymous class using "index"...
}

Java 8 makes this a bit simpler but is only available on Android N and newer.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152