2013-07-04 53 views
4

我有一個應用程序使用SherlockActionBar並通過操作欄中的ActionItems在動態片段之間切換。無法通過改變方向保留片段或保存片段UI

問題是我無法保存片段狀態及其UI數據。

這是FragmentActivity:

public class MainActivity extends SherlockFragmentActivity { 

private LocationFragment locationFragement; 
private HomeFragment homeFragment; 
private SettingsFragment settingsFragment; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    ActionBar actionBar = getSupportActionBar(); 
    actionBar.setDisplayShowTitleEnabled(false); 


    locationFragement = new LocationFragment(); 
    homeFragment = new HomeFragment(); 
    settingsFragment = new SettingsFragment(); 

} 

@Override 
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) { 
    getSupportMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 



@Override 
public boolean onOptionsItemSelected(MenuItem item) { 

    FragmentManager fragManager = getSupportFragmentManager(); 
    FragmentTransaction fragTransaction = fragManager.beginTransaction(); 

    switch (item.getItemId()){ 

    case R.id.home: 

     fragTransaction.replace(android.R.id.content, homeFragment);    
     break; 

    case R.id.location: 

     fragTransaction.replace(android.R.id.content, locationFragement); 
     break; 

    case R.id.settings: 

     fragTransaction.replace(android.R.id.content, settingsFragment); 
     break; 

    } 
    fragTransaction.commit(); 
    return true; 
} 

首先,我試圖打電話到片段的單個實例,只有每次我在onOptionsItemSelected開關塊

fragTransaction.replace(android.R.id.content, myFragmentClassName); 

確實遇到NullPointerExceptions的而片段實例化在

if(savedInstanceState == null){ 
     locationFragement = new LocationFragment(); 
     homeFragment = new HomeFragment(); 
     settingsFragment = new SettingsFragment(); 
     } 

碎片不會在方向改變的情況下創建,我也無法確定它是否可以讓它們實例化。所以我決定每創建一個onCreate(這是壞的,但我想要的東西工作),並保存UI數據只是爲了傳回給片段。

這是一個片段,其他2是相同的:

public class LocationFragment extends SherlockFragment { 

private View myView; 
private CheckBox myCheckBok; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    setRetainInstance(true); 
    Log.d("LocationFragment", "onCreate running"); 
    super.onCreate(savedInstanceState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    Log.d("LocationFragment", "onCreateView running"); 

    myView = inflater.inflate(R.layout.map_fragment, container, false); 
    myCheckBok = (CheckBox) myView.findViewById(R.id.mapFragmentCheckBox); 

    if(savedInstanceState != null){ 
     myCheckBok.setChecked(savedInstanceState.getBoolean("isChecked")); 
    } 

    return myView; 

} 

@Override 
public void onResume() 
{ 
    Log.d("LocationFragment", "onResume running"); 
    super.onResume(); 
} 

@Override 
public void onPause() { 

    Log.d("LocationFragment", "onPause running"); 

    super.onPause(); 

} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    boolean isChecked = myCheckBok.isChecked();  
    outState.putBoolean("isChecked", isChecked); 

    Log.d("LocationFragment", "onSaved Instant running"); 

    super.onSaveInstanceState(outState); 
} 

我節省的複選框的狀態,當我通過複選框狀態保存圖標並通過方向改變。但是,當我改變方向時,按另一個圖標(或按相同的一個)並返回到我的片段,狀態不會保存。我意識到這是由於onSavedInstanceState沒有運行時,我改變到另一個片段(因此不保存或傳遞checkBox數據)。

我還沒有找到答案的任何地方如何從片段正確保存UI數據(只是通過savedInstanceState不會削減它爲我的目的),或如何管理幾個片段實例化,同時改變它們。我知道,每當我更換一個片段時,系統會自動保存所有數據 ,但似乎無法使其工作。

請幫忙。

+0

爲什麼不使用Tablistener有什麼特別的原因:onTabSelected/onTabUnselected?我將我的數據保存在共享的首選項中,我的方法似乎正常工作。Google文檔對此很好,同樣適用於ABS:http://developer.android.com/guide/topics/ui/actionbar.html – IanB

+0

@IanB感謝您的評論。它確實發生在我最初使用標籤,我知道它的工作原理。共享首選項是一個好主意。不幸的是,這仍然沒有直接解決我的問題,如何使用操作項目作爲改變片段的手段。也許我的整個方法是錯誤的,我應該堅持製表符。 – peresisUser

+0

此外,我無法控制動作欄將在哪裏找到選項卡:在橫向上,選項卡將位於同一個欄上,在縱向上它們將佔用另一行。我需要將所有圖標放在同一行上。 – peresisUser

回答

2

這不是問題的一部分,但您應該意識到使用onSaveInstanceState不需要saving a View狀態。只要有視圖的ID,Android就已經爲你做了。

看起來像你面臨的問題是你沒有恢復從他們的FragmentManager片段。碎片在那裏,但你只是沒有去FragmentManager並帶來他們一旦onCreate再次發生。

此代碼應走在onCreate

// Try and fetch the fragments from the manager 
    locationFragement = fragmentManager.findFragmentByTag(LOCATION_FRAGMENT_TAG); 
    homeFragment = fragmentManager.findFragmentByTag(HOME_FRAGMENT_TAG); 
    settingsFragment = fragmentManager.findFragmentByTag(SETTINGS_FRAGMENT_TAG); 

    // If the fragment weren't found - meaning it's the first time the activity was 
    // started, create them 
    if (locationFragement == null) locationFragement = new LocationFragment(); 
    if (homeFragment == null)  homeFragment = new HomeFragment(); 
    if (settingsFragment == null) settingsFragment = new SettingsFragment(); 

而且,每當你添加/刪除/更換一個片段,一定要加他與TAG,即

// EXAMPLE HOW TO USE A REPLACE WITH A TAG 
    getSupportFragmentManager().beginTransaction().replace(android.R.id.content, 
             locationFragement, LOCATION_FRAGMENT_TAG); 

不那工作?

+0

謝謝!這大大地解決了實例的問題。 – peresisUser

+1

我不知道爲什麼我無法在SO和在線上找到關於此的更多解釋,但是您的帖子對我非常有幫助。 – Suragch

相關問題