Android: imposta l'ID del frammento


111

Come posso impostare una Fragment's in Idmodo da poterla utilizzare getSupportFragmentManager().findFragmentById(R.id.--)?


Puoi impostarlo nel file xml di layout
Vladimir Eremeev

Risposte:


117

Non è possibile impostare l'ID di un frammento a livello di codice .

Tuttavia, esiste un String tagelemento che puoi impostare all'interno di FragmentTransaction che può essere utilizzato per identificare in modo univoco un frammento.

Come Aleksey ha sottolineato, è possibile passare un ID di FragmentTransaction's add(int, Fragment)metodo. Tuttavia, questo non specifica l'ID per un frammento. Specifica l'ID di a ViewGroupin cui inserire il file Fragment. Questo non è così utile per lo scopo che mi aspetto tu abbia, perché non identifica in modo univoco Fragments, ma ViewGroups. Questi ID sono contenitori a cui uno o più frammenti possono essere aggiunti dinamicamente. L'utilizzo di un tale metodo per identificare Fragmenti messaggi di posta elettronica richiederebbe di aggiungere ViewGroupdinamicamente messaggi di posta elettronica al layout per ogni Fragmentinserimento. Sarebbe piuttosto macchinoso.

Quindi, se la vostra domanda è come creare un identificatore univoco per un frammento si sta aggiungendo in modo dinamico, la risposta è quella di utilizzare FragmentTransaction's add (int containerViewId, Fragment frammento, tag String) metodo e FragmentManager' s findFragmentByTag (String) metodo.

In una delle mie app, sono stato costretto a generare stringhe in modo dinamico. Tuttavia, non è così costoso rispetto all'effettiva FragmentTransaction.

Un altro vantaggio del metodo tag è che può identificare un frammento che non viene aggiunto all'interfaccia utente. Vedere il metodo add (Fragment, String) di FragmentTransaction . Fragmentnon è necessario avere Views! Possono anche essere usati per mantenere uno stato temporaneo tra le modifiche alla configurazione!


Se utilizzo il tag e non l'ID per il frammento, come dovrei utilizzare la chiamata di sostituzione che richiede un ID risorsa frammento?
Namratha

12
@TomDignan, che ne dici di un frammento che verrà aggiunto in un ViewPager? Come posso impostare il suo tag? Non posso usare le transazioni in questa situazione.
GuilhE

1
@GuilhE Activity fornisce un metodo addFragment () a cui puoi fare riferimento dal viewpager. Mantenere il tag prima di ciò potrebbe essere ottenuto con una hashmap.
Thomas Dignan,

1
La risposta può essere modificata un po 'per sottolineare che è possibile impostare l'ID nel layout xml? Perché personalmente non ho letto altre domande e avevo l'impressione che non ci fosse alcun modo per impostare id al frammento ...
Ivan

41

Risulta che potresti non aver bisogno di conoscere l'id del frammento.

Dai documenti:

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.

La parte importante è "come ID contenitore quando aggiunto in una transazione".

così:

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

e poi

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

ti darà qualunque (fantastico) frammento contenuto in R.id.fragment_holder.


4

Nella maggior parte dei casi puoi utilizzare il tag fragment oltre che l'ID.
Puoi impostare il valore del tag in FragmentTransaction.add(Fragment fragment, String tag );. Quindi puoi usare il comando FragmentManager.findFragmentByTag(String tab)per trovare il frammento in questione.


2

Come hanno già menzionato Tom e altri, ci sono modi per mettere un tag su un frammento e usare quel tag per l'identificazione. Un problema successivo che ho riscontrato con queste soluzioni è che il frammento non riceve un tag finché non è associato all'attività (o, in realtà, al FragmentManager). Cosa fare se è necessario identificare un frammento prima che sia stato etichettato?

Le mie soluzioni finora si basano tutte sul trucco (Java) più antico del mondo: creare un frammento di template minimalista che prende un id in uno dei suoi costruttori e fornisce un getFragmentId()metodo che restituisce quell'id. Poi ho lasciato che quei frammenti che richiedono un'identificazione precoce estendano quel modello e; Ecco! Problema risolto.

Questa soluzione potrebbe, sfortunatamente, richiedere una serie di frammenti di template, uno per ogni tipo di frammento ListFragment, DialogFragmento semplicemente vecchi Fragment(POFO ?!) che richiedono un'identificazione precoce. Ma questo è gestibile nel caso di frammenti credo, considerando i guadagni forniti.

Scusa per aver strappato le ferite in via di guarigione :-)

Saluti!


0

Utilizza il seguente:

Per aggiungere un frammento:

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

Per identificare il frammento esistente:

getFragmentManager().findFragmentByTag(fragmentName);

La risposta non è rilevante per la domanda. Aggiorna la risposta. Happy Coding
CodeWithVikas

-1

Quando si utilizza un tag, assicurarsi di aggiungere il file

fragmentTransaction.addToBackStack(null); 

in modo che il frammento venga ripristinato anziché distrutto come indicato nelle guide per gli sviluppatori.

Se non chiami addToBackStack () quando esegui una transazione che rimuove un frammento, quel frammento viene distrutto quando viene eseguito il commit della transazione e l'utente non può tornare ad esso. Considerando che, se chiami addToBackStack () durante la rimozione di un frammento, il frammento viene interrotto e viene successivamente ripreso se l'utente torna indietro.

Puoi trovarlo alla fine di questa pagina .

Ho perso circa 30 minuti cercando di capire perché il mio frammento non veniva trovato tramite una semplice findFragmentByTag();chiamata


-2

Oltre alla risposta di Tom, il metodo di sostituzione supporta anche il tag fragment, oltre al metodo di aggiunta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.