在 EditText 视图数组中动态创建 OnClickListener



我想创建一个 EditText 视图数组,然后仅为数组内的"日期相关"EditText 视图分配 OnClickListener。侦听器将弹出一个日期选取器对话框供用户输入。代码如下:

oEditText = new EditText[oFieldNames.length];    // oFieldNames contains field names like e.g. "Student ID", "Student Name", "Birth Date", "Start Date", "Gender", etc. 
for (int i = 0; i < oFieldNames.length; i++) {
oEditText[i] = new EditText(oContext);
...
// code for "Date-related" EditText view:
if (oFieldNames[i].toLowerCase().contains("date") == true) {
oEditText[i].setFocusable(false);
oEditText[i].setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int day = oCalendar.get(Calendar.DAY_OF_MONTH);
int month = oCalendar.get(Calendar.MONTH);
int year = oCalendar.get(Calendar.YEAR);
datePickerDialog = new DatePickerDialog(oContext, new DatePickerDialog.OnDateSetListener(){
@Override
public void onDateSet(DatePicker datePicker, int iYear, int iMonth, int iDay) {
oEditText[i] = (iYear + "/" + (iMonth+1) + "/" + iDay);
}
}, year, month, day);    // ERROR here!!!
datePickerDialog.show();    
}
});
}
}

正如预期的那样,出现错误消息,抱怨变量"i"在内部类中被访问,必须声明为"final"。好吧~coz的变量"i"不应该是"final",因为我正在用"i"做一个for循环。看起来我需要通过创建一个新的自定义 EditText 类来重组代码,但它很麻烦。关于如何进行小更改以使其成功运行的任何想法?

谢谢!

在这里我做了一些更改,使变量 i 变为 final. 试试看

for (int i = 0; i < oFieldNames.length; i++) {
oEditText[i] = new EditText(oContext);
...
// code for "Date-related" EditText view:
if (oFieldNames[i].toLowerCase().contains("date") == true) {
oEditText[i].setFocusable(false);
final int tempI=i;
oEditText[i].setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int day = oCalendar.get(Calendar.DAY_OF_MONTH);
int month = oCalendar.get(Calendar.MONTH);
int year = oCalendar.get(Calendar.YEAR);
datePickerDialog = new DatePickerDialog(oContext, new DatePickerDialog.OnDateSetListener(){
@Override
public void onDateSet(DatePicker datePicker, int iYear, int iMonth, int iDay) {
oEditText[tempI] = (iYear + "/" + (iMonth+1) + "/" + iDay);
}
}, year, month, day);    // ERROR here!!!
datePickerDialog.show();    
}
});
}
}

内部 for 循环 将 i 值分配给最终变量,然后像这样使用它

for (int i = 0; i < oFieldNames.length; i++) {
final int index = i;
oEditText[index].setOnClickListener(new OnClickListener() {
void onClick(View v) {
Log.i("TAG", "The index is" + index);
}
});
}

您可以为每个引用数组中 EditText 的循环设置最终的 EditText。
同样在里面onDateSet()使用setText()来设置编辑文本的文本。
将您的代码更改为以下内容:

for (int i = 0; i < oFieldNames.length; i++) {
oEditText[i] = new EditText(oContext);
final EditText et = oEditText[i];
// code for "Date-related" EditText view:
if (oFieldNames[i].toLowerCase().contains("date") == true) {
et.setFocusable(false);
et.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int day = oCalendar.get(Calendar.DAY_OF_MONTH);
int month = oCalendar.get(Calendar.MONTH);
int year = oCalendar.get(Calendar.YEAR);
datePickerDialog = new DatePickerDialog(oContext, new DatePickerDialog.OnDateSetListener(){
@Override
public void onDateSet(DatePicker datePicker, int iYear, int iMonth, int iDay) {
et.setText(iYear + "/" + (iMonth+1) + "/" + iDay);
}
}, year, month, day);    // ERROR here!!!
datePickerDialog.show();
}
});
}
}

你应该在调用setOnClickListener和创建内部类之前创建最终变量。

final int j = i;

然后使用 j 而不是 i

最新更新