2015-02-21 2 views
3

Я нахожусь на ранних стадиях разработки Android, и у меня возникла проблема с циклом for.Android Java: Использование setOnClickListener in for loop

Вот мой код:

for (int i=0; i<=30; i++){ 

     tableRows[i] = new TableRow(this); 
     tableRows[i].setId(i); 
     tableRows[i].setLayoutParams(tableRowParams); 
     tableRows[i].setBackgroundResource(R.drawable.bg); 

     textViews1[i] = new TextView(this); 
     textViews1[i].setText("Eng Kelime " + i); 
     textViews1[i].setTextSize(25); 
     textViews1[i].setTextColor(Color.WHITE); 
     textViews1[i].setId(i); 
     textViews1[i].setPadding(20, 30, 0, 0); 
     textViews1[i].setLayoutParams(Params2); 
     tableRows[i].addView(textViews1[i]); 

     textViews2[i] = new TextView(this); 
     textViews2[i].setText("Tr Kelime " + i); 
     textViews2[i].setTextSize(25); 
     textViews2[i].setTextColor(Color.WHITE); 
     textViews2[i].setId(i); 
     textViews2[i].setPadding(30,30,0,0); 
     textViews2[i].setLayoutParams(Params2); 
     tableRows[i].addView(textViews2[i]); 

     tableLayout.addView(tableRows[i]); 

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

       //These textViews[i] veriables need to be declared final. 
       //But I don't know how!.. 

       if (textViews2[i].getVisibility() == View.VISIBLE) { 
        textViews2[i].setVisibility(View.INVISIBLE); 
       }else{ 
        textViews2[i].setVisibility(View.VISIBLE); 
       } 
      } 
     }); 


    } 

У меня есть TableRows и два textViews в каждом TableRows. Когда я нажимаю первый textView1[i], второй, textView2[i] будет невидимым или видимым.

Но в setOnClickListener кодовый блок у меня был «переменная« i »доступна изнутри внутреннего класса, который должен быть объявлен окончательным» кодом ошибки.

Я объявил i как final, как for(final int i=0; i<=30; i++). Тогда у меня была другая ошибка. «Variable„я“не может быть объявлен окончательный»

+0

вы не можете изменить значение конечного variable.remember, что –

+0

Declare я, как переменная члена. –

ответ

2

Объявите новую переменную j и изменить код, как:

final int j = i; 
textViews1[j].setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      if (textViews2[j].getVisibility() == View.VISIBLE) { 
       textViews2[j].setVisibility(View.INVISIBLE); 
      }else{ 
       textViews2[j].setVisibility(View.VISIBLE); 
      } 
     } 
    }); 

Попробуйте это. Это сработает.

+0

спасибо. Это работает. :) Я не могу проголосовать за ваш ответ. У меня нет привилегии модерации. Извините .. –

+0

@ DegetThe: можете ли вы пометить ответ как правильный? Это будет полезно для других. Спасибо :) –

+0

Я отметил это как правильный ответ. Он был зеленым. Я проверил его снова.Теперь? –

2

Для того, чтобы получить доступ к локальной переменной из внутреннего класса, он должен быть объявлен final, поэтому он не может быть изменен внешне. Вы можете сделать это с помощью дополнительного фиктивной переменной:

final index = i; // here! 
textViews1[i].setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (textViews2[index].getVisibility() == View.VISIBLE) { 
       textViews2[index].setVisibility(View.INVISIBLE); 
      }else{ 
       textViews2[index].setVisibility(View.VISIBLE); 
      } 
     } 
    }); 
+0

спасибо, что ... –

1

Попробуйте это:

final TextView txtToToggle = textViews2[i]; 
textViews1[i].setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     if (txtToToggle.getVisibility() == View.VISIBLE) { 
      txtToToggle.setVisibility(View.INVISIBLE); 
     } else { 
      txtToToggle.setVisibility(View.VISIBLE); 
     } 
    } 
}); 
+0

Этот тоже работает. Спасибо большое .. :) –

0

Я declered "я" в качестве окончательного как "для (конечная ИНТ я = 0; я < = 30; я ++)". Тогда у меня была другая ошибка. «Veriable„я“не может быть объявлен окончательный»

Декларирование я как окончательный означает, что вы не можете изменить значение я. Следовательно, i ++ будет недействительным. Вы не можете объявить i как окончательный в для цикл.

Путь вокруг было бы создать новую переменную, скажем J, как окончательное и присвоить ему значение я. Во внутреннем классе используйте j вместо i как указано @ZygoteInit.

+0

Большое спасибо. Я понял, что делает последнее сейчас .. :) –

0

Я обеспечиваю вам очень простой трюк, как и в Java, с JMenuItem, но вы можете сделать то же самое для вашего проекта:

package tests; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 

import javax.swing.JMenu; 
import javax.swing.JMenuBar; 
import javax.swing.JMenuItem; 

public class MyMenu extends JMenuBar { 

    private ArrayList<String> list = new ArrayList<String>(); 
    private JMenu menu = new JMenu("Menu"); 
    private ArrayList<JMenuItem> jMenus = new ArrayList<JMenuItem>(); 

    public MyMenu() { 
     populateMenu(); 
     createMenu(); 
     createAction(); 
    } 

    private void populateMenu(){ 
     for (int i = 0; i < 3; i++) { 
      list.add("Object "+i); 
     } 
    } 

    private void createMenu(){ 
     for (int i = 0; i < list.size(); i++) { 
      JMenuItem item = new JMenuItem(list.get(i)); 
      jMenus.add(item); 
      menu.add(item); 
     } 
     add(menu); 
    } 

    private void createAction(){ 

     for (int i = 0; i < jMenus.size(); i++) { 
      final int index = i; 
      jMenus.get(i).addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        System.out.println(jMenus.get(index).getText()); 
       } 
      }); 
     } 
    } 
}