我正在使用ADT在创建使用Dropdown ActionBar的应用程序时创建的默认代码。
问题是我无法保留我的片段视图状态,因为每次在下拉菜单中设置所选项目时都会创建一个新的Fragment实例。
当用户更改选择时,这没关系。问题是设备旋转时。我无法避免重新创建菜单,它必须再次设置所选项目。
我只是不知道如何避免在所选项目未更改时(例如更改方向时)创建新片段实例(并替换旧片段实例)。
这是我的MainActivity代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity_layout);
// Set up the action bar to show a dropdown list.
final ActionBar actionBar = getActionBar();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
// Set up the dropdown list navigation in the action bar.
actionBar.setListNavigationCallbacks( new ArrayAdapter<String>(getActionBarThemedContextCompat(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
getResources().getStringArray(R.array.main_menu_array)), this);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Restore the previously serialized current dropdown position.
if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
// Serialize the current dropdown position.
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar().getSelectedNavigationIndex());
}
@Override
public boolean onNavigationItemSelected(int position, long id) {
String[] array = getResources().getStringArray(R.array.main_menu_array);
String name = array[position];
if( name.equals(getString(R.string.Pontos)) ) {
getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, new MainActivityPontosFragment()).commit();
return true;
} else if( name.equals(getString(R.string.Sobre)) ) {
getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, new SobreFragment()).commit();
return true;
} else if( name.equals(getString(R.string.Temporizadores))) {
getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, new TimersListFragment()).commit();
return true;
}
return false;
}
每次创建菜单时都会调用onNavigationItemSelected,我无法避免它的重现。
但是,当调用onNavigationItemSelected时,如何避免创建新的片段实例?
我想不出更好的方法,但我也无法想象如何实现这一目标。
但我接受其他建议。
由于
修改
我将onNavigationItemSelected更改为this(如果是,则检查最后一个):
@Override
public boolean onNavigationItemSelected(int position, long id) {
String[] array = getResources().getStringArray(R.array.main_menu_array);
String name = array[position];
if( name.equals(getString(R.string.Pontos)) ) {
getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, new MainActivityPontosFragment()).commit();
return true;
} else if( name.equals(getString(R.string.Sobre)) ) {
getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, new SobreFragment()).commit();
return true;
} else if( name.equals(getString(R.string.Temporizadores))) {
MainActivityTimersFragment frag = (MainActivityTimersFragment) getSupportFragmentManager().findFragmentByTag(MainActivityTimersFragment.MY_TAG);
if( frag == null ) { frag = new MainActivityTimersFragment(); }
getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, frag, MainActivityTimersFragment.MY_TAG).commit();
return true;
}
return false;
}
但“frag”总是返回null。
答案 0 :(得分:1)
我使用以下方法测试了以下内容:
import android.support.v4.app.Fragment;
使用支持片段,并不是我记得使用常规片段类的所有内容,但这些是我可以根据测试提供的答案。
在屏幕方向更改时,活动将被销毁,并且会调用片段的onDestroyView和onDestroy方法。
但是,当您在Activity的OnCreate方法中调用super.onCreate(savedInstanceState)时,片段将重新创建 - 此时片段将重新附加到您的活动。
您可以使用片段管理器找到这些片段:
Fragment fragment = getSupportFragmentManager().findFragmentByTag(str_ID);
另一种方法是在静态变量中存储对片段的引用。在任何一种情况下,如果在super.OnCreate(savedInstanceState)之前使用,则manger或静态引用将返回NULL。
片段类中的任何非静态变量都将丢失。这是我不确定常规片段类是否表现不同的区域之一。无论如何,您可以覆盖其中一个onDestroy函数,并保存重新创建实例所需的所有变量/数据。
答案 1 :(得分:1)
Altough user3126670对我的问题给出了很好的答案。
我找到了他们的根。
我一直在重建我的活动,因为我的清单只预测了活动的方向变化。我错过了需要添加到API 13 +的screenSize参数。
我所要做的就是:
<activity
android:name="br.com.mtcbrasilia.aa.MainActivity"
android:label="@string/app_name"
android:configChanges="locale|orientation|screenSize" <---add this
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>