2014-12-31 7 views
4

У меня есть вопрос, заданный здесь более одного раза, но я не могу понять, как это решить для моего дела.Android oncreateview называется дважды

У меня есть приложение, которое пользователь делает это:

1 - Откройте navigationDrawer и выбирает один из вариантов (фрагмент создан) (я здесь выбираю второй вариант);

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 - Панель управления имеет вкладки и в iconpager. Для каждой страницы пейджера и для каждой вкладки создается новый фрагмент. У меня есть 3 вкладки и 3 страницы, поэтому создано 9 фрагментов;

@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(); у меня есть этот код:

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 имеют почти один и тот же код:

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 имеет следующий код:

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 с третьей вкладке выбранным. Если я повернуть экран у меня есть эта последовательность событий:

  1. ControlPanelFragment onSaveInstanceState сохраняет текущую вкладку и текущий фрагмент
  2. Fragmenta onSaveInstanceState сохраняет фрагменты вкладки для пейджера
  3. navigationDrawer второй вариант получает снова называется fragment = ControlPanelFragment.newInstance();
  4. Вызывается ControlPanelFragment onViewCreated, и я могу получить сохраненную информацию о данных, а новый пейджер и вкладки создаются
  5. FragmentA onViewCreated is и я могу извлечь сохраненные данные
  6. FragmentADetail onActivityCreated получает сохраненные данные и загружает данные correctelly (по крайней мере, я думаю) И теперь второй набор методов называется вторым, а ранее сохраненные данные сброшена, и поэтому теперь отображает неправильные данные
  7. ControlPanelFragment onSaveInstanceState но теперь savedInstanceState является нулевым
  8. ControlPanelPagerAdapter getItem называется инстанцирования 3 фрагмента
  9. Fragmenta onSaveInstanceState его теперь называют, но savedInstanceState равно нулю
  10. FragmentADetail onActivityCreated называется, но теперь вкладка = 0

Может кто-нибудь объяснить мне, как я могу остановить шаги от 7 до 10 от случаться?

ответ

9

Я выясняю, в чем была моя проблема.

Когда я делал:

case FRAGMENT_OPTION2: 
    fragment = ControlPanelFragment.newInstance(); 
break; 

я создавал фрагмент и когда я повернул экран selectItem(int position) снова так называется новый экземпляр того же объекта был создан таким образом, шаги 7 и после. Решение состояло в том, чтобы проверить, был ли уже создан фрагмент и использовать его вместо создания нового. Я сохранил исходный фрагмент с тегом, и они искали этот тег. Если тег существует, используйте этот фрагмент, иначе создайте новый.

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(); 
     } 
} 
Смежные вопросы