it-roy-ru.com

Почему я хочу избежать нестандартных конструкторов во фрагментах?

Я создаю приложение с Fragments и в одном из них я создал конструктор не по умолчанию и получил это предупреждение:

Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead

Может кто-нибудь сказать мне, почему это не очень хорошая идея?

Можете ли вы также предложить, как я мог бы сделать это:

public static class MenuFragment extends ListFragment {
    public ListView listView1;
    Categories category;

    //this is my "non-default" constructor
    public MenuFragment(Categories category){
        this.category = category;
    }....

Без использования конструктора не по умолчанию?

160
BlackHatSamurai

Создайте объект связки и вставьте ваши данные (в данном примере это ваш объект Category). Будьте осторожны, вы не можете передать этот объект непосредственно в пакет, если он не сериализуем. Я думаю, что лучше построить свой объект во фрагменте и поместить в связку только идентификатор или что-то еще. Это код для создания и прикрепления пакета:

Bundle args = new Bundle();
args.putLong("key", value);
yourFragment.setArguments(args);

После этого в вашем фрагменте получите доступ к данным:

Type value = getArguments().getType("key");

Это все.

105
nistv4n

Кажется, что ни один из ответов на самом деле не отвечает "зачем использовать пакет для передачи параметров, а не конструкторы по умолчанию"

Причина, по которой вам следует передавать параметры через пакет, заключается в том, что когда система восстанавливает fragment (например, при изменении конфигурации), она автоматически восстанавливает ваше bundle.

Обратные вызовы, такие как onCreate или onCreateView, должны считывать параметры из bundle - таким образом вы гарантированно корректно восстановите состояние fragment в то же состояние, с которым инициализировано fragment (обратите внимание, что это состояние может отличаться от onSaveInstanceState bundle, который передается в onCreate/onCreateView)

Рекомендация по использованию статического метода newInstance() - это просто рекомендация. Вы можете использовать конструктор не по умолчанию, но убедитесь, что вы заполняете параметры инициализации в bundle внутри тела этого конструктора. И прочитайте эти параметры в методах onCreate() или onCreateView().

229
numan salati

Ваше Fragment не должно иметь конструкторов из-за того, как FragmentManager его создает. У вас должен быть статический метод newInstance(), определенный с нужными вам параметрами, затем связать их и установить их в качестве аргументов фрагмента, к которому вы позже сможете обратиться с помощью параметра Bundle.

Например:

public static MyFragment newInstance(int title, String message) {
    MyFragment fragment = new MyFragment();
    Bundle bundle = new Bundle(2);
    bundle.putInt(EXTRA_TITLE, title);
    bundle.putString(EXTRA_MESSAGE, message);
    fragment.setArguments(bundle);
    return fragment ;
}

И прочитайте эти аргументы в onCreate:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    title = getArguments().getInt(EXTRA_TITLE);
    message = getArguments().getString(EXTRA_MESSAGE);

    //...
}

Таким образом, при отсоединении и повторном присоединении состояние объекта может быть сохранено с помощью аргументов, во многом как bundles, прикрепленное к Intents.

47
Asaf Pinhassi

Если вы используете параметр для какого-то класса. попробуй это

SomeClass mSomeInstance;
public static final MyFragment newInstance(SomeClass someInstance){
    MyFragment f = new MyFragment();
    f.mSomeInstance = someInstance;
    return f;
}
12
김동기

Я думаю, что нет никакой разницы между статическим конструктором и двумя конструкторами (пустым и параметризованным, который хранит аргументы в пакете аргументов фрагмента), скорее всего, это практическое правило создано, чтобы уменьшить вероятность того, что вы забудете реализовать конструктор без аргументов в Java , который неявно генерируется при наличии перегрузки.

В своих проектах я использую Kotlin и реализую фрагменты с помощью основного конструктора без аргументов и вторичного конструктора для аргументов, которые просто сохраняют их в пакет и устанавливают в качестве аргументов фрагмента, все работает нормально.

1
Pavlus