Создание фрагмента: конструктор против newInstance()


мне в последнее время надоело постоянно знать String ключи для передачи аргументов в Bundles при создании 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() и проходя параметры. Я считаю, что вы можете использовать эту же технику конструктора с действиями, и Линт не будет жаловаться на это. так что в основном мой вопрос, почему Google не хочет, чтобы вы использовали конструкторы с параметрами для Fragments?

я только предполагаю, что вы не пытаетесь установить переменную экземпляра без использования Bundle, который не будет установлен, когда Fragment пересоздался. С помощью static newInstance() метод, компилятор не позволит вам получить доступ к переменной экземпляра.

public ImageRotatorFragment(int imageResourceId) {
    Log.v(TAG, "ImageRotatorFragment(int imageResourceId)");

    mImageResourceId = imageResourceId;
}

я все еще не чувствую, что это достаточная причина, чтобы запретить использование параметров в конструкторах. Кто - нибудь еще имеет представление об этом?

2 54

2 ответа:

Я лично считаю, что использование конструкторов является гораздо более распространенной практикой, чем использование newInstance() и передача параметров.

на заводской метод pattern используется довольно часто в современной разработке программного обеспечения.

поэтому в основном мой вопрос, почему Google не хочет, чтобы вы использовать конструкторы с параметрами фрагментов?

вы сами ответили на свой вопрос:

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

правильно.

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

вы можете высказать свое мнение. Вы можете отключить эту проверку Линта, либо на конструкторе, либо на рабочей области.

Android только воссоздает фрагменты, которые он убивает, используя конструктор по умолчанию, поэтому любая инициализация, которую мы делаем в дополнительных конструкторах, будет потеряна.Следовательно, данные будут потеряны.