1

I am new to Android programming.
I would like to use a for loop to do the similar things.
Here is my code:

int stubs[] = {R.id.stub_1, R.id.stub_2, R.id.stub_3};
View viewStubs[] = {stub_1, stub_2e, stub_3};
Button buttons[] = {button2, button3, button4};
button2 = (Button)findViewById(R.id.button2);
button3 = (Button)findViewById(R.id.button3);
button4 = (Button)findViewById(R.id.button4);
for(int i=0; i<buttons.length; i++){
            buttons[i].setOnClickListener(new View.OnClickListener() {      
                public void onClick(View v) {
                    if(viewStubs[i] == null){
                        viewStubs[i] = ((ViewStub)findViewById(stubs[i])).inflate();
                    }

                }
            }
        }

However, there is an error in onClick method "i":
Cannot refer to a non-final variable i inside an inner class defined in a different method

Andro Selva
  • 53,910
  • 52
  • 193
  • 240
jjLin
  • 3,281
  • 8
  • 32
  • 55
  • Check the following question http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-differen – barrel Aug 01 '12 at 10:32
  • There is no closures in Java with version less 7! You may not use local var `i` inside inner class. You should rewrite your code – Sergii Stotskyi Aug 01 '12 at 10:36
  • 1
    you can make a final int var and assign i to it. then pass the new var to the inner class... – Shark Aug 01 '12 at 10:40
  • I think you have to assign the int i globally, if you want to continue with the same code. But its really a cheap idea.. – Andro Selva Aug 01 '12 at 10:40
  • we can, you just need to a final variable index in loop, and then use this variable further – jeet Aug 01 '12 at 10:45
  • 1
    see this might be helpful for you http://stackoverflow.com/questions/9711312/dynamic-setonclicklistener/9713997#9713997 – Avi Kumar Aug 01 '12 at 10:48

3 Answers3

0

Try to add final before int i.

bluish
  • 26,356
  • 27
  • 122
  • 180
Santacrab
  • 3,165
  • 2
  • 25
  • 31
  • This wont work. Adding final to a variable in a for loop means the variable value can't be changed and hence it will start to throw some other error like "The final local variable i cannot be assigned". – Andro Selva Aug 01 '12 at 10:33
  • imagine looping over a final variable and you get why it's a problem. – Shark Aug 01 '12 at 10:37
  • for(final int i= 0; i < k; i++){...} final keyword is legal in this case but incompatible with i++. – Guillermo Blasco Aug 01 '12 at 15:34
0

viewStubs array should be a property of this class (it seems it may be static).

int stubs[] = {R.id.stub_1, R.id.stub_2, R.id.stub_3};
// viewStubs should be a property of this class (maybe static)
viewStubs[] = {stub_1, stub_2, stub_3};

Button buttons[] = {
   (Button)findViewById(R.id.button2),
   (Button)findViewById(R.id.button3),
   (Button)findViewById(R.id.button4)
};

for (int i=0; i<buttons.length; i++) {
    View.OnClickListener listener = new View.OnClickListener() {
        private int viewId;

        private int stubId;

        public void onClick(View v) {
           if (viewStubs[stubId] == null) {
              viewStubs[stubId] = (ViewStub)findViewById(viewId).inflate();
           }
        }

        public View.OnClickListener setIds(int vid, int sid) {
           viewId = vid;
           stubId = sid;
           return this;
        }
    }
    buttons[i].setOnClickListener(listener.setIds(stubs[i], i));
}
Sergii Stotskyi
  • 5,134
  • 1
  • 22
  • 21
0

for(int i = 0; i < something.length; i++){

 final int inmutable_index = i;

 btn.setOnClickListener(new OnClickListener(){...});

}

Now you can use inside for-loop the final variable inmutable_index without any problem, just replace all uses of i variable in the inner class for inmutable_index variable.