[英]How to save and reuse same instance of fragments?
我最近開始使用片段創建了一個演示應用程序,如下所示:
單擊每個按鈕可在片段1,片段2和片段3之間切換。
我想要完成的是每個Fragment只有一個實例並重用它。 (請注意,所有片段都是動態創建和添加的)。 目前我這樣做是通過創建片段的HashMap並放置每個實例並從那里抓取它。
所以我的問題是:有沒有更好的方法:使用FragmentManager的putFragment(...)方法? putFragment (Bundle bundle, String key, Fragment fragment)
我無法弄清楚如何在我的情況下使用它。 如果有人能給我一個如何使用這種方法的例子。
在我的活動中保留每個片段的引用是否昂貴? 這會使所有碎片保持活力嗎? 我正在使用軟參考來解決這個問題,但我不確定這是否是正確的方法。 請指出我這樣做的任何其他方式或讓我知道這是否是實現這一目標的最佳方式。
提前致謝。
這是我的代碼:
更新 :我正在嘗試重用后端堆棧中的片段,嘗試僅在后端堆棧中不存在時添加它們。 在我離開片段1之后,下面的代碼給了我非法狀態異常 - >回到它 - >然后嘗試按下后退按鈕:
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;
}
}
}
要演示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)
強制系統使您的實例保持活動setRetainInstance(true)
。
這是您創建交易的方式。
FragmentTransaction fragmentTransaction = context.getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.layout, new MyFragment(), f.getClass().getName());
fragmentTransaction.commit();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.