当用户点击列表中的项目时,我会加载一些片段。假设用户已单击列表中的第二项,则加载第二个片段。但是,在旋转屏幕时,列表中的第一个片段会被加载。如何在用户旋转屏幕时确保加载相同的片段。 这就是我加载片段的方式
private void selectItem(position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new FirstFragment();
break;
case 1:
fragment = new SecondFragment();
break;
case 2:
fragment = new ThirdFragment();
break;
default:
break;
}
if (fragment != null) {
android.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
}
else {
Log.e("NavigationActivity", "Error in creating fragment");
}
}
我在活动的selectItem(0)
中呼叫onCreate
。
答案 0 :(得分:2)
整个活动在轮换期间被破坏并重新创建。因此,如果您在Activity.onCreate中调用setItem(0),那么您将始终在内容框架中获得FirstFragment。
似乎很容易就是检测你是否已经在onCreate中设置了一个片段并且没有加载默认值。使用onSaveInstanceState和/或将片段标记为保留。
除了初始加载之外,我对保留的片段或片段管理没有太多经验,因此只需使用onSaveInstanceState来跟踪加载哪个片段似乎是合适的。
在您的Activity中,覆盖onSaveInstanceState:
@Override
public void onSaveInstanceState(Bundle bundle)
{
bundle.putInt("which_fragment", _fragmentId);
super.onSaveInstanceState(bundle);
}
其中_fragmentId
只是您要加载的特定片段的一些数字标识符。它甚至可能是它的布局ID。在selectItem方法中设置此值。
然后在onCreate:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
_fragmentId = 0;
if (savedInstanceState != null)
{
_fragmentId = savedInstanceState.getInt("which_fragment", 0);
}
...
selectItem(_fragmentId);
}
答案 1 :(得分:2)
首先,我不会使用positionOnTheList->Fragment
依赖。我会依赖一些id
(最终或来自资源)。
其次,我认为当你从列表中选择项目时,你不应该创建每个Fragment
类的新实例。
你应该考虑这种方法:
Fragment f = fragmentManager.findFragmentById( String.valueOf(id) );
if( f == null )
f = new FragmentDependingOnId();
mCurrentlySelectedId = id;
fragmentManager.beginTransaction()
.replace( R.id.container, f , String.valueOf(id))
.commit();
添加以下方法:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SELECTED_ID, mCurrentlySelectedId);
}
并在onCreate
添加:
if(savedInstanceState!=null){
mCurrentlySelectedId = savedInstanceState.getInt(SELECTED_ID);
selectItem(mCurrentlySelectedId);
}
答案 2 :(得分:1)
使用片段时,您通常会使用onCreateView
来扩充您的布局。然后使用onActivityCreated
来完成初始化列表视图等所需的所有内容......
在您的情况下,您遇到的问题是您应该使用saveInstanceState来跟踪是否加载了片段,因为片段是在每次轮换时重新创建的。
让我们看看一些代码
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.your_fragment_layout, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
//do nothing if the state already exists
} else {
//do something if state already exists
}
}
请注意,如果您需要保存给定值,例如布尔值,您可以使用
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(YOUR_BOOL_TAG, mYourBooleanVar);
}
并使用
将其恢复到onCreateView
mYourBooleanVar= savedInstanceState.getBoolean(YOUR_BOOL_TAG);
同样适用于其他类型。
修改强>
我没有回答你的问题,所以我提出了更多细节。上面的代码在片段中。但是对于你的问题,在activity
你需要类似的东西。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
//here is the transaction to load your first fragment
}
}
并且你的第一个fragement每次都不会重新加载。
第一次savedInstanceState
为空并设置默认片段。然后,每次旋转savedInstanceState
时都不为空,并且您的默认片段不会重新加载,而是当前存在的片段。
只有这段代码与您相关,但我将EDIT上方的代码留给了其他人,以防它们对他们有用。