2015-08-08 28 views
5

Sto provando a utilizzare un ciclo per impostare l'azione per ciascun pulsante quando si fa clic (poiché la maggior parte dei pulsanti restituirà il loro valore di testo), tuttavia viene visualizzato un errore "variabile 'I' è accessibile dalla classe interna, deve essere dichiarato finale ". Come posso aggirare questo?Utilizzo di un ciclo per impostare i pulsanti onclicklistener

Ecco cosa ho ottenuto

String getValuesPressed(){ 

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

     buttonList[i].setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       if(i == 0){//error occurs here 
        //do stuff 
       } 

      } 
     }); 
    } 
    return textOnScreen; 
} 

risposta

7

È possibile copiare il valore della i a una variabile finale Temp come -

for (int i = 0; i < buttonList.length; i++) { 
     final int finalI = i; 
     buttonList[i].setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       if (finalI == 0) {//error occurs here 
        //do stuff 
       } 
      } 
     }); 
    } 
2

Si sta creando un anonymous class (View.OnClickListener) per ogni pulsante, il metodo onClick() all'interno di quella classe ha un ambito diverso rispetto al metodo getValuesPressed(), pertanto non ha accesso alla variabile locale i.

La soluzione è contenuta all'interno del link fornito sopra:

An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.

introducendo quindi una variabile finale nel circuito potrebbe risolvere l'errore:

String getValuesPressed(){ 

    for(int i = 0; i < buttonList.length; i++){ 
     final int j = i; 
     buttonList[i].setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       if(j == 0){//error occurs here 
        //do stuff 
       } 

      } 
     }); 
    } 
    return textOnScreen; 
} 
1

è possibile creare voi proprio ascoltatore che prende il posizione come parametro per aggirare il fatto che stai usando una classe interna anonima.

private class MyClickListener implements View.OnClickListener { 

    int position; 

    public MyClickListener (int position) { 
     this.position = position; 
    } 

    @Override 
    public void onClick(View v) { 
     if(position == 0){ 
      //do stuff 
     } 
    } 
} 

Poi, nel tuo ciclo è possibile creare in questo modo

String getValuesPressed(){ 

    for(int i = 0; i < buttonList.length; i++){ 
     buttonList[i].setOnClickListener(new MyClickListener(i)); 
    } 

    return textOnScreen; 
}