2013-11-26 6 views
0

Если я добавляю фрагменты моей деятельности, как это:.getSupportFragmentManager() findFragmentByTag непредсказуемое поведение

fragment_tags = new ArrayList<String>(); 
    fragment_tags.add("user_fragment"); 
    fragment_tags.add("memorial_fragment"); 

    UserFragment user = new UserFragment(); 
    MemorialFragment memorial = new MemorialFragment(); 

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 

    ft.add(R.id.content_frame, user, fragment_tags.get(0)); 
    ft.add(R.id.content_frame, memorial, fragment_tags.get(1)); 
    ft.commit(); 

, а затем через некоторое время я пытаюсь получить эти фрагменты, как это:

List<Fragment> frg = getSupportFragmentManager().getFragments(); 
    Fragment fragUser = getSupportFragmentManager().findFragmentByTag(
      "user_fragment"); 
    Fragment fragUserID = getSupportFragmentManager().findFragmentById(
      R.id.user_fragment_id); 
      Log.d("MV", "fragments size:" + (frg == null ? " null" : frg.size())); 

Log.d всегда возвращает размер 2, но fragUser иногда является нулевым, а иногда это фрагмент, который я вставлял в транзакцию.

Что более интересно то, что этот код:

try { 
     Log.d("MV", "0:" + frg.get(0).toString()); 
     Log.d("MV", "1:" + frg.get(1).toString()); 
    } catch (NullPointerException e) { 
     Log.d("MV", "null caught"); 
    } 

иногда будет работать для обоих фрагментов, а иногда и просто для первого и если я smething так:

if(frg.get(0) == fragUser) 

будет иногда оценивается как истина, но не часто. Я действительно не понимаю этого поведения, но мне нужно реализовать переключение между несколькими фрагментами, поэтому мне нужно получить ссылку на точный фрагмент. Кто-нибудь? Я пытаюсь решить это в течение 6 часов, и я действительно не понимаю, как это сделать. Спасибо

+0

Ну, чтобы ответить на одну часть ... ** "if (frg.get (0) == fragUser)" ** ... вы не можете сравнить объекты с помощью '=='. Вам нужно использовать 'if (frg.get (0).equals (fragUser)) ' – Squonk

+0

Сквонк на самом деле это мое намерение. Мне все равно, если объекты имеют одинаковые атрибуты, но если их ссылки одинаковы, они должны быть теми же объектами. Я хочу тот же фрагмент. – vanomart

ответ

0

Поскольку этот вопрос был отправлен мной еще в 2013 году, он получил более 1000 просмотров, но все равно без ответа, я попытаюсь подвести итог тому, что я узнал за годы работы с фрагментами.

  1. Не используйте getSupportFragmentManager(). GetFragments() (подробнее об этом в getSupportFragmentManager().getFragments() shows a compile time error)
  2. FragmentManager есть для управления жизненным циклом фрагментов. Не пытайтесь помещать фрагменты в свои собственные списки или сохраняйте их сильную ссылку.
  3. Причина, по которой if(frg.get(0) == fragUser) не работает последовательно, привязана к точке 2. - FragmentManager управляет фрагментами, поэтому, когда он решает убить одного и воссоздайте его снова, ссылки не будут совпадать.

Теперь вопрос - как безопасно работать с фрагментами? Метод

  1. передавать данные фрагменты в связке с использованием setArguments(), так что Android может убить & воссоздать фрагмент.
  2. FragmentManager.findFragmentById(R.id.some_id) найдет фрагмент, прикрепленный к представлению с id some_id. Очень вероятно, что если у вас есть несколько фрагментов, добавленных в R.id.some_id, FragmentManager.findFragmentById(R.id.some_id) даст разные результаты (но, как правило, это очень хороший способ узнать, какой фрагмент в настоящее время виден, если вы также не скрываете/не отображаете свои фрагменты)
  3. Понять различные методы из API FragmentTransaction, особенно различия между add и replace, hide, detach, remove и show.
  4. Иногда вещи просто не работают (сбой при одновременном запуске нескольких анимаций перехода фрагмента), или ваше приложение не является хорошим вариантом для фрагментов. Вы можете больше узнать о последнем в классическом посте https://medium.com/square-corner-blog/advocating-against-android-fragments-81fd0b462c97
Смежные вопросы