Недавно я устал от необходимости постоянно знать ключи String
для передачи аргументов в Bundles
при создании my Fragments
. Поэтому я решил создать конструкторы для моего Fragments
, которые будут принимать параметры, которые я хотел установить, и поместить эти переменные в Bundles
с правильными клавишами String
, поэтому устраняя необходимость в других Fragments
и Activities
нужно знать эти ключи.
public ImageRotatorFragment() {
super();
Log.v(TAG, "ImageRotatorFragment()");
}
public ImageRotatorFragment(int imageResourceId) {
Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");
// Get arguments passed in, if any
Bundle args = getArguments();
if (args == null) {
args = new Bundle();
}
// Add parameters to the argument bundle
args.putInt(KEY_ARG_IMAGE_RES_ID, imageResourceId);
setArguments(args);
}
И затем я вывожу эти аргументы, как обычно.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "onCreate");
// Set incoming parameters
Bundle args = getArguments();
if (args != null) {
mImageResourceId = args.getInt(KEY_ARG_IMAGE_RES_ID, StaticData.getImageIds()[0]);
}
else {
// Default image resource to the first image
mImageResourceId = StaticData.getImageIds()[0];
}
}
Тем не менее, Линт принял решение об этом, заявив, что не имеет подклассов Fragment
с конструкторами с другими параметрами, требуя, чтобы я использовал @SuppressLint("ValidFragment")
, чтобы даже запустить приложение. Дело в том, что этот код работает отлично. Я могу использовать ImageRotatorFragment(int imageResourceId)
или старый метод школы ImageRotatorFragment()
и называть setArguments()
вручную на нем. Когда Android нужно воссоздать фрагмент (изменение ориентации или низкая память), он вызывает конструктор ImageRotatorFragment()
, а затем передает тот же аргумент Bundle
с моими значениями, которые устанавливаются правильно.
Итак, я искал "предложенный" подход и вижу множество примеров, используя newInstance()
для создания Fragments
с параметрами, которые, похоже, делают то же самое, что и мой конструктор. Поэтому я сделал свой собственный, чтобы проверить его, и он работает так же безупречно, как и раньше, минус Линт, скулящий об этом.
public static ImageRotatorFragment newInstance(int imageResourceId) {
Log.v(TAG, "newInstance(int imageResourceId)");
ImageRotatorFragment imageRotatorFragment = new ImageRotatorFragment();
// Get arguments passed in, if any
Bundle args = imageRotatorFragment.getArguments();
if (args == null) {
args = new Bundle();
}
// Add parameters to the argument bundle
args.putInt(KEY_ARG_IMAGE_RES_ID, imageResourceId);
imageRotatorFragment.setArguments(args);
return imageRotatorFragment;
}
Я лично считаю, что использование конструкторов является гораздо более распространенной практикой, чем знание использовать newInstance()
и передавать параметры. Я считаю, что вы можете использовать эту же конструкторскую технику с Activity, и Lint не будет жаловаться на это. Итак, в основном, мой вопрос: почему Google не хочет, чтобы вы использовали конструкторы с параметрами для Fragments
?
Моя единственная догадка заключается в том, что вы не пытаетесь установить переменную экземпляра без использования Bundle
, который не будет установлен, если воссоздается Fragment
. Используя метод static newInstance()
, компилятор не даст вам доступ к переменной экземпляра.
public ImageRotatorFragment(int imageResourceId) {
Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");
mImageResourceId = imageResourceId;
}
Мне все еще не кажется, что этого достаточно, чтобы запретить использование параметров в конструкторах. Кто-нибудь еще знает об этом?