Хотя @yydl дает убедительную причину того, почему метод newInstance
лучше:
Если Android решит позже воссоздать ваш фрагмент, он будет вызывать конструктор без аргументов вашего фрагмента.,Таким образом, перегрузка конструктора не является решением.
все еще вполне возможно использовать конструктор .Чтобы понять, почему это так, сначала нам нужно выяснить, почему вышеупомянутый обходной путь используется Android.
Прежде чем можно будет использовать фрагмент, необходим экземпляр.Android вызывает YourFragment()
(конструктор без аргументов ), чтобы создать экземпляр фрагмента.Здесь любой перегруженный конструктор, который вы напишите, будет игнорироваться, так как Android не может знать, какой из них использовать.
Во время жизни действия фрагмент создается, как описано выше, и несколько раз уничтожается Android.Это означает, что если вы поместите данные в сам объект фрагмента, они будут потеряны после уничтожения фрагмента.
Чтобы обойти эту проблему, Android попросит вас сохранить данные, используя Bundle
(вызов setArguments()
),к которому можно получить доступ из YourFragment
.Аргумент bundle
s защищен Android, и, следовательно, гарантированно будет persistent .
Один из способов установить этот пакет - использовать статический метод 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 .Так что для этого потребуется определить конструктор no arg , который можно избежать с помощью фабричного метода newInstance
.
EDIT : Android не делает 'Больше нельзя использовать перегруженный конструктор для фрагментов.Вы должны использовать метод newInstance
.