Получить текущий фрагмент объекта


175

По моему main.xmlу меня

  <FrameLayout
        android:id="@+id/frameTitle"
        android:padding="5dp"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:background="@drawable/title_bg">
            <fragment
              android:name="com.fragment.TitleFragment"
              android:id="@+id/fragmentTag"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content" />

  </FrameLayout>

И я устанавливаю фрагмент объекта, как это

FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment newFragment = new FragmentType1();
fragmentTransaction.replace(R.id.frameTitle, casinodetailFragment, "fragmentTag");

// fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

Он устанавливает разные типы объектов Fragment ( FragmentType2,FragmentType3,...) в разное время. Теперь в какой-то момент мне нужно определить, какой объект в данный момент находится там.

В короткий мне нужно сделать что - то вроде этого:

Fragment currentFragment = //what is the way to get current fragment object in FrameLayout R.id.frameTitle

Я попробовал следующее

TitleFragment titleFragmentById = (TitleFragment) fragmentManager.findFragmentById(R.id.frameTitle);

и

    TitleFragment titleFragmentByTag = (TitleFragment) fragmentManager.findFragmentByTag("fragmentTag");

Но оба объекта (titleFragmentById и titleFragmentByTag) -null
Я что-то пропустил?
Я использую Compatibility Package, r3и разрабатываю для API level 7.

findFragmentById()и findFragmentByTag()будет работать, если мы установили фрагмент с помощью fragmentTransaction.replaceили fragmentTransaction.add, но будет, return nullесли мы установили объект в XML (как то, что я сделал в моем main.xml). Я думаю, что чего-то не хватает в моих файлах XML.



Помогает ли вам ответ @CommonsWare, потому что я все еще получаю ноль?
— IntoTheDeep

Ответы:


253

Теперь в какой-то момент мне нужно определить, какой объект в настоящее время там

Вызов findFragmentById()на FragmentManagerи определить , какой фрагмент находится в вашем R.id.frameTitleконтейнере.


1
Спасибо за ваш ответ. Это будет работать, если мы установили фрагмент с помощью fragmentTransaction.replace или, fragmentTransaction.addно не получится, если мы установили его на xml. См. Мое редактирование 2
— Labeeb Panampullan

9
@Labeeb P: Вы не можете изменять фрагменты, объявленные в ресурсах макета.
— CommonsWare

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

@CommonsWare findFragmentByTagвозвращает ноль в случае ActionBarвкладок. В моем Activityрасширении ActionBarActivityя сначала добавляю вкладки, ActionBarа потом нахожу его!
— Мухаммед Бабар,

1
@MuhammadBabar: Вы можете попробовать executePendingTransactions()на FragmentManagerпосле вызова commit()на сделку, хотя я не пробовал. Или вы можете использовать setContentView()файл макета с <fragment>тегом. Любое из этих событий происходит синхронно, и поэтому фрагмент будет существовать внутри самого onCreate()вызова, где вы использовали executePendingTransaction()или setContentView(). В противном случае обычный FragmentTransactionпроцесс обрабатывается асинхронно, и он даже не начнется к концу времени onCreate().
— CommonsWare

110

Попробуй это,

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

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

    if (currentFragment instanceof NameOfYourFragmentClass) {
     Log.v(TAG, "find the current fragment");
  }

Где поставить эту строку?
— Ананд Савьяни

9
Иногда вы должны использовать getSupportFragmentManager()вместо этого, и будет нулевой без supportчасти
— Muz

Удалите цитаты вокруг "НАЗВАНИЕ ВАШЕГО ФРАГМЕНТНОГО КЛАССА".
— Алан Нельсон

37

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

@Override
public void onAttachFragment(Fragment fragment) {
    // TODO Auto-generated method stub
    super.onAttachFragment(fragment);

    Toast.makeText(getApplicationContext(), String.valueOf(fragment.getId()), Toast.LENGTH_SHORT).show();

}

3
я могу получить какой фрагмент я прикрепил. Мне кажется, что когда я меняю ориентацию, мне нужно отобразить то же представление, а не другое, так как это сделать.
— Androi Developer

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

1
@Justin, поэтому нам просто нужно использовать onDetach также со списком
— слабых

12

Я думаю, что вы должны сделать:

Fragment currentFragment = fragmentManager.findFragmentByTag("fragmentTag");

Причина в том, что вы устанавливаете тэг «fragTag» на последний добавленный вами фрагмент (когда вы вызываете replace).


Спасибо, я исправил это. Это опечатка при написании этого вопроса. Это будет работать, если мы установили фрагмент с помощью fragmentTransaction.replace или, fragmentTransaction.addно не получится, если мы установили его на xml. См. Мое редактирование 2
— Labeeb Panampullan

Спасибо вам большое! Решил мою проблему!
— Йонас Грёгер

2
Разве это решение не означает, что вы должны поставить один и тот же тег для нескольких фрагментов? иначе как бы вы узнали, fragmentTagявляется ли тег для текущего фрагмента?
— Thupten

12

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

    FragmentManager fm = getSupportFragmentManager();
    List<Fragment> fragments = fm.getFragments();
    Fragment lastFragment = fragments.get(fragments.size() - 1);

Но иногда (при переходе назад) размер списка остается прежним, но некоторые из последних элементов являются нулевыми. Так что в списке я итерировал до последнего ненулевого фрагмента и использовал его.

    FragmentManager fm = getSupportFragmentManager();
    if (fm != null) {
        List<Fragment> fragments = fm.getFragments();
        if (fragments != null) {
            for(int i = fragments.size() - 1; i >= 0; i--){
                Fragment fragment = fragments.get(i);
                if(fragment != null) {
                    // found the current fragment

                    // if you want to check for specific fragment class
                    if(fragment instanceof YourFragmentClass) {
                        // do something
                    }
                    break;
                }
            }
        }
    }

3
Не используйте getFragments()метод. Он помечен @hideи не должен был быть включен в jar библиотеки поддержки. Его не следует рассматривать как часть экспортируемого API.
— Джеймс Вальд

Хех, тогда они должны были создать метод, который позволяет вам делать именно то, что getFragments()делает, потому что он вам нужен довольно часто. Я думаю, что это на самом деле публично сейчас тоже.
— EpicPandaForce

10

Это самое простое решение и работа для меня.

1.) Вы добавляете свой фрагмент

ft.replace(R.id.container_layout, fragment_name, "fragment_tag").commit();

2.)

FragmentManager fragmentManager = getSupportFragmentManager();

Fragment currentFragment = fragmentManager.findFragmentById(R.id.container_layout);

if(currentFragment.getTag().equals("fragment_tag"))

{

 //Do something

}

else

{

//Do something

}

9

Возможно, уже поздно, но я надеюсь, что это поможет кому-то еще, также @CommonsWare опубликовал правильный ответ.

FragmentManager fm = getSupportFragmentManager();
Fragment fragment_byID = fm.findFragmentById(R.id.fragment_id);
//OR
Fragment fragment_byTag = fm.findFragmentByTag("fragment_tag");

9
Это не позволяет вам получить активный фрагмент, так как вы не обязательно знаете идентификатор или тег.
— Джастин

7

Может быть, самый простой способ это:

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;
}

У меня сработало


6

Вы можете создать поле в родительском классе деятельности:

public class MainActivity extends AppCompatActivity {

    public Fragment fr;

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

}

И затем внутри каждого класса фрагмента:

public class SomeFragment extends Fragment {

@Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        ((MainActivity) getActivity()).fr = this;
}

Ваше поле 'fr' является текущим фрагментом Object

Работает также с popBackStack ()


4

Я знаю, что это было давно, но я сделаю это здесь, если это кому-нибудь поможет.

На данный момент правильный ответ (и выбранный) - это ответ CommonsWare. У меня была такая же проблема, как опубликовано, следующее

MyFragmentClass fragmentList = 
            (MyFragmentClass) getSupportFragmentManager().findFragmentById(R.id.fragementID);

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

<fragment
    android:tag="@+id/fragementID"
    android:name="com.sf.lidgit_android.content.MyFragmentClass"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
/>

Ошибка была в том, что у меня был android: тег INSTEAD OF android: id .


2

Ответ @Hammer работал на меня, я использую, чтобы управлять плавающей кнопкой действия

final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View view) {
            android.app.Fragment currentFragment = getFragmentManager().findFragmentById(R.id.content_frame);
            Log.d("VIE",String.valueOf(currentFragment));
            if (currentFragment instanceof PerfilFragment) {
                PerfilEdit(view, fab);
            }
        }
});


1

Если вы определяете фрагмент в XML-структуре действия, то Activityубедитесь, что вы вызываете setContentView()перед вызовом findFragmentById().


1

Если вы используете BackStack ... и ТОЛЬКО если вы используете задний стек, попробуйте это:

rivate Fragment returnToPreviousFragment() {

    FragmentManager fm = getSupportFragmentManager();

    Fragment topFrag = null;

    int idx = fm.getBackStackEntryCount();
    if (idx > 1) {
        BackStackEntry entry = fm.getBackStackEntryAt(idx - 2);
        topFrag = fm.findFragmentByTag(entry.getName());
    }

    fm.popBackStack();

    return topFrag;
}

0

Это даст вам имя текущего фрагмента класса ->

String fr_name = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();

0
  1. Выполните проверку (какой фрагмент в контейнере активности) в методе onStart;

    @Override
    protected void onStart() {
    super.onStart();
    Fragment fragmentCurrent = getSupportFragmentManager.findFragmentById(R.id.constraintLayout___activity_main___container);
    }
  2. Некоторые проверяют:

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