为了避免 Android 事件监听器出现“内部类地狱”,我将监听器移动到单独的类中。以下是TextView
保存日期字符串的 a 的此类侦听器之一。触摸它时,我打开 aDatePickerDialog
并将所选日期值设置回TextView
.
我进一步增强了这个监听器以使用 Butterknife,如下所示:
public class DateViewClickListener implements View.OnClickListener {
private final DateTime prevDate;
private DateTimeFormatter dateFmt;
public DateViewClickListener(DateTime prevDate, DateTimeFormatter dateFmt) {
this.prevDate = prevDate;
this.dateFmt = dateFmt;
}
@Override
public void onClick(View view) {
new DatePickerDialog(view.getContext(), new DatePickerDialog.OnDateSetListener() {
@InjectView(R.id.date)
TextView dateView;
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Activity activity = ActivityUtil.getParentActivity(view);
ButterKnife.inject(this, activity.getWindow().getDecorView());
DateTime newDate = prevDate.withDate(year, monthOfYear, dayOfMonth);
dateView.setText(dateFmt.print(newDate));
}
}, prevDate.getYear(), prevDate.getMonthOfYear(), prevDate.getDayOfMonth()).show();
}
}
ActivityUtil.getParentActivity(view)
在上面的代码中使用,扫描视图的上下文层次结构并找到它的父活动。以下是它的代码:
public class ActivityUtil {
public static Activity getParentActivity(View view) {
Context context = view.getContext();
return scanForActivity(context);
}
private static Activity scanForActivity(Context context) {
if (context == null)
return null;
else if (context instanceof Activity)
return (Activity) context;
else if (context instanceof ContextWrapper)
return scanForActivity(((ContextWrapper) context).getBaseContext());
return null;
}
}
在执行此代码时,dateView
剩下的会null
抛出一个NPE
. 但是,当我不使用 Butterknife 时,此代码对我有用(DateViewClickListener
在这种情况下,类如下)。
public class DateViewClickListener implements View.OnClickListener {
private final DateTime prevDate;
private DateTimeFormatter dateFmt;
public DateViewClickListener(DateTime prevDate, DateTimeFormatter dateFmt) {
this.prevDate = prevDate;
this.dateFmt = dateFmt;
}
@Override
public void onClick(View view) {
new DatePickerDialog(view.getContext(), new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Activity activity = ActivityUtil.getParentActivity(view);
TextView dateView = (TextView) activity.findViewById(R.id.date);
DateTime newDate = prevDate.withDate(year, monthOfYear, dayOfMonth);
dateView.setText(dateFmt.print(newDate));
}
}, prevDate.getYear(), prevDate.getMonthOfYear(), prevDate.getDayOfMonth()).show();
}
}
我的理解哪里出了问题?