Nano Hash - криптовалюты, майнинг, программирование

Одно действие с несколькими фрагментами и ориентацией экрана

В настоящее время я решаю проблему с Android и его циклом повторного создания при повороте экрана:

У меня есть одно действие и множество фрагментов (Support-V4). Например, вход в систему выполняется в одном действии с фрагментом, когда вход в систему, приложение меняет свое поведение навигации и использует несколько фрагментов, я сделал это, потому что передача данных между фрагментом A и фрагментом B намного проще, чем передача данные между действием A и действием B.

Итак, моя проблема возникает, когда я поворачиваю устройство, при первом подходе начальный фрагмент был загружен, но что произойдет, если пользователь на странице 15 и повернет свое устройство, он вернется к фрагменту 1 и даст очень плохой пользовательский опыт. Я настроил все свои фрагменты так, чтобы они сохраняли свой экземпляр, и добавил это в MainActivity при создании:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
    initBackStackManager();
    initControllers();
    mayDownloadData();
    setTitle();
    if(savedInstanceState == null){
        addAreaFragment();
    }
}

Теперь первый фрагмент не загружается после изменения ориентации экрана, но если я пытаюсь выполнить транзакцию фрагмента, он говорит Невозможно выполнить FragmentTransaction.commit() после onSaveInstanceState(), есть ли способ справиться с этим? Или мне действительно нужно использовать несколько действий с встроенным фрагментом?

Большое спасибо!

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

AreaFragment -> WaiterSelectionFragment -> WaiterOptionsFragment.

Если я нахожусь в AreaFragment и вращаю устройство, я все равно могу добавлять/заменять фрагменты, и ничего не происходит, никакой ошибки не возникает. Если я нахожусь в WaiterSelectionFragment, ошибок тоже не возникает. НО, если я нахожусь в WaiterOptionsFragment, возникает ошибка. WaiterSelectionFragment имеет следующую структуру:

  1. LinearLayout
  2. Фрагменттабхост

Внутри FragmentTabHost есть несколько фрагменты, и именно здесь происходит ошибка. Вы можете задаться вопросом Почему FragmentTabHost? Просто клиент хочет, чтобы это приложение отображало панель вкладок. Если я использую нативные вкладки Android, вкладки перестраиваются на панель действий при Альбомная позиция.

ИЗМЕНИТЬ 2

Я использовал метод, предоставленный @AJ Macdonald, но пока безуспешно. У меня есть текущий фрагмент, сохраняемый методом onSaveInstanceState(Bundle), и я восстанавливаю свой фрагмент методом onRestoreInstanceState(Bundle) в Android Activity, я восстанавливаю кнопку назад и текущий фрагмент, но когда я добираюсь до третьего фрагмента, ошибка все еще возникает. Я использую ViewPager, который содержит 4 фрагмента. Будет ли это причиной проблемы? Только в этом разделе приложения происходит. У меня есть 4 (основной рабочий процесс) фрагмента, в первом, втором и третьем фрагменте нет ошибок, которые он представляет, только на ViewPager.


  • В какой момент вы пытаетесь зафиксировать транзакцию? Это во время обратного вызова жизненного цикла Activity, такого как onPause или onStop? 26.06.2014
  • Нет, у меня есть фрагмент, который использует FragmentTabHost, когда устройство вращается, он показывает фрагмент с сеткой, и пользователь выбирает ячейку, а затем добавляется новый фрагмент, и это не тот момент, когда он использует FragmentTransaction.commit () 26.06.2014

Ответы:


1

Дайте каждому из ваших фрагментов уникальный тег.

В вашей деятельности onSaveInstanceState сохраните текущий фрагмент. (Это, вероятно, будет проще всего сделать, если вы сохраните переменную, которая автоматически обновляется каждый раз, когда изменяется фрагмент.)

В вашей активности onCreate или onRestoreInstanceState вытащите тег из сохраненного пакета и запустите новый фрагмент этого типа.

public static final int FRAGMENT_A = 0;
public static final int FRAGMENT_B = 1;

private int currentFragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //other stuff
    if(savedInstanceState == null){
        addAreaFragment();
        currentFragment = FRAGMENT_A;
    }else{
        currentFragment = savedInstanceState.getInt("currentFragment");
        switch(currentFragment){
        case FRAGMENT_A:        
        addAreaFragment();
        break;
        case FRAGMENT_B:
        addFragmentB();
        }
    }
}


// when you switch fragment A for fragment B:
currentFragment = FRAGMENT_B;


@Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        savedInstanceState.putInt("currentFragment", currentFragment);
        super.onSaveInstanceState(savedInstanceState);
    }
26.06.2014
  • Я использую имя класса в качестве тега фрагмента. Но... Например, для запуска Фрагмента B некоторые данные передаются через статический метод newInstance(...). Также задний стек будет потерян, верно? 26.06.2014
  • Если данные, которые вы передаете фрагменту B, относятся к примитивному типу, вы также можете попробовать сохранить их в пакет saveInstanceState. Я не могу придумать простого способа сделать это с непримитивным объектом. Я думаю, что backstack будет потерян при воссоздании активности. Возможно, вы сможете сохранить в пакете ArrayList‹String› с тегами всех фрагментов обратного стека... затем в onCreate используйте этот список для повторного создания всех фрагментов, заменяя их по порядку и добавляя их обратно на backstack, как вы идете. 26.06.2014
  • Я собираюсь попробовать использовать ваш ответ, надеюсь, он сработает... Пожалуйста, посмотрите мой отредактированный пост. 26.06.2014
  • Если вы попытаетесь использовать ArrayList для хранения тегов обратного стека, будет лучше, если вы также удалите теги из списка, если пользователь нажмет кнопку «Назад»… к сожалению, я думаю, что может не быть способа обнаружить кнопку «Назад». нажмите, чтобы это произошло. Так что я не уверен, насколько это отличная идея в целом. 26.06.2014
  • Это просто, мы могли бы использовать OnBackStackChangeListener, чтобы определить, когда фрагмент был добавлен/удален.! 26.06.2014
  • Ницца! И тогда вы сможете использовать getBackStackEntryCount() для удаления только последнего элемента в ArrayList. 26.06.2014

  • 2

    Предлагаем попробовать использовать FragmentTransaction.commitAllowingStateLoss() вместо FragmentTransaction.commit(). Это должно предотвратить создание исключения, но недостатком является то, что если вы снова повернете устройство, самое последнее состояние пользовательского интерфейса может не вернуться. Это предположение, учитывая, что я не уверен в эффекте использования FragmentTabHost, если он вообще имеет какой-либо эффект.

    26.06.2014
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..


    © 2024 nano-hash.ru, Nano Hash - криптовалюты, майнинг, программирование