2013-07-04 57 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

相关问题