我不止一次地看到这个问题在这里被问到,但我不知道如何解决我的问题.
I have see this question asked here more than one time but I can't figure it out how to solve for my case.
我有一个用户这样做的应用:
I have an app that the user does this:
1 - 打开navigationDrawer并选择一个选项(创建一个片段)(我这里选择第二个选项);
1 - Open the navigationDrawer and selects one option (a fragment is created) (I'm here selecting the second option);
public void selectItem(int position) {
Fragment fragment = null;
switch (position) {
case FRAGMENT_OPTION1:
...
break;
case FRAGMENT_OPTION2:
fragment = ControlPanelFragment.newInstance();
break;
...
case FRAGMENT_OPTIONN:
...
return;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).commitAllowingStateLoss();
}
}
2 - 选定的选项 (ControlPanelFragment) 被加载:2.1 - 控制面板有标签和图标页面.对于每个寻呼机页面和每个选项卡,都会创建一个新片段.我有 3 个标签和 3 个页面,因此创建了 9 个片段;
2 - The selected option (ControlPanelFragment) gets loaded: 2.1 - Control panel has tabs and an iconpager. For each pager page and for each tab a new fragment is created. I have 3 tabs and 3 pages so 9 fragments are created;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState != null) {
currentControlPanelOption = savedInstanceState.getInt("currentControlPanelOption", currentControlPanelOption);
currentControlPanelTab = savedInstanceState.getInt("currentControlPanelTab", currentControlPanelTab);
}
setControlPanelTabs();
setIconPager();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("currentControlPanelOption", pager.getCurrentItem());
outState.putInt("currentControlPanelTab", mTabHost.getCurrentTab());
}
3 - 在 setIconPager();
我有这个代码:
3 - In the setIconPager();
I have this code:
pager = (ViewPager) view.findViewById(R.id.pager);
cPanelPagerAdapter = new ControlPanelPagerAdapter(getChildFragmentManager());
pager.setOffscreenPageLimit(2);
pager.setAdapter(cPanelPagerAdapter);
其中 ControlPanelPagerAdapter
有这个代码:
public Fragment getItem(int index) {
Fragment fragment;
switch (index) {
case 1:
fragment = FragmentA.newInstance();
break;
case 2:
fragment = FragmentB.newInstance();
break;
case 3:
fragment = FragmentC.newInstance();
break;
default:
fragment = null;
break;
}
...
return fragment;
}
4 - FragmentA
、FragmentB
和 FragmentC
的代码几乎相同:
4 - FragmentA
, FragmentB
and FragmentC
have almost the same code:
public static FragmentA newInstance() {
return new FragmentA();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_placeholder, container, false);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState == null) {
fragmentA_Data = new FragmentADetail[3];
createTabInstance(0);
} else {
fragmentA_Data = (FragmentADetail[]) savedInstanceState.getSerializable("Data");
return;
}
}
private void createTabInstance(int tab) {
new FragmentADetail();
fragment = FragmentADetail.newInstance(tab);
Bundle args = new Bundle();
args.putInt("tab", tab);
fragment.setArguments(args);
fragmentA_Data[tab] = fragment;
FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_placeholder, fragmentA_Data[tab]);
fragmentTransaction.commitAllowingStateLoss();
}
public void getTabData(int tab) {
if (fragmentA_Data[tab] == null) {
createStoreTimePeriodInstance(tab);
} else {
if (fragmentA_Data[tab].getArguments() == null) {
Bundle args = new Bundle();
args.putInt("tab", tab);
fragmentA_Data[tab].setArguments(args);
}
FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_placeholder, fragmentA_Data[tab]);
fragmentTransaction.commitAllowingStateLoss();
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("data", fragmentA_Data);
}
5 - 最后,FragmentADetail
有这个代码:
5 - Finally, FragmentADetail
has this code:
public static FragmentADetail newInstance(int tab) {
selectedTab = tab;
return new FragmentADetail();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.details_fragment, container, false);
...
if (savedInstanceState != null) {
selectedTab = savedInstanceState.getInt("selectedTab");
}
...
}
public void getTabData(int tab) {
//This is where I'm getting the data that populates the layout
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("selectedTab", selectedTab);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle args = getArguments();
if (args != null) {
getTabData(args.getInt("tab"));
}
}
现在,假设我在 FragmentA
上选择了第三个选项卡.如果我旋转屏幕,我会有以下事件序列:
Now, imagine I'm on FragmentA
with the third tab selected. If I rotate the screen I have this sequence of events:
onSaveInstanceState
保存当前选项卡和当前片段onSaveInstanceState
保存分页器的标签片段fragment = ControlPanelFragment.newInstance();
onViewCreated
被调用,我可以获取保存的数据信息并创建一个新的分页器和选项卡onViewCreated
被调用,我可以提取保存的数据onActivityCreated
获取保存的数据并正确加载数据(至少我认为)并且从现在开始第二次调用第二组方法,并且之前保存的数据被重置,因此现在显示错误数据onSaveInstanceState
但现在 savedInstanceState 为空getItem
被称为实例化 3 个片段onSaveInstanceState
现在调用它但 savedInstanceState 为空onActivityCreated
被调用,但现在 tab = 0onSaveInstanceState
saves the current tab and current fragmentonSaveInstanceState
saves the tabs fragments for the pagerfragment = ControlPanelFragment.newInstance();
onViewCreated
is called and I can get the saved data information and a new pager and tabs are createdonViewCreated
is called and I can extract the saved dataonActivityCreated
gets the saved data and loads the data correctelly (at least I think)
And from now a second set of methods is called the second time and the data that was previously saved is reseted and so it now displays wrong dataonSaveInstanceState
but now the savedInstanceState is nullgetItem
is called instantiating the 3 fragmentsonSaveInstanceState
its now called but savedInstanceState is nullonActivityCreated
is called but now the tab = 0谁能解释一下,我怎样才能阻止步骤 7 到 10 的发生?
Can someone explain-me how can I stop steps 7 to 10 from happening?
我知道我的问题是什么.
I figure out what was my problem.
当我在做的时候:
case FRAGMENT_OPTION2:
fragment = ControlPanelFragment.newInstance();
break;
我正在创建一个片段,当我旋转屏幕时 selectItem(int position)
再次被调用,因此创建了同一对象的新实例,因此步骤 7
和以下.解决方案是检查片段是否已经创建并使用他而不是创建新片段.我已经用标签保存了初始片段,他们正在寻找那个标签.如果标签存在,则使用该片段,否则创建一个新片段.
I was creating a fragment and when I rotated the screen selectItem(int position)
was again called so a new instance of the same object was created thus the steps 7
and following. The solution was to check if the fragment was already created and use him instead of creating a new one.
I've saved the initial fragment with a tag and them looked for that tag. If the tag existed, use that fragment otherwise create a new one.
public void selectItem(int position) {
Fragment fragment = null;
switch (position) {
case FRAGMENT_OPTION1:
...
break;
case FRAGMENT_OPTION2:
fragment = getSupportFragmentManager().findFragmentByTag(String.valueOf(position));
if (fragment == null) {
fragment = ControlPanelFragment.newInstance();
}
break;
...
case FRAGMENT_OPTIONN:
...
return;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment,
String.valueOf(position)).commitAllowingStateLoss();
}
}
这篇关于Android oncreateview 调用了两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!