Android イベント リスナーの場合の「内部クラス地獄」を回避するために、リスナーを別のクラスに移動しました。TextView
以下は、日付文字列を保持する のリスナーの 1 つです。それに触れると、 を開きDatePickerDialog
、選択した日付の値を に戻します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
. ただし、このコードは、バターナイフを使用しない場合に機能します (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();
}
}
私の理解はどこが間違っていますか?