Подтвердить что ты не робот

Android: Лучше ли создавать новый фрагмент каждый раз при щелчке элемента навигационного элемента или загружать ранее созданные фрагменты?

Я реализую стандартный шаблон ящика навигации для Android, с примерно 10 фрагментами, которые пользователь может перейти с ящика. В настоящее время я создаю новый фрагмент каждый раз, когда другой элемент навигационного элемента кликается так:

// When a new navigation item at index is clicked 
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
Fragment newFragment = null;
if (index == 0)
    fragment = new Fragment0();
...
ft.replace(R.id.container, newFragment);
ft.commit();

Мне было интересно, было бы более эффективно делать что-то вроде следующего:

// Somewhere in onCreate
Fragment[] fragments = new Fragment[n];
fragments[0] = new Fragment0();
fragments[1] = new Fragment1();
...

// When a new navigation item (at index) is clicked 
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.replace(R.id.container, fragments[index]);
ft.commit();

Мое основное беспокойство заключается в том, что некоторые фрагменты содержат значительный объем данных (довольно большие списки и множество просмотров). Будут ли какие-либо проблемы с хранением всех этих фрагментов в памяти и будут ли они давать какие-либо преимущества перед созданием новых фрагментов каждый раз (кроме более быстрых переключений между фрагментами)? Есть ли общепринятое "лучшее" решение?

4b9b3361

Ответ 1

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

switch (position) {
    case 0:
        if (fragmentOne == null)
            fragmentOne = new FragmentOne();
        getSupportFragmentManager().beginTransaction().......
        break;
    case 1:
        if (fragmentTwo == null)
            fragmentTwo = new FragmentTwo();
        getSupportFragmentManager()......

FragmentOne и FragmentTwo - это два разных класса фрагментов, а фрагмент - один и фрагмент - это их объекты, объявленные как поля в MainActivity

Edit

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

//somewhere in onCreate
if (savedInstanceState == null) {
    selectItem(defaultFragment);
}
else
    selectItem(selectedFragment);
//selectItem is method called by DrawerItemClickListener as well


//in selectItem: when navigation item at index is clicked, the listener calls this
switch (index) {
    case 0:
        if (fragments == null) {
            fragments = new Fragment[n];
            fragment[0] = new Fragment0();
        }
        else if (fragments[0] == null) {
            fragments[0] = new Fragment0();
        }
        break;
    ....
}
FragmentTransaction ft = fragmentManager.beginTransaction();
...
ft.replace(R.id.container, fragments[index]);
ft.commit();

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