Obtenir l'objet fragment actuel


175

Dans mon main.xmlj'ai

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

Et je mets un objet fragment comme celui-ci

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

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

Il définit différents types d'objets Fragment ( FragmentType2,FragmentType3,...) à des moments différents. Maintenant, à un moment donné, j'ai besoin d'identifier quel objet est actuellement là.

En bref, je dois faire quelque chose comme ça:

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

J'ai essayé ce qui suit

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

et

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

Mais les deux objets (titleFragmentById et titleFragmentByTag) sont.null
Ai-je manqué quelque chose?
J'utilise et je Compatibility Package, r3développe pour API level 7.

findFragmentById()et findFragmentByTag()fonctionnera si nous avons défini le fragment en utilisant fragmentTransaction.replaceou fragmentTransaction.add, mais le fera return nullsi nous avons défini l'objet en xml (comme ce que j'ai fait dans my main.xml). Je pense qu'il me manque quelque chose dans mes fichiers XML.



La réponse @CommonsWare vous aide-t-elle, car je suis toujours nul?
IntoTheDeep

Réponses:


253

Maintenant, à un moment donné, j'ai besoin d'identifier quel objet est actuellement là

Appelez findFragmentById()sur FragmentManageret déterminer quel fragment est dans votre R.id.frameTitlerécipient.


1
Merci pour votre réponse. Cela fonctionnera si nous avons défini fragment en utilisant fragmentTransaction.replace ou fragmentTransaction.addmais ne l'obtiendra pas si nous l'avons défini sur xml. Voir ma modification 2
Labeeb Panampullan

9
@Labeeb P: Vous ne pouvez pas modifier les fragments déclarés dans les ressources de mise en page.
CommonsWare

Créer une classe pour contenir l'onglet / fragment actuellement visible fonctionnera également, j'ai juste essayé cela. J'espère qu'il n'y a pas d'échecs.
Skynet

@CommonsWare findFragmentByTagrenvoie null en cas de ActionBartabulations. Dans mon Activityqui s'étend, ActionBarActivityj'ajoute d'abord des onglets ActionBar, puis je le trouve!
Muhammad Babar

1
@MuhammadBabar: Vous pouvez essayer executePendingTransactions()sur FragmentManageraprès avoir appelé commit()à la transaction, bien que je ne l' ai pas essayé. Ou vous pouvez utiliser setContentView()pour utiliser un fichier de mise en page avec une <fragment>balise. L'un ou l'autre se produit de manière synchrone, et le fragment existera donc dans l' onCreate()appel lui-même où vous avez utilisé executePendingTransaction()ou setContentView(). Sinon, un ordinaire FragmentTransactionest traité de manière asynchrone, et il n'aura même pas commencé à la onCreate()fin du temps .
CommonsWare

110

Essaye ça,

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

cela vous donnera le fragment actuel, alors vous pouvez le comparer à la classe de fragment et faire votre travail.

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

Où mettre cette ligne?
Anand Savjani

9
Parfois, vous devez utiliser à la getSupportFragmentManager()place et obtiendrez null sans la supportpièce
Muz

Supprimez les guillemets autour de "NOM DE VOTRE CLASSE DE FRAGMENT".
Alan Nelson

37

Je pense que vous pouvez utiliser l' événement onAttachFragment peut être utile pour détecter quel fragment est actif.

@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
je peux savoir quel fragment je suis attaché. Mon problème est que lorsque je change l'orientation, je dois afficher la même vue pas une autre vue, alors comment faire cela.
Androi Developer

7
Cela ne fonctionne pas car cela ne met pas à jour le fragment actif lorsque vous revenez en arrière.
Justin le

1
@Justin, nous devons donc simplement utiliser onDetach avec une liste de
références faibles

12

Je pense que tu devrais faire:

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

La raison en est que vous définissez la balise "fragmentTag" sur le dernier fragment que vous avez ajouté (lorsque vous avez appelé replace).


Merci, je l'ai corrigé. C'est une faute de frappe lors de la rédaction de cette question. Cela fonctionnera si nous avons défini fragment en utilisant fragmentTransaction.replace ou fragmentTransaction.addmais ne l'obtiendra pas si nous l'avons défini sur xml. Voir ma modification 2
Labeeb Panampullan

Merci beaucoup! J'ai résolu mon problème!
Jonas Gröger

2
cette solution ne signifie-t-elle pas que vous devez mettre la même balise pour plusieurs fragments? sinon, comment sauriez-vous que fragmentTagla balise correspond au fragment actuel?
Jeudi

12

Vous pouvez obtenir la liste des fragments et regarder le dernier.

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

Mais parfois (lorsque vous revenez en arrière), la taille de la liste reste la même mais certains des derniers éléments sont nuls. Donc, dans la liste, j'ai itéré jusqu'au dernier fragment non nul et je l'ai utilisé.

    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
N'utilisez pas la getFragments()méthode. Il est marqué @hideet n'était pas censé être inclus avec le fichier jar de la bibliothèque de support. Il ne doit pas être considéré comme faisant partie de l'API exportée.
James Wald

Hé, alors ils auraient dû créer une méthode qui vous permette de faire exactement ce que vous faites getFragments(), car vous en avez souvent besoin. Je pense qu'il est également accessible au public maintenant.
EpicPandaForce

10

C'est la solution la plus simple et cela fonctionne pour moi.

1.) vous ajoutez votre fragment

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

Il est peut-être tard, mais j'espère que cela aidera quelqu'un d'autre, également @CommonsWare a publié la bonne réponse.

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

9
Cela ne vous permet pas d'obtenir le fragment actif, car vous ne connaissez pas nécessairement l'identifiant ou la balise.
Justin le

7

Le moyen le plus simple est peut-être:

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

Ça a marché pour moi


6

Vous pouvez créer un champ dans votre classe d'activités parentale:

public class MainActivity extends AppCompatActivity {

    public Fragment fr;

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

}

Et puis à l'intérieur de chaque classe de fragment:

public class SomeFragment extends Fragment {

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

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

Votre champ 'fr' est l'objet du fragment actuel

Cela fonctionne aussi avec popBackStack ()


4

Je sais que ça fait un moment, mais je vais ici au cas où cela aiderait quelqu'un.

La bonne réponse est de loin (et celle choisie) celle de CommonsWare. J'avais le même problème que celui publié, le suivant

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

continué à retourner null. Mon erreur était vraiment idiote, dans mon fichier xml:

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

L'erreur était que j'avais android: tag au lieu d' android: id .


2

La réponse @Hammer a fonctionné pour moi, j'utilise pour contrôler un bouton d'action flottant

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

2

Si vous étendez à partir de AbstractActivity, vous pouvez utiliser la méthode getFragments ():

for (Fragment f : getFragments()) {
    if (f instanceof YourClass) {
        // do stuff here
    }
}

1

Si vous définissez le fragment dans le format XML de l'activité, Activityassurez-vous d'appeler setContentView()avant d'appeler findFragmentById().


1

Si vous utilisez le BackStack ... et UNIQUEMENT si vous utilisez le back stack, essayez ceci:

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

Cela vous donnera le nom de classe de fragment actuel ->

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

0
  1. Faites une vérification (quel fragment dans le conteneur d'activité) dans la méthode onStart;

    @Override
    protected void onStart() {
    super.onStart();
    Fragment fragmentCurrent = getSupportFragmentManager.findFragmentById(R.id.constraintLayout___activity_main___container);
    }
  2. Certains vérifient:

    if (fragmentCurrent instanceof MenuFragment) 
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.