Отображение фрагментов при смене ориентации
Отображение фрагментов при смене ориентации
Добрый день, господа программисты!
Столкнулся с проблемкой при создании приложения, использующего фрагменты.
Загружаю в основном активити фрагменты таким образом, что последующий фрагмент замещает его предшественника. Всё бы ничего, но заметил такой баг - при смене ориентации (лайоут файлы размещения объектов при разных ориентация отличаются) на последующие фрагменты накладываются предыдущие... С чем это может быть связано и как от этого избавиться?
Столкнулся с проблемкой при создании приложения, использующего фрагменты.
Загружаю в основном активити фрагменты таким образом, что последующий фрагмент замещает его предшественника. Всё бы ничего, но заметил такой баг - при смене ориентации (лайоут файлы размещения объектов при разных ориентация отличаются) на последующие фрагменты накладываются предыдущие... С чем это может быть связано и как от этого избавиться?
- Mikhail_dev
- Сообщения: 2386
- Зарегистрирован: 09 янв 2012, 14:45
- Откуда: Самара
Re: Отображение фрагментов при смене ориентации
покажите как вы добавляете/заменяете фрагменты
Re: Отображение фрагментов при смене ориентации
Mikhail_dev,
в MainActivity в методе OnCreate следующее:
Т.е. при создании activity изначально загружается fragment Primary.
Далее из фрагмента Primary вызывается с заменой один из двух фрагментов следующим образом:
Во фрагменте Primary:
Код в MainActivity. Заменяем в зависимости от значения фрагмент Primary на фрагменты Info либо List:
Вот как-то так... При всём при этом фрагмент Primary при повороте экрана раз за разом загружается вновь.
в MainActivity в методе OnCreate следующее:
Код: Выделить всё
Fragment frag1 = new Primary();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.frag_field, frag1);
ft.commit();
Далее из фрагмента Primary вызывается с заменой один из двух фрагментов следующим образом:
Во фрагменте Primary:
Код: Выделить всё
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_info:
someEventListener.someEvent("Info");
break;
case R.id.btn_list:
someEventListener.someEvent("List");
break;
}
return;
}
Код: Выделить всё
public void someEvent(String s) {
if (s == "Info") {
Fragment frag1 = new Info();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frag_field, frag1);
ft.commit();
}
if (s == "List") {
Fragment frag1 = new List();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frag_field, frag1);
ft.commit();
}
}
Re: Отображение фрагментов при смене ориентации
onClick() у тебя вообще не отрабатывает, как должен. Потому что
"Info".equals(s)
"List".equals(s)
В onCreate() нужно не просто добавлять фрагмент, а сначала проверить существование фрагмента и создавать его, если его нет. Иначе, при каждом повороте экрана создается новый экземпляр фрагмента и добавляется к активности.
"Info".equals(s)
"List".equals(s)
В onCreate() нужно не просто добавлять фрагмент, а сначала проверить существование фрагмента и создавать его, если его нет. Иначе, при каждом повороте экрана создается новый экземпляр фрагмента и добавляется к активности.
Re: Отображение фрагментов при смене ориентации
Dark67,
Что-то моего уровня знаний не хватает, на самом деле, чтобы понять, что делать с "Info".equals(s) и "List".equals(s) чтобы всё работало корректно (где это и что это). Подскажите пожалуйста...
И, если не трудно, наведите на мысль, как реализовать сравнение в OnCreate() фрагментов... Метод или хотябы литературу на эту тему... Спасибо за помощь.
Что-то моего уровня знаний не хватает, на самом деле, чтобы понять, что делать с "Info".equals(s) и "List".equals(s) чтобы всё работало корректно (где это и что это). Подскажите пожалуйста...
И, если не трудно, наведите на мысль, как реализовать сравнение в OnCreate() фрагментов... Метод или хотябы литературу на эту тему... Спасибо за помощь.
Re: Отображение фрагментов при смене ориентации
Сравнение строк выполняется с помощью метода equals(). То есть нужно писать не
s == "Info" , а
"Info".equals(s) (здесь впереди находится строка "Info" для того, чтобы избежать исключения NullPointerException в случае если (s == null) ).
А по поводу присоединения фрагмента к активности
[syntax=java]
FragmentManager fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = new YourFragment();
fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
}[/syntax]
Если же используется фрагмент из библиотеки поддержки (support library), то нужно вызывать метод getSupportFragmentManager().
Этот код перед тем как добавить фрагмент в контейнер, сначала проверит существует ли в системе нужный фрагмент.
s == "Info" , а
"Info".equals(s) (здесь впереди находится строка "Info" для того, чтобы избежать исключения NullPointerException в случае если (s == null) ).
А по поводу присоединения фрагмента к активности
[syntax=java]
FragmentManager fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = new YourFragment();
fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
}[/syntax]
Если же используется фрагмент из библиотеки поддержки (support library), то нужно вызывать метод getSupportFragmentManager().
Этот код перед тем как добавить фрагмент в контейнер, сначала проверит существует ли в системе нужный фрагмент.
Re: Отображение фрагментов при смене ориентации
Dark67,
Спасибо большое за толковое объяснение. Всё понял!
Спасибо большое за толковое объяснение. Всё понял!
Re: Отображение фрагментов при смене ориентации
Верну немного тему к жизни...
В своё время мне очень помогли ваши советы, в том числе и с проверкой, создан ли фрагмент в активити при запуске... Сейчас же столкнулся с проблемой посерьёзнее - что если фрагменты в горизонтальном положении и в вертикальном - разные (различные компоновки)? На сегодняшний день, при повороте экрана у меня вылетает ошибка FATAL ERROR в MainActivity с проверкой, представленной в этой теме.
В своё время мне очень помогли ваши советы, в том числе и с проверкой, создан ли фрагмент в активити при запуске... Сейчас же столкнулся с проблемой посерьёзнее - что если фрагменты в горизонтальном положении и в вертикальном - разные (различные компоновки)? На сегодняшний день, при повороте экрана у меня вылетает ошибка FATAL ERROR в MainActivity с проверкой, представленной в этой теме.
Re: Отображение фрагментов при смене ориентации
Полное описание ошибки в студию!
- Mikhail_dev
- Сообщения: 2386
- Зарегистрирован: 09 янв 2012, 14:45
- Откуда: Самара
Re: Отображение фрагментов при смене ориентации
А ничего. Создайте в обоих XML файлах контейнеры с одинаковым id, куда будете добавлять фрагмент. Падает наверное потому что у вас id (fragment_container) не во всех XML файлах есть?Сейчас же столкнулся с проблемой посерьёзнее - что если фрагменты в горизонтальном положении и в вертикальном - разные (различные компоновки)?
И еще, используйте .replace для добавления фрагмента, а не .add
Re: Отображение фрагментов при смене ориентации
Посмотрел, контейнеры и существуют и совпадают по id как в вертикальной компоновке, так и в land. Поменял add на replace - та же фигня... При том использую replace и до этого использовал при замещении фрагментов в дальнейшем. Самое что интересное - проблема существует только с первым, заглавным фрагментом, который я и вставляю при проверке. Последующие фрагменты при смене ориентации ведут себя нормально.
Лог ошибки:
08-09 11:35:09.259: E/AndroidRuntime(14781): FATAL EXCEPTION: main
08-09 11:35:09.259: E/AndroidRuntime(14781): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.friends_home/com.example.memodtp.MainActivity}: java.lang.NullPointerException
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2121)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2146)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3590)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.access$800(ActivityThread.java:140)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.os.Handler.dispatchMessage(Handler.java:99)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.os.Looper.loop(Looper.java:137)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.main(ActivityThread.java:4944)
08-09 11:35:09.259: E/AndroidRuntime(14781): at java.lang.reflect.Method.invokeNative(Native Method)
08-09 11:35:09.259: E/AndroidRuntime(14781): at java.lang.reflect.Method.invoke(Method.java:511)
08-09 11:35:09.259: E/AndroidRuntime(14781): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
08-09 11:35:09.259: E/AndroidRuntime(14781): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
08-09 11:35:09.259: E/AndroidRuntime(14781): at dalvik.system.NativeStart.main(Native Method)
08-09 11:35:09.259: E/AndroidRuntime(14781): Caused by: java.lang.NullPointerException
08-09 11:35:09.259: E/AndroidRuntime(14781): at com.example.memodtp.Primary.onCreateView(Primary.java:43)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:829)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1017)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1806)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.Activity.performCreate(Activity.java:5191)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2085)
08-09 11:35:09.259: E/AndroidRuntime(14781): ... 12 more
Лог ошибки:
08-09 11:35:09.259: E/AndroidRuntime(14781): FATAL EXCEPTION: main
08-09 11:35:09.259: E/AndroidRuntime(14781): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.friends_home/com.example.memodtp.MainActivity}: java.lang.NullPointerException
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2121)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2146)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3590)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.access$800(ActivityThread.java:140)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.os.Handler.dispatchMessage(Handler.java:99)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.os.Looper.loop(Looper.java:137)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.main(ActivityThread.java:4944)
08-09 11:35:09.259: E/AndroidRuntime(14781): at java.lang.reflect.Method.invokeNative(Native Method)
08-09 11:35:09.259: E/AndroidRuntime(14781): at java.lang.reflect.Method.invoke(Method.java:511)
08-09 11:35:09.259: E/AndroidRuntime(14781): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
08-09 11:35:09.259: E/AndroidRuntime(14781): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
08-09 11:35:09.259: E/AndroidRuntime(14781): at dalvik.system.NativeStart.main(Native Method)
08-09 11:35:09.259: E/AndroidRuntime(14781): Caused by: java.lang.NullPointerException
08-09 11:35:09.259: E/AndroidRuntime(14781): at com.example.memodtp.Primary.onCreateView(Primary.java:43)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:829)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1017)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1806)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.Activity.performCreate(Activity.java:5191)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
08-09 11:35:09.259: E/AndroidRuntime(14781): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2085)
08-09 11:35:09.259: E/AndroidRuntime(14781): ... 12 more
Re: Отображение фрагментов при смене ориентации
по ссылке в подписи
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Отображение фрагментов при смене ориентации
Чтобы фрагмент пережил смену ориентации, в его код добавляют setRetainInstance(true)
метод replace() нужен для смены одного фрагмента другим. Тебе же надо восстанавливать состояние существующего фрагмента.
А вообще, почитай про жизненные циклы фрагментов и активити.
Кстати, у тебя фрагмент прописан в XML? (Всмысле, в коде разметки активити)
метод replace() нужен для смены одного фрагмента другим. Тебе же надо восстанавливать состояние существующего фрагмента.
А вообще, почитай про жизненные циклы фрагментов и активити.
Кстати, у тебя фрагмент прописан в XML? (Всмысле, в коде разметки активити)
Re: Отображение фрагментов при смене ориентации
контейнер для вставки фрагмента в xml activity прописан...
Спасибо большое за информацию, почитаю углублённее о жизненных циклах фрагментов... и попробую использовать предложенное)
Спасибо большое за информацию, почитаю углублённее о жизненных циклах фрагментов... и попробую использовать предложенное)
Re: Отображение фрагментов при смене ориентации
Zammm
Вот тебе человек написал. поправь это изменение, и снимет все, как рукой. (Если проблемой остается налаживание фрагментов один на один)И еще, используйте .replace для добавления фрагмента, а не .add
- Mikhail_dev
- Сообщения: 2386
- Зарегистрирован: 09 янв 2012, 14:45
- Откуда: Самара
Re: Отображение фрагментов при смене ориентации
не снимет. я просто указал на то, как лучше делать, а ошибка у него в другом. foenix ему верно написала.
Re: Отображение фрагментов при смене ориентации
Большущее спасибо всем за потраченное на вразумление время! Вы мне очень помогли - ошибка NPE по foenix была в методе OnCreate в коде заглавного фрагмента:
Одна из объявленных buttton не совпадала по id с существующей button в xml фрагмента для land. После устранения этой нелепой оплошности всё заработало как часы!
Получилось как со студентом, который может, но недостаточно усердно занимается. Ошибся, а после недостаточно приложил усилий для реабилитации.
Одна из объявленных buttton не совпадала по id с существующей button в xml фрагмента для land. После устранения этой нелепой оплошности всё заработало как часы!
Получилось как со студентом, который может, но недостаточно усердно занимается. Ошибся, а после недостаточно приложил усилий для реабилитации.