java – 通过循环为按钮分配onClickListeners – Android

我知道如何通过长期非优雅的方式完成这项任务,但我想缩短它并使其更优雅.下面我展示了我可以做的非优雅的方式以及我想如何优雅地做到这一点.优雅的方式不是编译.我评论了错误的位置和错误.

任何代码结构帮助表示赞赏!先感谢您.

Results.java

public class Results extends Activity {
int x = -1;

Button q1details, q2details, q3details, q4details, q5details, q6details, q7details, q8details, q9details, q10details;

final Context context = this;

@Override
public void onCreate(Bundle savedInstanceState) {

    q1details = (Button)findViewById(R.id.q1details);
    q2details = (Button)findViewById(R.id.q2details);
    q3details = (Button)findViewById(R.id.q3details);
    q4details = (Button)findViewById(R.id.q4details);
    q5details = (Button)findViewById(R.id.q5details);
    q6details = (Button)findViewById(R.id.q6details);
    q7details = (Button)findViewById(R.id.q7details);
    q8details = (Button)findViewById(R.id.q8details);
    q9details = (Button)findViewById(R.id.q9details);
    q10details = (Button)findViewById(R.id.q10details);

    buttonList.add(q1details); buttonList.add(q2details); buttonList.add(q3details); buttonList.add(q4details); buttonList.add(q5details); buttonList.add(q6details); buttonList.add(q7details); buttonList.add(q8details); buttonList.add(q9details); buttonList.add(q10details);

    for(int i = 0; i < buttonList.size(); i++) {
        buttonList.get(i).setText("Question Details");
        buttonList.get(i).setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                x = i;  //ERROR:  "Cannot refer to a non-final variable  i inside an inner class defined in a different method."  But I cannot put the i as Final in a for-loop.
                displayDetails();
            }
        });
    }

/*      q1details.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            x = 0;
            displayDetails();
        }
    });
            //I could do 10 of these to accomplish the task but its non-elegant...
*/

public void displayDetails() {

    final Dialog dialog = new Dialog(context);
    dialog.setContentView(R.layout.questiondetails);
    dialog.setTitle("Question " + (x + 1) + " Details");

    ImageView image = (ImageView)dialog.findViewById(R.id.image);
    TextView correctness = (TextView)dialog.findViewById(R.id.correctness);
    TextView questionHeader = (TextView)dialog.findViewById(R.id.questionHeader);
    TextView question = (TextView)dialog.findViewById(R.id.question);
    TextView selectedAnswerHeader = (TextView)dialog.findViewById(R.id.selectedAnswerHeader);
    TextView selectedAnswer = (TextView)dialog.findViewById(R.id.selectedAnswer);
    TextView correctAnswerHeader = (TextView)dialog.findViewById(R.id.correctAnswerHeader);
    TextView correctAnswer = (TextView)dialog.findViewById(R.id.correctAnswer);
    TextView points = (TextView)dialog.findViewById(R.id.points);
    TextView verseHeader = (TextView)dialog.findViewById(R.id.verseHeader);
    TextView verse = (TextView)dialog.findViewById(R.id.verse);
    Button close = (Button)dialog.findViewById(R.id.close);

    if(qs.get(x).getSelectedAnswer() == qs.get(x).getCorrectAnswer()) {
        image.setBackgroundResource(R.drawable.green_check_mark);
        correctness.setText("CORRECT!");
        correctness.setTextColor(Color.GREEN);
    } else {
        image.setBackgroundResource(R.drawable.red_x);
        correctness.setText("INCORRECT!");
        correctness.setTextColor(Color.RED);
    }

    String a = "<u>QUESTION</u>";
    questionHeader.setText(Html.fromHtml(a));
    question.setText(qs.get(0).getQuery());

    String b = "<u>ANSWER YOU SELECTED</u>";
    selectedAnswerHeader.setText(Html.fromHtml(b));
    selectedAnswer.setText("" + qs.get(0).getStringSelectedAnswer());

    String c = "<u>CORRECT ANSWER</u>";
    correctAnswerHeader.setText(Html.fromHtml(c));
    correctAnswer.setText("" + qs.get(0).getStringCorrectAnswer());

    points.setText("You received " + QuestionView.getPointsPerQuestion().get(x) + " out of a possible 100 points.");

    String d = "<u>PROVE THE ANSWER IN YOUR BIBLE</u>";
    verseHeader.setText(Html.fromHtml(d));
    verse.setText(qs.get(0).getVerse());        

    close.setText("Close");

    close.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            dialog.dismiss();
        }
    });
    dialog.show();
}

解决方法:

在匿名类的正外部范围内声明的最终引用可供该匿名类访问. (Java的闭包味道):

for(int i = 0; i < buttonList.size(); i++) {
    Button button = buttonList.get(i);
    button.setText("Question Details");

    final int j = i;

    button.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
            x = j;
            displayDetails();
        }
    });
}

相关文章

Android 如何解决dialog弹出时无法捕捉Activity的back事件 在...
Android实现自定义带文字和图片的Button 在Android开发中经常...
Android 关于长按back键退出应用程序的实现最近在做一个Andr...
android自带的时间选择器只能精确到分,但是对于某些应用要求...