4

我有一个使用 SherlockActionBar 并通过操作栏中的 ActionItems 在动态片段之间切换的应用程序。

问题是我无法保存片段状态及其 UI 数据。

这是片段活动:

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 开关块中都遇到 NullPointerExceptions

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

而片段实例化在

 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 没有运行(因此没有保存或传递复选框数据)。

我在任何地方都没有找到关于如何从片段中正确保存 UI 数据的答案(只是通过 savedInstanceState 并不能满足我的目的),或者如何在更改片段时管理多个片段实例。我知道每次更改片段时,系统都会自动保存所有数据,但似乎无法使其正常工作。

请帮忙。

4

1 回答 1

3

这不是问题的一部分,但您应该知道保存视图状态onSaveInstanceState不需要使用。只要 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);

那样有用吗?

于 2013-07-16T10:17:44.020 回答