目前,我有2个Fragments,可通过ActionBar标签切换.
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab newTab = getSupportActionBar().newTab();
newTab.setText("history");
newTab.setTabListener(new TabListenerHistoryFragment>(this, "history",
HistoryFragment.class));
Run Code Online (Sandbox Code Playgroud)
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// Check if the fragment is already initialized
if (mFragment == null) {
// If not, instantiate and add it to the activity
mFragment = Fragment.instantiate(mActivity, mClass.getName());
mFragment.setRetainInstance(true);
ft.add(android.R.id.content, mFragment, mTag);
} else {
// If it exists, simply attach it in order to show it
ft.attach(mFragment);
}
}
Run Code Online (Sandbox Code Playgroud)
我意识到我的第一次Activity(此活动持有2个片段)正在启动,Fragments'方法将按以下顺序调用.
onCreate -> onCreateView -> onStart
当我执行Tab切换,然后Tab切换回相同的片段时,将再次调用以下方法.
onCreateView -> onStart
我只是希望保留相同的GUI视图状态,当Tab被切换回来时.
我知道在Tab切换时我可以使用以下方法保存/恢复简单变量
android片段 - 如何在片段上推送另一个片段时保存片段中的视图状态
但是,这不是我想要的,因为我的GUI状态很难在一堆原始值中描述.
我尝试以下方法.当然它不会工作,因为我得到以下运行时错误.
public class HistoryFragment extends Fragment {
View view = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (this.view != null) {
return this.view;
}
this.view = inflater.inflate(R.layout.history_activity, container, false);
}
}
Run Code Online (Sandbox Code Playgroud)
java.lang.IllegalStateException:指定的子级已有父级.您必须首先在孩子的父母上调用removeView().
我意识到以下演示示例能够在Tab切换时保留其片段GUI状态(例如,列表的垂直滚动的位置).但我猜,也许是因为他们正在使用ListFragment?因为我没有发现它们执行任何特殊处理以保留GUI状态.
我可以知道,在执行制表切换时如何避免重新创建相同的视图?
小智 36
我遇到了同样的问题,并尝试按照错误消息中的建议.我尝试了以下代码,它对我有用.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
if (mMyView == null) {
mMyView = new MyView(getActivity());
} else {
((ViewGroup) mMyView.getParent()).removeView(mMyView);
}
return mPuzzleView;
}
Run Code Online (Sandbox Code Playgroud)
bra*_*all 19
几个小时前我开始寻找一个简单的解决方案,最后偶然发现了@roger的答案,这为我节省了很多头发....
在其他实现中使用ViewPager时,我可以简单地调用:
mViewPager.setOffscreenPageLimit(//number of pages to cache);
Run Code Online (Sandbox Code Playgroud)
所以,我很惊讶我花了这么多时间来解决这个问题.他给的例子是不完全清楚的,所以为了完整起见,这里是我在使用的片段代码FragmentTabHost
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentExample extends Fragment {
private View rootView;
public FragmentExample() {
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
if (rootView == null) {
rootView = inflater.inflate(R.layout.fragment_example_layout, container, false);
// Initialise your layout here
} else {
((ViewGroup) rootView.getParent()).removeView(rootView);
}
return rootView;
}
}
Run Code Online (Sandbox Code Playgroud)
我搜索了以下我在这里添加的关键短语,希望我能帮助别人摆脱我刚刚经历过的挫折!
FragmentTabHost保存Fragment状态
重新创建FragmentTabHost视图
FragmentTabHost缓存碎片
FragmentTabHost onCreateView Fragment被破坏
小智 6
以下解决方案适合我.它可以防止在切换选项卡时调用Fragment的onCreateView.
Activity的onCreate应该添加所有片段并隐藏除第一个选项卡之外的所有片段:
ft.add(R.id.fragment_content, secondTabFragment);
ft.hide(secondTabFragment);
ft.add(R.id.fragment_content, firstTabFragment);
ft.show(firstTabFragment);
ft.commit();
currentFragment = firstTabFragment;
Run Code Online (Sandbox Code Playgroud)
Activity的onTabSelected应该只隐藏当前片段并显示与所选选项卡对应的片段.
ft.hide(currentFragment);
ft.show(chosenFragment);
ft.commit();
currentFragment = chosenFragment;
Run Code Online (Sandbox Code Playgroud)
请注意,更改设备方向将重新启动您的活动,然后重新创建碎片.您可以通过在Manifest中添加此configChanges来避免这种情况:
<activity android:configChanges="keyboardHidden|orientation" ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14360 次 |
| 最近记录: |