Чтобы избежать «внутреннего класса ада» в случае прослушивателей событий в Android, я переместил слушателей на отдельные классы. Ниже приведен один из таких слушателей для TextView
, который содержит строку даты. Прикосновением к нему я открываю 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
. Однако этот код работает для меня, когда я не использую 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();
}
}
Где мое понимание не так?
Возможно, это потому, что вы пытаетесь ввести в анонимный класс. – MyDogTom
Я думаю, что это возможно передать 'dateView' в конструктор. И у меня есть вопрос. Почему вы не используете аннотацию ButterKnife '@ OnClick'? – MyDogTom
Даже если бы я использовал '@ OnClick' Butterknife, мне все равно пришлось бы использовать' OnDateSetListener', поскольку в ButterKnife нет ничего похожего на '@ OnDateSet'. Что касается анонимной вещи класса, я стараюсь и даю вам знать. – TechSpellBound