[英]Fragments Not Working Correctly After Orientation Change
我遇到Fragments
和方向改變的問題。
我有一個具有MainActivity
的應用程序,它通過選項卡式操作欄處理切換Fragments
。 以下是選項卡式操作欄的代碼以及選擇選項卡的時間。
private class MyTabListener <T extends android.support.v4.app.Fragment> implements ActionBar.TabListener {
private android.support.v4.app.Fragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
public MyTabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
@Override
public void onTabSelected(Tab tab, android.support.v4.app.FragmentTransaction ft) {
if (mFragment == null){ // check to see if the fragment has already been initialised. If not create a new one.
mFragment = android.support.v4.app.Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content,mFragment,mTag);
} else {
ft.attach(mFragment); // if the fragment has been initialised attach it to the current activity
}
}
@Override
public void onTabUnselected(Tab tab, android.support.v4.app.FragmentTransaction ft) {
if (mFragment != null){
ft.detach(mFragment); // when a fragment is no longer needed, detach it from the activity but dont destroy it
}
}
@Override
public void onTabReselected(Tab tab, android.support.v4.app.FragmentTransaction ft) {
}
我看到的方式是,當應用程序首次以縱向模式加載時,一切正常。 當我旋轉時,由於某種原因添加了另一個Fragment1
實例,然后在選擇另一個選項卡時不會分離。 當我然后旋轉回肖像時也是這種情況。
我嘗試過使用setRetainInstance(true);
在我的Fragments
但這不起作用。
是否有一種方法需要在旋轉之前覆蓋或對我的Fragments
做一些事情?
提前致謝。
編輯我現在已經看到在重新創建活動時再次調用onTabSelected。 這可能是我的問題的原因,片段連接不止一次?
這是我的活動onCreate方法。
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
//setContentView(R.layout.main);
}
// Create the Action Bar with tabs
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(false);
//create the tab for track and add it to the action bar.
Tab tab = actionBar.newTab()
.setText("Track")
.setTabListener(new MyTabListener<TrackingFragment>(this,"track",TrackingFragment.class));
actionBar.addTab(tab);
//create the tab for ski tracks and add it to the action bar.
tab = actionBar.newTab()
.setText("Something Tracks")
.setTabListener(new MyTabListener<TrackListFragment>(this,"somethingtracks",TrackListFragment.class));
actionBar.addTab(tab);
//create the tab for photos and add it to the action bar.
tab = actionBar.newTab()
.setText("Photos")
.setTabListener(new MyTabListener<PhotoFragment>(this,"photos",PhotoFragment.class));
actionBar.addTab(tab);
簡短修復:
在onTabSelected
方法中,在使用if (mFragment == null)
您需要嘗試獲取片段(使用mFragment = getSupportFragmentManager().findFragmentByTag(mTag)
)。 你也可以從外面設置這個,但我不認為你這樣做。
檢查onCreate
上if(savedInstanceState == null)
也可以解決這個問題,我認為這是一個更好的方法! :)
聽起來你的onCreate
方法中沒有包含在if(savedInstanceState == null)
,所以除了從savedInstanceState包中恢復的片段之外,你還要創建另一個片段。
編輯
仔細查看你的代碼,我認為我對onCreate有誤,你的onTabSelected應該處理它。 我認為你的if (mFragment == null)
總是為null,因為你沒有嘗試找到片段。 將該代碼部分更改為:
@Override
public void onTabSelected(Tab tab, android.support.v4.app.FragmentTransaction ft) {
mFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag); // add this
if (mFragment == null){ // check to see if the fragment has already been initialised. If not create a new one.
mFragment = android.support.v4.app.Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content,mFragment,mTag);
} else {
ft.attach(mFragment); // if the fragment has been initialised attach it to the current activity
}
}
我發現實際上忽略了setRetainInstance
,並且android.support.v4.app.FragmentManager
創建的所有片段都存儲在onSaveInstanceState
,並在onCreate
中重新創建。
對我來說,解決方案是直截了當地刪除多余的片段: https : //stackoverflow.com/a/13996054/341091
我或多或少有同樣的問題,但上面提到的解決方案在我的情況下似乎沒有成功。 最終我找到了以下解決方案:
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.replace(android.R.id.content, mFragment, mTag); // Use replace iso add
}
else {
ft.attach(mFragment);
}
}
if(savedInstanceState == null)始終不起作用。 有時savedInstanceState!= null,因為橫向方向需要添加另一個片段。
另一種方法是測試fm.findFragmentById(R.id.frameLayoutLeft),無論方向是什么,是否為null,如果是,則創建新的片段實例,否則什么都不做。 如果在橫向模式下需要第二個片段,則首先需要檢查它是否為橫向,如果是,請檢查fm.findFragmentById(R.id.frameLayoutRight)是否為空。 如果為null,則為create,否則不執行任何操作,因為它已經由Android OS保留。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.