Обработка изменений ориентации с помощью фрагментов - PullRequest
4 голосов
/ 29 мая 2011

В настоящее время я тестирую свое приложение с многоканальным Fragment представлением, используя пакет совместимости с HC, и у меня много трудностей с обработкой изменений ориентации.

Мое действие Host имеет 2 панели в альбомной ориентации (menuFrame и contentFrame) и только menuFrame в портретной ориентации, в которую загружаются соответствующие фрагменты.Если у меня есть что-то в обеих панелях, но затем изменить ориентацию на портретную, я получаю NPE, поскольку он пытается загрузить представления во фрагменте, который будет в (не существует) contentFrame.Использование метода setRetainState() во фрагменте контента не сработало.Как я могу разобраться, чтобы система не загружала фрагмент, который не будет показан?

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

Ответы [ 3 ]

3 голосов
/ 10 августа 2011

Кажется, что onCreateViewMethod вызывал проблемы;он должен возвратить ноль, если контейнер нуль:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {   
    if (container == null) // must put this in
        return null;
    return inflater.inflate(R.layout.<layout>, container, false);
}
0 голосов
/ 31 декабря 2018

Создание нового экземпляра только в первый раз.

Это помогает:
Создание нового экземпляра фрагмента при первом запуске операции, иначе повторное использованиестарый фрагмент.
Как вы можете это сделать?
FragmentManager - это ключ

Вот фрагмент кода:

if(savedInstanceState==null) {
    userFragment = UserNameFragment.newInstance();
    fragmentManager.beginTransaction().add(R.id.profile, userFragment, "TAG").commit();
}
else {
    userFragment = fragmentManager.findFragmentByTag("TAG");
}

Сохранение данных на стороне фрагмента

Если у вашего фрагмента есть EditText, TextViews или любые другие переменные класса, которые вы хотите сохранить при изменении ориентации.Сохраните его onSaveInstanceState() и получите их onCreateView() методом

Вот фрагмент кода:

// Saving State

@Override
public void onSaveInstanceState(Bundle outState) {
     super.onSaveInstanceState(outState);
     outState.putString("USER_NAME", username.getText().toString());
     outState.putString("PASSWORD", password.getText().toString());
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {

     View view = inflater.inflate(R.layout.user_name_fragment, parent, false);

     username = (EditText) view.findViewById(R.id.username);
     password = (EditText) view.findViewById(R.id.password);


     // Retriving value

     if (savedInstanceState != null) {
         username.setText(savedInstanceState.getString("USER_NAME"));
         password.setText(savedInstanceState.getString("PASSWORD"));
     }

     return view;
}

Вы можете увидеть полный рабочий код ЗДЕСЬ

0 голосов
/ 06 июня 2011

Вероятно, не идеальный ответ, но если у вас есть contentFrame для портрета и в вашей деятельности загружайте menuFrame, только когда saveInstanceState имеет значение NULL, тогда ваши фрагменты содержимого будут отображаться при изменении ориентации.

Не идеально, хотя, если вы нажмете кнопку «Назад» (столько раз, сколько необходимо), вы никогда не увидите фрагмент меню, поскольку он не был загружен в contentFrame.

Это позорчто демонстрации API FragmentLayout не сохраняют правильное состояние фрагмента при изменении ориентации.Независимо от того, что я обдумал эту проблему и попробовал разные вещи, я не уверен, что есть прямой ответ.Лучший ответ, который я придумала до сих пор (не проверено), это иметь одинаковую компоновку в портретной и альбомной ориентации, но скрывать menuFrame, когда в detailsFrame что-то есть.Аналогичным образом покажите это и скройте frameLayout, когда последний пуст.

...