39

У меня есть приложение в Honeycomb, и я использую фрагменты.
Это мое приложениеСохранять объект фрагмента во время вращения

  • У меня есть активность (Say A1) и в том, что фрагмент
  • Первоначально держать этот фрагмент объект один объект фрагмент сказать (F1)
  • Тогда в зависимости от действия пользователя может изменить на другие объекты F2, F3 ....

Что моя проблема заключается в том

Когда пользователь поворачивать устройство активность будет воссоздана и которые делают F1 в качестве объекта фрагмента, даже если перед поворотом не был
What is the way to retain the fragment object while rotating?
Я использовал setRetainInstance(true);, но он не работает для меня
И у меня есть добавлен фрагмент с помощью кода в моей onCreate функции как этот

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); 

    Fragment homeFragment = new Home(); 
    fragmentTransaction.add(R.id.mainFragement, homeFragment); 
    fragmentTransaction.commit(); 
} 

ответ

53

по умолчанию Android сохранит объекты фрагмента. В вашем коде вы устанавливаете homeFragment в своей функции onCreate. Именно поэтому всегда есть homeFragment или fl, что вы установили в onCreate.

Потому что всякий раз, когда вы поворачиваете, то OnCreate будет выполнять и установить объект фрагмента к первому

Так простое решение для вас проверить, является ли нулевым savedInstanceState расслоения или нет и установить объект фрагмента

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    if(null == savedInstanceState) { 
     // set you initial fragment object 
    } 
} 
+1

, что я должен делать в случае, если я использую активность с ViewPager, которая обрабатывает фрагменты? –

+0

@androiddeveloper молиться. Серьезно, что я сделал: super.onCreate (null); – Warpzit

+19

«По умолчанию андроид сохранит объекты фрагмента» ... не верно. Android создаст новые объекты при изменении ориентации, если не вызвано 'setRetainInstance (true)'. Не путайте это с автоматической перезагрузкой фрагментов Android. Это не одно и то же. Проверьте следы, сообщенные S.D. на [этот ответ] (http://stackoverflow.com/a/12641575/2619107). – Rafa

34

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

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    String tag = "my_fragment"; 
    FragmentManager fragmentManager = getFragmentManager(); 
    if(fragmentManager.findFragmentByTag(tag) == null) { 
     FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); 
     Fragment homeFragment = new Home(); 
     fragmentTransaction.add(R.id.mainFragement, homeFragment, tag); 
     fragmentTransaction.commit(); 
    } 
} 

Проверка ли savedInstanceState является недействительным не является безопасным способом проверить, является ли ваш фрагмент уже установлен - он будет работать в большинстве случаев, но в некоторых случаях (например, когда устройство находится на низкой памяти), Android может убить вашу активность, что может сломать ваше приложение.

Чтобы увидеть это в действии, поставьте галочку «Не держите действия» в настройках разработки устройства (параметр доступен в Android 4.0+, не уверен в более ранних версиях). Когда вы открываете новое действие, ваше первое действие уничтожается. Когда вы вернетесь к нему (нажав назад), он будет создан снова, а savedInstanceState будет не null. Однако ваш фрагмент больше не работает, и вы должны добавить его снова.

EDIT - Показаны исходный принцип, но с SupportFragmentManager

public class ActivityAwesome extends AppCompatActivity 
{ 
    private final String TAG = getClass().getSimpleName(); 
    private FragmentHome mHomeFragment; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_layout); 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     Fragment fragment = fragmentManager.findFragmentByTag(TAG); 
     if(fragment == null) 
     { 
      // Create the detail fragment and add it to the activity using a fragment transaction. 
      mHomeFragment = new FragmentHome(); 
      fragmentManager.beginTransaction() 
        .add(R.id.fragment_container, mHomeFragment, TAG) 
        .commit(); 
     } 
     else 
     { 
      // get our old fragment back ! 
      mHomeFragment = (FragmentHome)fragment; 
     } 
    } 
} 

это происходит в особенно полезно, если вы хотите, чтобы манипулировать фрагмент (в данном случае mHomeFragment) после поворота устройства

+0

Пока я использовал ответ, предоставленный @labeeb раньше, я считаю, что проверка уникального «тега» - лучший подход. –

+0

интересно! Похоже, Google нуждается в обновлении кода своего шаблона. –

0

Я определил a Fragment в макете деятельности, onSaveInstanceState в Fragment действительно вызывается, но savedInstanceStateBundle в Фрагменте onCreatView имеет значение null.

Причина заключалась в том, что мой Fragment не имеют ID в XML:

android:id="@+id/compass_fragment" ... 
3

Использование onAttachFragment() в вашем Activity переназначить объект:

@Override 
public void onAttachFragment(Fragment fragment) { 
    if (fragment instanceof MyFragment) 
     this.myFragment = (MyFragment) fragment; 
} 
Смежные вопросы