Как сохранить и повторно использовать один и тот же экземпляр фрагментов?
Я недавно начал использовать фрагменты создали демо-приложение, которое выглядит так:
нажатие на каждую кнопку переключается между фрагментом 1, фрагментом 2 и фрагментом 3.
то, что я пытаюсь сделать, это иметь только 1 экземпляр каждого фрагмента и повторного использования, что. (Обратите внимание, что все фрагменты создаются и добавляются динамически). В настоящее время я делаю это, создавая HashMap фрагмента и помещая каждый экземпляр и вытаскивали его оттуда.
Итак, мои вопросы:
Есть ли лучший способ сделать это:
Используя putFragment FragmentManager(...) метод? putFragment (Bundle bundle, String key, Fragment fragment)
Я не могу выяснить, как использовать его в моем случае. Если кто-нибудь может дать мне пример, как использовать этот метод.
дорого ли держать ссылку на каждый фрагмент в моей деятельности? Это сохраняет все фрагменты живыми? Я использую мягкую ссылку для решения этой проблемы, но я не уверен, что это правильный способ сделать это. Пожалуйста, укажите мне любой альтернативный способ сделать это или дайте мне знать, если это лучший способ сделать это.
спасибо заранее.
вот мой код:
обновление: Я пытаюсь повторно использовать фрагменты из заднего стека, пытаясь добавить их, только если он не существует в заднем стеке. Код ниже дает мне исключение незаконного состояния после перехода от фрагмента один - > вернуться к нему - > затем попробуйте нажать назад кнопка:
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;
}
}
}
2 ответов
демонстрация 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;
}
}
Это позволит вам легко переходить от одного фрагмента к другому.
FragmentManager выполняет собственное управление памятью. Он будет убивать / воссоздавать или хранить в памяти ваши экземпляры в соответствии с его логикой. Вы можете убедиться, что состояние вашего фрагмента сохранено с помощью onSaveInstanceState()
или вы можете заставить систему сохранить ваш экземпляр в живых с помощью setRetainInstance(true)
на ваш фрагмент.
вот как вы создаете транзакцию.
FragmentTransaction fragmentTransaction = context.getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.layout, new MyFragment(), f.getClass().getName());
fragmentTransaction.commit();