Android / Dagger2 - Как добавить аргументы пакета? Вставить фрагмент или использовать newInstance? - PullRequest
0 голосов
/ 29 августа 2018

Я ищу решение о том, как внедрить фрагмент и передать ему аргументы. И я не нашел правильного решения, потому что внедрение фрагмента означает конструктор, который небезопасен для состояний.

Есть ли способ сделать это, не вызывая шаблон newInstance?

Спасибо

Best.

1 Ответ

0 голосов
/ 30 августа 2018

Поскольку Android управляет жизненным циклом вашего Фрагмента, вы должны разделить проблемы прохождения состояния во Фрагмент через его связку и , вводящих Фрагмент с помощью инъецируемых капсул . Как правило, лучший способ отделить их - предоставить статический фабричный метод , который вы могли бы вызывать newInstance pattern .

public class YourFragment extends Fragment {

  // Fragments must have public no-arg constructors that Android can call.
  // Ideally, do not override the default Fragment constructor, but if you do
  // you should definitely not take constructor parameters.

  @Inject FieldOne fieldOne;
  @Inject FieldTwo fieldTwo;

  public static YourFragment newInstance(String arg1, int arg2) {
    YourFragment yourFragment = new YourFragment();
    Bundle bundle = new Bundle();
    bundle.putString("arg1", arg1);
    bundle.putInt("arg2", arg2);
    yourFragment.setArguments(bundle);
    return yourFragment;
  }

  @Override public void onAttach(Context context) {
    // Inject here, now that the Fragment has an Activity.
    // This happens automatically if you subclass DaggerFragment.
    AndroidSupportInjection.inject(this);
  }

  @Override public void onCreate(Bundle bundle) {
    // Now you can unpack the arguments/state from the Bundle and use them.
    String arg1 = bundle.getString("arg1");
    String arg2 = bundle.getInt("arg2");
    // ...
  }
}

Обратите внимание, что это инъекция другого типа, к которой вы можете привыкнуть: вместо того, чтобы получать экземпляр Fragment путем его инъекции, вы говорите Fragment, чтобы вставлял себя позже , как только он был присоединен к деятельность. В этом примере для этой инъекции используется dagger.android , который использует субкомпоненты и методы внедрения членов для внедрения @Inject-annotated полей и методов, даже когда Android создает экземпляр Fragment вне контроля Dagger.

Также обратите внимание, что Bundle - это общее хранилище значений ключей; Я использовал «arg1» и «arg2» вместо того, чтобы придумывать более креативные имена, но вы можете использовать любые строковые ключи, которые захотите. См. Bundle и его суперкласс BaseBundle , чтобы увидеть все типы данных, поддерживаемые Bundle в его get и put методах. Этот комплект также полезен для сохранения данных фрагмента; если ваше приложение прерывается телефонным звонком и Android уничтожает вашу активность для экономии памяти, вы можете использовать onSaveInstanceState, чтобы поместить данные поля формы в Bundle, а затем восстановить эту информацию в onCreate.

Наконец, обратите внимание, что вам не нужно создавать статический фабричный метод, такой как newInstance; Вы также можете попросить своих потребителей создать экземпляр new YourFragment() и передать им конкретный дизайн Bundle. Однако в этот момент структура Bundle становится частью вашего API, чего вы, возможно, не хотите. Создавая статический метод фабрики (или объект фабрики, или другую структуру), вы позволяете дизайну Bundle быть деталью реализации вашего фрагмента и предоставляете потребителям документированную и хорошо сохраняемую структуру для создания новых экземпляров.

...