Подтвердить что ты не робот

Как сохранить и повторно использовать один и тот же экземпляр фрагментов?

Я недавно начал использовать фрагменты, создал демонстрационное приложение, которое выглядит так:

Demo App

Нажатие на каждую кнопку переключается между фрагментом 1, фрагментом 2 и фрагментом 3.

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

Итак, мои вопросы: Есть ли лучший способ сделать это: С помощью метода FragmentManager putFragment (...)? putFragment (Bundle bundle, String key, Fragment fragment) Я не могу понять, как использовать его в моем случае. Если кто-нибудь может дать мне пример того, как использовать этот метод.

Стоит ли держать ссылку на каждый фрагмент в моей деятельности? Сохраняет ли это все фрагменты? Я использую мягкую ссылку для решения этой проблемы, но я не уверен, что это правильный способ сделать это. Пожалуйста, укажите мне любой альтернативный способ сделать это или сообщить мне, если это лучший способ выполнить это.

Спасибо заранее.

Вот мой код:

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

10-28 13:21:40.255: ERROR/MessageQueue-JNI(3548): java.lang.IllegalStateException: Fragment already added: FragmentOne{423db570 #0 id=0x7f050006 fragOne}

public class MainActivity extends Activity implements View.OnClickListener {

private Button btnOne;
private Button btnTwo;
private Button btnThree;

 /* Called when the activity is first created.
  */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    initialize();
    if(findViewById(R.id.fl) != null){
        if(savedInstanceState != null)
            return;
    }

    FragmentManager.enableDebugLogging(true);
    updateView("fragOne");
}

private void initialize(){
    btnOne = (Button) findViewById(R.id.button1);
    btnTwo = (Button) findViewById(R.id.button2);
    btnThree = (Button) findViewById(R.id.button3);
    btnOne.setOnClickListener(this);
    btnTwo.setOnClickListener(this);
    btnThree.setOnClickListener(this);
    fragHolder = new HashMap<String, SoftReference<Fragment>>();
}

private void updateView(String tag){
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    Fragment frag = getFragmentManager().findFragmentByTag(tag);

    boolean addToStack = true;
    if(frag == null){
        if(tag.equals("fragOne"))
            frag = new FragmentOne();    
        else if(tag.equals("fragTwo"))
            frag = new FragmentTwo();
        else if(tag.equals("fragThree"))
            frag = new FragmentThree();
    }else{
        //Don't add to back stack
        addToStack = false;
    }
    ft.replace(R.id.fl, frag, tag);
    if(addToStack)
        ft.addToBackStack(null);
    ft.commit();
}

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.button1:
                updateView("fragOne");
                break;
            case R.id.button2:
                updateView("fragTwo");
                break;
            case R.id.button3:
                updateView("fragThree");
                break;
        }
    }
}
4b9b3361

Ответ 1

Чтобы продемонстрировать FragmentTransaction, вам может быть полезен следующий пример.

Во-первых, вы хотите сделать все свои файлы инициализации в onCreate() своей деятельности, что у вас есть, но мы сделаем несколько изменений.

public class MainActivity extends Activity implements View.OnClickListener {

private Button btnOne;
private Button btnTwo;
private Button btnThree;

/* Called when the activity is first created.*/
@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    initialize();
    if(findViewById(R.id.fl) != null)
    {
        if(savedInstanceState != null)
        {
            FragmentTransaction trans = getFragmentManager().beginTransaction();

            //This is where we add our first fragment
            trans.add(R.id.fl, new FragmentOne());
            trans.commit();
        }
    }
}

private void initialize()
{
    btnOne = (Button) findViewById(R.id.button1);
    btnTwo = (Button) findViewById(R.id.button2);
    btnThree = (Button) findViewById(R.id.button3);
    btnOne.setOnClickListener(this);
    btnTwo.setOnClickListener(this);
    btnThree.setOnClickListener(this);
}

public void onClick(View view)
{
    //Here is where we'll actually transfer the fragments

    FragmentTransaction trans = getFragmentManager().beginTransaction();
    switch(v.getId()){
        case R.id.button1:
            trans.replace(R.id.fl, new FragmentOne());
            trans.addToBackStack(null);
            trans.commit();
            break;
        case R.id.button2:
            trans.replace(R.id.fl, new FragmentTwo());
            trans.addToBackStack(null);
            trans.commit();
            break;
        case R.id.button3:
            trans.replace(R.id.fl, new FragmentThree());
            trans.addToBackStack(null);
            trans.commit();
            break;
    }
}

Это позволит вам легко перейти от одного фрагмента к другому.

Ответ 2

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

Или вы можете заставить систему сохранить ваш экземпляр живым с помощью setRetainInstance(true) на вашем фрагменте.

Вот как вы создаете транзакцию.

    FragmentTransaction fragmentTransaction = context.getSupportFragmentManager().beginTransaction();
    fragmentTransaction.replace(R.id.layout, new MyFragment(), f.getClass().getName());
    fragmentTransaction.commit();