Хоча @yydl наводить вагомі причини, чому newInstance
метод краще:
Якщо Android вирішить відтворити ваш фрагмент пізніше, він викличе конструктор без аргументу вашого фрагмента. Тож перевантаження конструктора - це не рішення.
все-таки цілком можливо використовувати конструктор . Щоб зрозуміти, чому це так, спершу нам потрібно розібратися, чому саме вищевказане рішення використовується Android.
Перш ніж фрагмент можна буде використовувати, потрібен екземпляр. Android закликає YourFragment()
( конструктор без аргументів ), щоб сконструювати примірник фрагмента. Тут будь-який перевантажений конструктор, який ви пишете, буде ігнорований, оскільки Android не може знати, який з них використовувати.
За час діяльності фрагмент створюється як вище та знищується Android декілька разів. Це означає, що якщо ви введете дані в сам об’єкт фрагмента, він буде втрачений, як тільки фрагмент буде знищений.
Для вирішення проблеми Android вимагає, щоб ви зберігали дані за допомогою Bundle
(дзвінка setArguments()
), до якого потім можна отримати доступ YourFragment
. Аргументи bundle
захищені Android, а значить, гарантовано зберігаються .
Один із способів встановити цей пакет - за допомогою статичного newInstance
методу:
public static YourFragment newInstance (int data) {
YourFragment yf = new YourFragment()
/* See this code gets executed immediately on your object construction */
Bundle args = new Bundle();
args.putInt("data", data);
yf.setArguments(args);
return yf;
}
Однак конструктор:
public YourFragment(int data) {
Bundle args = new Bundle();
args.putInt("data", data);
setArguments(args);
}
може зробити те саме, що і newInstance
метод.
Звичайно, це не вдасться, і це одна з причин Android хоче, щоб ви використовували newInstance
метод:
public YourFragment(int data) {
this.data = data; // Don't do this
}
Для подальшого пояснення ось клас фрагментів Android:
/**
* Supply the construction arguments for this fragment. This can only
* be called before the fragment has been attached to its activity; that
* is, you should call it immediately after constructing the fragment. The
* arguments supplied here will be retained across fragment destroy and
* creation.
*/
public void setArguments(Bundle args) {
if (mIndex >= 0) {
throw new IllegalStateException("Fragment already active");
}
mArguments = args;
}
Зауважте, що Android просить встановити аргументи лише під час будівництва, і гарантує, що вони будуть збережені.
EDIT : Як зазначалося в коментарях @JHH, якщо ви надаєте користувальницький конструктор, який вимагає певних аргументів, Java не надасть вашому фрагменту конструктор за замовчуванням без аргументів . Тому для цього потрібно визначити конструктор no arg , який є кодом, якого ви можете уникнути newInstance
фабричним методом.
EDIT : Android більше не дозволяє використовувати перевантажений конструктор для фрагментів. Ви повинні використовувати newInstance
метод.