it-swarm.com.ru

Сохраните объект Fragment во время вращения

Я разработал приложение в Honeycomb, и я использую фрагменты.
Это мое приложение 

  • У меня есть активность (скажем, 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();
}
47
Jithin

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

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

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

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

    if(null == savedInstanceState) {
        // set you initial fragment object 
    }
 }
61
Labeeb Panampullan

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

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+, но не в предыдущих версиях). Когда вы открываете новое действие, ваше первое действие уничтожается. Когда вы вернетесь к нему (нажав назад), он будет создан снова, а для элемента saveInstanceState будет not null. Тем не менее, ваш фрагмент больше не находится в активности, и вы должны добавить его снова.

РЕДАКТИРОВАТЬ - Показывает оригинальный принцип, но с 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) после поворота вашего устройства

38
Ralf

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

@Override
public void onAttachFragment(Fragment fragment) {
    if (fragment instanceof MyFragment)
        this.myFragment = (MyFragment) fragment;
}
3
Oded Breiner

Вы можете просто установить свойство RetainInstance внутри OnCreate класса фрагмента.

public override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    RetainInstance = true;
}

Сохранить объект фрагмента во время вращения

0
Shawinder Sekhon

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

Причина была в том, что у моего Fragment не было идентификатора в XML:

Android:id="@+id/compass_fragment" ...
0
zomarev