Android - Установить идентификатор фрагмента


Ответы:


117

Вы не можете установить идентификатор фрагмента программно .

Однако существует объект String tag, который можно установить внутри FragmentTransaction, который можно использовать для однозначной идентификации фрагмента.

Как отметил Алексей, вы можете передать идентификатор FragmentTransaction«S add(int, Fragment)методом. Однако это не указывает идентификатор для фрагмента. Он определяет идентификатор, в который ViewGroupнужно вставить Fragment. Это не так полезно для той цели, которую я ожидаю, потому что он не однозначно идентифицирует Fragments, но ViewGroups. Эти идентификаторы относятся к контейнерам, в которые можно динамически добавлять один или несколько фрагментов. Использование такого метода для идентификации Fragments потребует от вас ViewGroupдинамического добавления s в макет для каждого Fragmentвставляемого вами элемента. Это было бы довольно громоздко.

Так что, если ваш вопрос заключается в том , чтобы создать уникальный идентификатор для фрагмента вы добавляете динамически, то ответ заключается в использовании FragmentTransaction«s надстройки (INT containerViewId, фрагмент фрагмента, строковый тег) метода и FragmentManager» s findFragmentByTag (String) метод.

В одном из моих приложений мне пришлось динамически генерировать строки. Но в любом случае это не так дорого по сравнению с фактическим FragmentTransaction.

Еще одно преимущество метода тега заключается в том, что он может идентифицировать фрагмент, который не добавляется в пользовательский интерфейс. См. Метод add (Fragment, String) FragmentTransaction . Fragments не обязательно иметь Views! Их также можно использовать для сохранения эфемерного состояния между изменениями конфигурации!


Если я использую тег, а не идентификатор для фрагмента, как мне использовать вызов замены, для которого требуется идентификатор ресурса фрагмента?
Намрата

12
@TomDignan как насчет фрагмента, который будет добавлен в ViewPager? Как мне установить его тег? Я не могу использовать транзакции в этой ситуации.
GuilhE

1
@GuilhE Activity предоставляет метод addFragment (), на который вы можете ссылаться из окна просмотра. Сохранение тега до этого можно было выполнить с помощью хэш-карты.
Томас Дигнан

1
Можно ли немного отредактировать ответ, чтобы подчеркнуть, что вы можете установить id в макете xml? Потому что я лично не читал другие вопросы и у меня сложилось впечатление, что вообще невозможно установить id для фрагмента ...
Иван

41

Оказывается, вам может не понадобиться знать идентификатор фрагмента.

Из документов:

public abstract Fragment findFragmentById (int id)

Finds a fragment that was identified by the given id either
when inflated from XML or as the container ID when added in
a transaction.

Важная часть - «как идентификатор контейнера при добавлении в транзакцию».

так:

getSupportFragmentManager()
    .beginTransaction()
    .add(R.id.fragment_holder, new AwesomeFragment())
    .commit();

а потом

AwesomeFragment awesome = (AwesomeFragment)
     getSupportFragmentManager()
          .findFragmentById(R.id.fragment_holder);

предоставит вам любой (потрясающий) фрагмент, хранящийся в R.id.fragment_holder.


4

В большинстве случаев вы можете использовать тег фрагмента, а также идентификатор.
Вы можете установить значение тега в FragmentTransaction.add(Fragment fragment, String tag );. Затем вы можете использовать команду, FragmentManager.findFragmentByTag(String tab)чтобы найти рассматриваемый фрагмент.


2

Как уже упоминали Том и другие, есть способы поставить тег на фрагмент и использовать этот тег для идентификации. Следующая проблема, с которой я столкнулся с этими решениями, заключается в том, что фрагмент не получает тег, пока он не связан с Activity (или, фактически, с FragmentManager). Что делать, если нужно идентифицировать фрагмент до того, как он был помечен?

Пока все мои решения основаны на самом старом (Java) трюке в мире: создать минималистичный фрагмент шаблона, который принимает идентификатор в одном из своих конструкторов и предоставляет getFragmentId()метод, который возвращает этот идентификатор. Затем я позволяю тем фрагментам, которые нуждаются в ранней идентификации, расширять этот шаблон и; вуаля! Задача решена.

Это решение может, к сожалению, потребовать набора фрагментов шаблона, по одному для каждого типа фрагмента ListFragment, DialogFragmentили просто старых Fragment(POFO ?!), которые нуждаются в ранней идентификации. Но я думаю, что в случае с фрагментами это возможно, учитывая полученный выигрыш.

Простите, что раздирала заживающие раны :-)

Ура!


0

Используйте следующее:

Чтобы добавить фрагмент:

getFragmentManager().beginTransaction().add(R.id.fragment_container, fragmentToBeAdded, tag).commit();

Чтобы идентифицировать существующий фрагмент:

getFragmentManager().findFragmentByTag(fragmentName);

Ответ не имеет отношения к вопросу. Пожалуйста, обновите ответ. Счастливое кодирование
CodeWithVikas

-1

При использовании тега обязательно добавьте

fragmentTransaction.addToBackStack(null); 

, чтобы ваш фрагмент был возобновлен, а не уничтожен, как указано в руководствах разработчика.

Если вы не вызываете addToBackStack () при выполнении транзакции, которая удаляет фрагмент, этот фрагмент уничтожается, когда транзакция фиксируется, и пользователь не может вернуться к нему. Принимая во внимание, что если вы вызываете addToBackStack () при удалении фрагмента, фрагмент останавливается и позже возобновляется, если пользователь переходит назад.

Вы можете найти это в конце этой страницы .

Я потерял около 30 минут, пытаясь выяснить, почему мой фрагмент не был найден с помощью простого findFragmentByTag();вызова


-2

В дополнение к ответу Тома метод replace также поддерживает тег фрагмента в дополнение к методу добавления.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.