2015-05-26 1 views
0

Чтобы избежать «внутреннего класса ада» в случае прослушивателей событий в 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(); 
    } 
} 

Где мое понимание не так?

+1

Возможно, это потому, что вы пытаетесь ввести в анонимный класс. – MyDogTom

+0

Я думаю, что это возможно передать 'dateView' в конструктор. И у меня есть вопрос. Почему вы не используете аннотацию ButterKnife '@ OnClick'? – MyDogTom

+0

Даже если бы я использовал '@ OnClick' Butterknife, мне все равно пришлось бы использовать' OnDateSetListener', поскольку в ButterKnife нет ничего похожего на '@ OnDateSet'. Что касается анонимной вещи класса, я стараюсь и даю вам знать. – TechSpellBound

ответ

1

Кажется, что инъекция Butterknife работает только в том случае, если инструкция Butterknife.inject() присутствует в конструкторе или любом из методов жизненного цикла Android.

Таким образом, я изменил DateViewClickListener класс, чтобы принять свою деятельность, что она будет вызываться из и использовать его в качестве «источника» для ножа для масла литьевого что-то вроде:

public class DateViewClickListener implements View.OnClickListener { 

    @InjectView(R.id.date) 
    TextView dateView; 


    private final DateTime prevDate; 
    private DateTimeFormatter dateFmt; 

    public DateViewClickListener(DateTime prevDate, DateTimeFormatter dateFmt, Activity contextActivity) { 
     Butterknife.inject(this, contextActivity); 
     this.prevDate = prevDate; 
     this.dateFmt = dateFmt; 
    } 

    ..... 
} 

А затем экземпляра слушателя, как:

public class MainActivity extends ActionBarActivity { 

    ..... 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     ...... 

     date.setOnClickListener(new DateViewClickListener(paymentDate, dateFmt, this)); 

     ...... 

    } 

    ..... 

}