Как узнать, какой фрагмент запущен в данный момент, при использовании одного действия и нескольких фрагментов

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

MyFragmentClass test = (MyFragmentClass) getSupportFragmentManager().findFragmentByTag("testID");
if (test != null && test.isVisible()) {
     //DO STUFF
}
else {
    //Whatever
}

Но не знаю, что вам за параметр "testID". Далее попробовал реализовать решение от Получить текущий объект фрагмента

Fragment currentFragment = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);

Но здесь я получаю сообщение об ошибке: «Не удается разрешить символ 'fragment_container'»

Кто-нибудь знает, как получить имя текущего фрагмента, который отображается при использовании подхода с одним действием и несколькими фрагментами?

Пожалуйста, поделитесь xml-файлом просмотра содержимого вашей активности, я постараюсь помочь.

Jan Rozenbajgier 09.04.2022 11:28

И ваше приложение не компилируется или это только предупреждение студии Android?

Jan Rozenbajgier 09.04.2022 11:29

@JanRozenbajgier: Спасибо за ваши комментарии. На самом деле код не компилируется (как всегда при ошибке "Не удается разрешить символ")

VanessaF 09.04.2022 13:02

Глядя на мои 2 примера из ответов Stackoverflow, знаете ли вы, какое значение я должен использовать для "testID" (подход 1) или R.id.fragment_container (подход 2)?

VanessaF 09.04.2022 13:05

R.id.fragment_container — это идентификатор FragmentContainerView. TestId должен быть набором тегов при добавлении фрагмента в контейнер. Я напишу ответ и все объясню.

Jan Rozenbajgier 09.04.2022 14:12

Я думаю, вам нужно перефразировать свой вопрос на How to get the currently displaying fragment in Nav Controller

Sambhav. K 10.04.2022 17:46
Основы программирования на Java
Основы программирования на Java
Java - это высокоуровневый объектно-ориентированный язык программирования, основанный на классах.
Концепции JavaScript, которые вы должны знать как JS программист!
Концепции JavaScript, которые вы должны знать как JS программист!
JavaScript (Js) - это язык программирования, объединяющий HTML и CSS с одной из основных технологий Всемирной паутины. Более 97% веб-сайтов используют...
1
6
37
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете сделать что-то вроде этого:

  1. Создайте поле Fragment в своей деятельности. Как это:
private Fragment mCurrentlyDisplayingFragment;
  1. Всякий раз, когда вы меняете фрагмент, просто передайте ему этот объект фрагмента. Как это:
MyFragment fragment = new MyFragment();
// show it in the frame layout
mCurrentlyDisplayingFragment = fragment;

Теперь всякий раз, когда вы проверяете, просто проверяйте это поле. Готово

Удачного кодирования 🙂

Спасибо за Ваш ответ. Я должен признать, что у меня есть проблемы с пониманием этого. Где именно я должен поставить код вашего 2. шага? Я просто хочу знать в основном действии, какой фрагмент отображается в данный момент.

VanessaF 09.04.2022 13:01

Глядя на мои 2 примера из ответов Stackoverflow, знаете ли вы, какое значение я должен использовать для "testID" (подход 1) или R.id.fragment_container (подход 2)?

VanessaF 09.04.2022 13:05

Всякий раз, когда вы меняете фрагмент, вы создаете экземпляр этого фрагмента, верно? Затем вы передаете это тому. Теперь, когда вы изменяете фрагмент, вы можете передать этот фрагмент этому mCurrentlyDisplayingFragment объекту.

Sambhav. K 10.04.2022 06:47

И этот второй аргумент (testId) t используется, когда вы изменяете фрагменты с помощью FragmentTransaction. Не навигационный контроллер

Sambhav. K 10.04.2022 06:53

Ваш 1-й подход:

Если вы хотите найти фрагмент по тегу, вам нужно сначала установить тег. Вы делаете это во время транзакции, например:

getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, SheetEditorScreen.class, args, "testID" //Here you set the tag
)

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

getSupportFragmentManager().findFragmentByTag("testID");

Ваш второй подход:

Если вы хотите получить фрагмент по идентификатору, вам нужно передать идентификатор представления контейнера, который вы объявляете в XML-файле макета вашей активности (установлено в setContentView(R.id.main_activity)):

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   xmlns:app="http://schemas.android.com/apk/res-auto">

   <androidx.fragment.app.FragmentContainerView
       android:id="@+id/fragment_container" <--- here is the id
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

а затем вы можете найти видимый фрагмент с помощью:

getSupportFragmentManager().findFragmentById(R.id.fragment_container);

Спасибо Ян за ваш ответ. Я должен признать, что у меня есть проблемы с пониманием обоих ваших подходов. Что касается 1-го подхода: Где именно я должен использовать код? В методе onCreate фрагмента или в действии? И что вы подразумеваете под «Вы делаете это во время транзакции, например»? Что такое транзакция и что такое ex? Что касается второго подхода: у меня нет FragmentContainerView в моем файле макета для действия. Я просто использую navHostfragment. Кроме того, у меня есть несколько фрагментов. Итак, я должен добавить предложенный вами XML-код в каждый фрагмент?

VanessaF 09.04.2022 15:52

Поделитесь своим кодом, где вы создаете фрагменты, чтобы я мог объяснить это для вашего случая.

Jan Rozenbajgier 09.04.2022 16:17

Спасибо за ваш ответ и усилия. Я очень ценю это. На самом деле мой код довольно большой (более 500 строк), поэтому я не думаю, что делиться им — хороший вариант. Однако я просто перехожу к различным фрагментам, используя onClickListener в основном действии, и запрашиваю нажатую кнопку. После этого я перехожу к соответствующему фрагменту. Итак, код выглядит так: if(view.getId() == R.id.navigation_Fragment1) { navController.navigate(R.id.Fragment1); }

VanessaF 09.04.2022 16:24

нужна строка, где вы инициализируете navController

Jan Rozenbajgier 09.04.2022 16:33

Спасибо Ян за ваш комментарий. Я инициализирую navController в методе onCreate основного действия, используя следующую строку navController = Navigation.findNavController(this, R.id.navHostfragment);

VanessaF 09.04.2022 16:35

Я никогда не использовал навигационный контроллер, но, возможно, попробую ((FragmentActivity)getActivity()).getSupportFragmentManager(‌​).findFragmentById(R‌​.id.navHostfragment)‌​;. Это должно вернуть видимый в данный момент фрагмент.

Jan Rozenbajgier 09.04.2022 16:38

Спасибо за Ваш ответ. При использовании Fragment currentFragment = ((FragmentActivity)getActivity()).getSupportFragmentManager(‌​).findFragmentById(R‌​.id.navHostfragment)‌​; я получаю сообщение об ошибке «Не удается разрешить метод getActivity ()». При использовании Fragment currentFragment = (getSupportFragmentManager().findFragmentById(R.id.navHostfr‌​agment)); я получаю сообщение об ошибке «Требуемый тип: android.app.Fragment Предоставлено: androidx.fragment.app.Fragment»

VanessaF 09.04.2022 16:47

Измените его на: androidx.fragment.app.Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.navHostfra‌​gment);

Jan Rozenbajgier 09.04.2022 17:01

Спасибо за Ваш ответ. Теперь на самом деле код компилируется и запускается, но когда я печатаю текущий фрагмент с помощью Log.e("LogTag_Main", "currentFragment: " + currentFragment);, я получаю очень странный вывод currentFragment: NavHostFragment{e6d2f4a} (bc743eb7-dba6-4de1-a3a2-580b9b4eb3c4 id=0x7f08013a), и очень странно то, что я всегда получаю один и тот же вывод независимо от того, какой фрагмент отображается. При изменении фрагмента основное действие генерирует тот же результат при использовании предложенного вами подхода.

VanessaF 09.04.2022 17:18

Спасибо Ян за ваши усилия. К сожалению, предложенные вами решения не сработали. Сейчас я использую одно из решений, предложенных Sambhav. К. Тем не менее, я очень ценю вашу помощь и усилия.

VanessaF 10.04.2022 09:48

Теперь, поскольку мне стало понятнее ваша проблема, я добавляю еще одно решение. Это работало с FrameLayout и транзакцией фрагмента. Но это будет работать и с NavController. Попробуйте этот код:

public Fragment getCurrentlyVisibleFragment(){
    Fragment navHostFragment = getSupportFragmentManager().findFragmentById(R.id.navHostFragment);
    return navHostFragment == null ? null : navHostFragment.getChildFragmentManager().getFragments().get(0);
}
Ответ принят как подходящий

Я знаю, что здесь уже есть 2 ответа, но у меня есть еще 1 решение, поэтому я пишу его здесь. Это код:

NavController navController = Navigation.findNavController(this, R.id.fragment);
        int id=navController.getCurrentDestination().getId();
      if(id==R.id.startGameFragment ){ // change the fragment id
          selectedPosition(0);

      }else if(id==R.id.gameFragment ){ // change the fragment id
          selectedPosition(1);

      }else if(id==R.id.endGameFragment ){ // change the fragment id
          selectedPosition(2);

      }

Круто, это решение отлично работает. Большое спасибо, Самбхав. К за вашу огромную помощь и усилия. Я очень ценю это. Я проголосовал и принял ваш ответ.

VanessaF 10.04.2022 09:46

Мой второй ответ также выполняет задачу TBH. И кстати всегда рад помочь

Sambhav. K 10.04.2022 12:12

Другие вопросы по теме