Получить в данный момент фрагмент

Я играю с Fragment в Android.

Я знаю, что могу изменить фрагмент, используя следующий код:

FragmentManager fragMgr = getSupportFragmentManager(); FragmentTransaction fragTrans = fragMgr.beginTransaction(); MyFragment myFragment = new MyFragment();//my custom fragment fragTrans.replace(android.R.id.content, myFragment); fragTrans.addToBackStack(null); fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); fragTrans.commit(); 

Мой вопрос заключается в том, что в файле Java, как я могу получить текущий отображаемый экземпляр Fragment?

Solutions Collecting From Web of "Получить в данный момент фрагмент"

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

 fragTrans.replace(android.R.id.content, myFragment, "MY_FRAGMENT"); 

… и позже, если вы хотите проверить, является ли фрагмент видимым:

 MyFragment myFragment = (MyFragment)getFragmentManager().findFragmentByTag("MY_FRAGMENT"); if (myFragment != null && myFragment.isVisible()) { // add your code here } 

См. Также http://developer.android.com/reference/android/app/Fragment.html

Я знаю, что это старый пост, но у него были проблемы с ним и раньше. Нашел решение, которое должно было сделать это в функции прослушивания onBackStackChanged()

 Fragment f = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container); if (f instanceof CustomFragmentClass) // do something with f ((CustomFragmentClass) f).doSomething(); 

Это сработало для меня, так как я не хотел перебирать каждый фрагмент, чтобы найти тот, который виден. Надеюсь, это тоже поможет кому-то другому.

Вот мое решение, которое я считаю удобным для сценариев с низким фрагментом

 public Fragment getVisibleFragment(){ FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager(); List<Fragment> fragments = fragmentManager.getFragments(); if(fragments != null){ for(Fragment fragment : fragments){ if(fragment != null && fragment.isVisible()) return fragment; } } return null; } 

Каждый раз, когда вы показываете фрагмент, вы должны поместить его в backstack:

 FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK); ft.add(R.id.primaryLayout, fragment, tag); ft.addToBackStack(tag); ft.commit(); 

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

 public BaseFragment getActiveFragment() { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { return null; } String tag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName(); return (BaseFragment) getSupportFragmentManager().findFragmentByTag(tag); } 

То, что я использую, чтобы найти текущий отображаемый фрагмент, находится ниже кода. Это просто и работает для меня. Он работает в активности, которая содержит фрагменты

  FragmentManager fragManager = this.getSupportFragmentManager(); int count = this.getSupportFragmentManager().getBackStackEntryCount(); Fragment frag = fragManager.getFragments().get(count>0?count-1:count); 

Реактивный способ:

 Observable.from(getSupportFragmentManager().getFragments()) .filter(fragment -> fragment.isVisible()) .subscribe(fragment1 -> { // Do something with it }, throwable1 -> { // }); 

Мой метод основан на try / catch следующим образом:

 MyFragment viewer = null; try { viewer = (MyFragment) getFragmentManager().findFragmentByTag(MY_TAG_FRAGMENT); } catch (ClassCastException e) { // not that fragment } 

Но может быть лучший способ …

1)

 ft.replace(R.id.content_frame, fragment, **tag**).commit(); 

2)

 FragmentManager fragmentManager = getSupportFragmentManager(); Fragment currentFragment = fragmentManager.findFragmentById(R.id.content_frame); 

3)

 if (currentFragment.getTag().equals(**"Fragment_Main"**)) { //Do something } else if (currentFragment.getTag().equals(**"Fragment_DM"**)) { //Do something } 

Вдохновленный ответом Тайни , вот мои два цента. Небольшое изменение от большинства других реализаций.

 private Fragment getCurrentFragment() { FragmentManager fragmentManager = myActivity.getSupportFragmentManager(); int stackCount = fragmentManager.getBackStackEntryCount(); if( fragmentManager.getFragments() != null ) return fragmentManager.getFragments().get( stackCount > 0 ? stackCount-1 : stackCount ); else return null; } 

Замените "myActivity" на «this», если это ваша текущая деятельность или используйте ссылку на вашу деятельность.

Ну, этот вопрос получил много просмотров и внимания, но до сих пор не содержал самого легкого решения с моего конца – использовать getFragments ().

  List fragments = getSupportFragmentManager().getFragments(); mCurrentFragment = fragments.get(fragments.size() - 1); 

Это немного поздно, но для всех, кто заинтересован: если вы знаете, что индекс вашего желаемого фрагмента в FragmentManager просто получите ссылку на него и проверьте функцию isMenuVisible ()! Вот :

 getSupportFragmentManager().getFragments().get(0).isMenuVisible() 

Если true видно пользователю и так далее!

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

 findFragmentByID(R.id.container); 

Фактически это будет текущий экземпляр фрагмента, который заполнен в представлении. Я была такая же проблема. Мне пришлось загрузить один и тот же фрагмент, дважды удерживая один в стопке.

Следующий метод не работает. Он просто получает фрагмент с тегом. Не тратьте время на этот метод. Я уверен, что он использует его, но для того, чтобы получить самую последнюю версию того же Фрагмента, это не один из них.

 findFragmentByTag() 

В findFragmentById() есть метод под названием findFragmentById() . Я использую его в контейнере действий, например:

 public Fragment currentFragment(){ return getSupportFragmentManager().findFragmentById(R.id.activity_newsfeed_frame); } 

Вот как получить ваш текущий Fragment . Если у вас есть пользовательский Fragment и вам нужно проверить, что это за Fragment , я обычно использую instanceof :

 if (currentFragment() instanceof MyFrag){ // Do something here } 

Это работа для меня. Надеюсь, это кому-то поможет.

 FragmentManager fragmentManager = this.getSupportFragmentManager(); String tag = fragmentManager .getBackStackEntryAt( fragmentManager .getBackStackEntryCount() - 1) .getName(); Log.d("This is your Top Fragment name: ", ""+tag); 
 final FragmentManager fm=this.getSupportFragmentManager(); final Fragment fragment=fm.findFragmentByTag("MY_FRAGMENT"); if(fragment != null && fragment.isVisible()){ Log.i("TAG","my fragment is visible"); } else{ Log.i("TAG","my fragment is not visible"); } 

В основной деятельности метод onAttachFragment (фрагмент фрагмента) вызывается, когда к этому активу присоединяется новый фрагмент. В этом методе вы можете получить экземпляр текущего фрагмента. Тем не менее, метод onAttachFragment не вызывается, когда фрагмент выскользнул с задней стороны, то есть когда нажата кнопка «Назад», чтобы получить верхний фрагмент поверх стека. Я все еще ищу метод обратного вызова, который запускается в основном действии, когда фрагмент становится видимым внутри действия.

На самом деле это не ответ, но у меня нет 50 комментариев для комментариев …

Ответ Сева является потрясающим! Он работает, когда вы нажимаете кнопку «Назад» или иным образом изменяете стопку назад. Я сделал что-то немного другое. У меня есть функция прослушивателя изменений backstack на базовом фрагменте и его выведенных фрагментах, и этот код находится в слушателе:

 Fragment f = getActivity().getSupportFragmentManager().findFragmentById(R.id.container); if (f.getClass().equals(getClass())) { // On back button, or popBackStack(), // the fragment that's becoming visible executes here, // but not the one being popped, or others on the back stack // So, for my case, I can change action bar bg color per fragment } 

Я столкнулся с аналогичной проблемой, где мне захотелось узнать, какой фрагмент последний раз отображался при нажатии клавиши «Назад». Я использовал очень простое решение, которое сработало для меня. Каждый раз, когда я открываю фрагмент, в методе onCreate () я устанавливаю переменную в моем одиночном тоне (заменим «myFragment» на имя вашего фрагмента)

 MySingleton.currentFragment = myFragment.class; 

Переменная объявляется в singleton как

 public static Class currentFragment = null; 

Затем в onBackPressed () я проверяю

  if (MySingleton.currentFragment == myFragment.class){ // do something return; } super.onBackPressed(); 

Обязательно вызовите super.onBackPressed (); После «возврата», в противном случае приложение обработает обратный ключ, который в моем случае заставил приложение завершить работу.

Спасибо за этот вопрос! Хорошо, у меня было время с этим. Если вы используете библиотеку поддержки v13, эта проблема исправлена, и вы должны просто переопределить

@Override

 public void setUserVisibleHint(boolean isVisibleToUser) { // TODO Auto-generated method stub super.setUserVisibleHint(isVisibleToUser); } 

Дело в том, что вы не можете их смешивать, потому что фрагмент не совместим с классом фрагментов версии 4

Если вы этого не сделали, и вы используете библиотеку поддержки V4, переопределите метод setPrimaryItem для вашего FragmentStatePagerAdapter.

Я использовал это, чтобы обновить заголовок Actionbat в больших списках.

НТН

Возможно, самый простой способ:

 public MyFragment getVisibleFragment(){ FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager(); List<Fragment> fragments = fragmentManager.getFragments(); for(Fragment fragment : fragments){ if(fragment != null && fragment.getUserVisibleHint()) return (MyFragment)fragment; } return null; } 

Это сработало для меня

Немного странно, но я посмотрел на FragmentManager $ FragmentManagerImpl, и для меня работает следующее:

 public static Fragment getActiveFragment(Activity activity, int index) { Bundle bundle = new Bundle(); String key = "i"; bundle.putInt(key,index); Fragment fragment=null; try { fragment = activity.getFragmentManager().getFragment(bundle, key); } catch(Exception e){} return fragment; } 

Чтобы первый активный фрагмент использовал 0 в качестве индекса

 public Fragment getVisibleFragment() { FragmentManager fragmentManager = getSupportFragmentManager(); List<Fragment> fragments = fragmentManager.getFragments(); if(fragments != null) { for (Fragment fragment : fragments) { if (fragment != null && fragment.isVisible()) return fragment; } } return null; } 

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

Возвращаемый фрагмент можно сравнить с фрагментом, который вы хотите поместить в стек.

Попробуйте этот метод …..

 private Fragment getCurrentFragment(){ FragmentManager fragmentManager = getSupportFragmentManager(); String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName(); Fragment currentFragment = getSupportFragmentManager() .findFragmentByTag(fragmentTag); return currentFragment; } 

Вы можете получить текущий фрагмент, используя следующий код

 FragmentClass f = (FragmentClass)viewPager.getAdapter().instantiateItem(viewPager, viewPager.getCurrentItem()); 

Вы можете добавить переменную класса selectedFragment, и каждый раз, когда вы меняете фрагмент, вы обновляете переменную.

 public Fragment selectedFragment; public void changeFragment(Fragment newFragment){ FragmentManager fragMgr = getSupportFragmentManager(); FragmentTransaction fragTrans = fragMgr.beginTransaction(); fragTrans.replace(android.R.id.content, newFragment); fragTrans.addToBackStack(null); fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); fragTrans.commit(); //here you update the variable selectedFragment = newFragment; } 

То вы можете использовать selectedFragment везде, где хотите

Привет, я знаю, что это очень старая проблема, но я хотел бы поделиться своим решением.

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

 public class MyHelperClass{ private static ArrayList<Fragment> listFragment = new ArrayList<>(); public static void addFragment(Fragment f){ if(!existFragment(f)) { listFragment.add(f); } } public static void removeFragment(){ if(listFragment.size()>0) listFragment.remove(listFragment.size()-1); } public static Fragment getCurrentFragment(){ return listFragment.get(listFragment.size()-1); } public static int sizeFragments(){ return listFragment.size(); } private static Boolean existFragment(Fragment f){ Boolean ret = false; for(Fragment fragment : listFragment){ if (fragment.getClass() == f.getClass()){ ret = true; } } return ret; } 

И в основное действие я переопределяю метод onAttachFragment

 @Override public void onAttachFragment(Fragment f) { super.onAttachFragment(f); MyHelperClass.addFragment(f); } 

А также, я переопределяю метод onBackPressed:

 @Override public void onBackPressed() { General.removeFragment(); if(General.sizeFragments()>0){ Fragment fragment = null; Class fragmentClass = General.getCurrentFragment().getClass(); try { fragment = (Fragment) fragmentClass.newInstance(); fragment.setArguments(General.getCurrentFragment().getArguments()); } catch (Exception e) { e.printStackTrace(); } fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit(); }else{ super.onBackPressed(); } } 

Поэтому таким образом вы можете в любой момент получить активный фрагмент с MyHelperClass.getCurrentFragment ()

Я надеюсь, что это будет полезно для всех

С уважением

Ну, я думаю, вы хотите увидеть, в каком фрагменте у меня есть предположение, что есть решение, которое я считаю не лучшим, но оно работает сначала


Вы должны создать свой родительский фрагмент, чтобы он расширил фрагмент


 public class Fragment2 extends Fragment { private static position; public static int getPosition() { return position; } public static void setPosition(int position) { FragmentSecondParent.position = position; } } 

второй

Вы должны расширять его в каждом фрагменте и в каждой записи в onCreateView

 setPosition(//your fragmentposition here) 

В третьих


Где вы хотите получить текущий фрагмент, вы должны


Напишите это

 Fragment2 fragment= (Fragment2) getSupportFragmentManager() .findFragmentById(R.id.fragment_status); int position = fragment.getPosition(); if(//position condition) { //your code here } 

Это лучший способ:

  android.app.Fragment currentFragment=getFragmentManager().findFragmentById(R.id.main_container); if(currentFragment!=null) { String[] currentFragmentName = currentFragment.toString().split("\\{"); if (currentFragmentName[0].toString().equalsIgnoreCase("HomeSubjectFragment")) { fragment = new HomeStagesFragment(); tx = getSupportFragmentManager().beginTransaction(); tx.replace(R.id.main_container, fragment); tx.addToBackStack(null); tx.commit(); } else if(currentFragmentName[0].toString().equalsIgnoreCase("HomeStagesFragment")) { new AlertDialog.Builder(this) .setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finish(); } }) .setNegativeButton("No", null) .show(); } } 

Не забудьте определить это в заголовке:

 private Fragment fragment; FragmentTransaction tx; 

В таких ситуациях особенно удобно использовать шину событий (например, Otto , EventBus или RxJava Bus ).

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

  1. Убедитесь, что вы соблюдаете жизненный цикл фрагмента и регистрируете / отменяете регистрацию шины событий в соответствующее время
  2. В тот момент, когда вам нужно знать текущий видимый фрагмент и выполнить набор действий. Снимать событие с автобусом событий.

Все видимые фрагменты, зарегистрированные на шине, будут выполнять необходимые действия.

Модификация кода Мэтта Момбреа:

 /** * Search a FragmentActivity for a visible fragment of the specified class. * * @this the FragmentActivity * @param fClass the fragment class, eg MyFragment.class * @param <F> the fragment class, need not be explicitly specified * @return a visible fragment of the specified class, or null if not found */ public <F extends Fragment> F getVisibleFragment(Class<F> fClass) { FragmentManager fragmentManager = getSupportFragmentManager(); List<Fragment> fragments = fragmentManager.getFragments(); if (fragments != null) { for (Fragment fragment : fragments) { if (fragment != null && fragment.isVisible() && fClass.isInstance(fragment)) { return (F) fragment; } } } return null; } 

использовать:

 MyFragment mf = getVisibleFragment(MyFragment.class); if (mf != null) { mf.someMethod(...); ... } else { ... }