2016-03-01 3 views
3

В моей деятельности был написан метод setLoading, который отвечает за настройку статуса загрузки моего приложения. Этот метод отвечает за создание экземпляра LoadingFragment, удаляя все существующие экземпляры его (используя FragmentManager), а затем в зависимости от его первого параметра loading, добавив его в один из двух возможных контейнеров (в зависимости от параметра top).Удаление фрагмента, а затем повторное добавление его

protected LoadingFragment loadingFragment; 

public void setLoading(boolean loading, boolean top) { 
    FragmentManager fragmentManager = getFragmentManager(); 

    // Create LoadingFragment instance if it has not already been created 
    if (loadingFragment == null || !(loadingFragment instanceof LoadingFragment)) { 
     loadingFragment = new LoadingFragment(); 
    } 

    // Remove the fragment first if it is present 
    fragmentManager 
      .beginTransaction() 
      .remove(loadingFragment) 
      .commit(); 

    // Only if loading is true should we display the fragment 
    if (loading) { 
     // Decide which container we're going to put the fragment in 
     int id = top ? R.id.topContainer : R.id.container; 

     // Place the fragment in the right position 
     fragmentManager 
       .beginTransaction() 
       .add(id, loadingFragment) 
       .commit(); 
    } 
} 

public void setLoading(boolean loading) { 
    setLoading(loading, true); 
} 

Я запуск setLoading(true) из других в моей деятельности, и я закомментирована это соответствующие setLoading(false) во время тестирования.

Что я хочу, чтобы мой LoadingFragment появлялся каждый раз, когда вызывается setLoading(true). Первый вызов не должен удалять что-либо, поскольку в тот момент он не существует. Все последующие вызовы должны удалить существующий LoadingFragment и добавить его снова.

Что происходит, так это то, что первый вызов setLoading(true) действительно создает LoadingFragment и помещает его в правильный контейнер. Однако последующие вызовы setLoading(true) удаляют фрагмент, но он никогда не добавляется повторно. Я проверил, что фрагмент действительно существует и имеет тип LoadingFragment в том месте, где он добавлен, и я также проверил, чтобы он вызывал метод onCreateView.

Я что-то не так?

Редактировать

Используя ответ, данный ниже, H Равал в качестве основы я сейчас придумал следующее:

public void setLoading(boolean loading, boolean top) { 
    FragmentManager fragmentManager = getFragmentManager(); 

    Fragment currentLoadingFragment = fragmentManager.findFragmentById(R.id.loadingFragment); 
    if (currentLoadingFragment != null) { 
     fragmentManager 
       .beginTransaction() 
       .remove(currentLoadingFragment) 
       .commit(); 
    } 

    if (loading) { 
     int id = top ? R.id.topContainer : R.id.container; 

     fragmentManager 
       .beginTransaction() 
       .add(id, new LoadingFragment()) 
       .commit(); 
    } 
} 

Это, кажется, работает, как ожидалось. Похоже, что основное различие заключается в том, что этот код каждый раз создает новый экземпляр LoadingFragment (когда loading = true), тогда как первоначально я пытался использовать один и тот же экземпляр и просто добавлять/удалять его с помощью FragmentManager.

Из интереса, есть ли причина, по которой мне нужно создать новый экземпляр после использования remove? Это правильный способ сделать это? Или он должен работать при использовании одного и того же экземпляра? Кроме того, если каждый раз рекомендуется создавать новый экземпляр, есть ли что-то, что я должен делать с точки зрения очистки, освобождения ресурсов и т. Д. (Возможно, есть способ изящно уничтожить устаревшие экземпляры)?

+0

, а не с помощью добавления метода фрагмента менеджера пользователя заменить –

+0

Я бы сделать это, однако , Я не знаю до вызова метода, существует ли фрагмент уже. Не только это, мой второй параметр позволяет мне поместить фрагмент в другой контейнер, как указано в строке 'int id = top? R.id.topContainer: R.id.container; '. Поэтому я не думаю, что «замена» будет способом пойти – Jonathon

+0

ну с заменой вы можете установить тег фрагмента ... и при добавлении времени вы можете проверить, существует ли помеченный фрагмент ... проверьте этот http: // stackoverflow .com/questions/9294603/get-current-shown-fragment –

ответ

1

хорошо я сделал некоторые изменения в коде и работает идеально подходит для me..let мне знать, если вы сталкиваетесь с какими-либо трудностями

public void loadFragment(boolean loading, boolean top){ 
     FragmentManager fragmentManager = getSupportFragmentManager(); 

      loadingFragment = new LoadingFragment(); 

     // Only if loading is true should we display the fragment 
     if (loading) { 
      // Decide which container we're going to put the fragment in 
      int id = top ? R.id.topContainer : R.id.container; 

      if(top){ 
       if(fragmentManager.findFragmentByTag("loadingFragment")!=null) 
        fragmentManager.beginTransaction().remove(fragmentManager.findFragmentByTag("loadingFragment")).commit(); 

       fragmentManager 
         .beginTransaction() 
         .replace(R.id.topContainer, loadingFragment,"toploadingFragment") 
         .commit(); 
      }else{ 
       if(fragmentManager.findFragmentByTag("toploadingFragment")!=null) 
        fragmentManager.beginTransaction().remove(fragmentManager.findFragmentByTag("toploadingFragment")).commit(); 

       fragmentManager 
         .beginTransaction() 
         .replace(R.id.container, loadingFragment,"loadingFragment") 
         .commit(); 
      } 

     } 
+0

Спасибо за ваш ответ. Ваш работает в некоторой степени (хотя он не заботится об удалении фрагмента при загрузке = false). У меня был беспорядок вокруг себя, используя ваш код в качестве базы, и я обнаружил, что основное различие, которое заставляет это работать, состоит в том, что вы каждый раз создаете новый экземпляр «LoadingFragment», тогда как я пытался использовать тот же экземпляр , Мой код использует 'findFragmentById' вместо' findFragmentByTag' и использует 'add' /' remove', а не 'replace'. Все работает так, как ожидалось. См. Мое редактирование для деталей. – Jonathon

+0

вы должны создавать новый экземпляр каждый раз, потому что если вы используете тот же экземпляр, что и вы, возможно, не используете тот же фрагмент с другим идентификатором ... он выкинет исключение .... проверьте это http://stackoverflow.com/questions/9906254/ IllegalStateException-косяк с изменением контейнера-ID из-фрагмента –

Смежные вопросы