android-layout fragment - Android:ho bisogno di alcuni chiarimenti sui frammenti rispetto alle attività e alle visualizzazioni




in xml (11)

Frammenti vive all'interno dell'Attività e ha:

  • il suo ciclo di vita
  • il proprio layout
  • i suoi frammenti figlio e così via

Pensa ai Frammenti come a un'attività secondaria dell'attività principale a cui appartiene, non può esistere e può essere chiamato / riutilizzato ancora e ancora. Spero che questo ti aiuti :)

Nell'API Android 11+, Google ha rilasciato una nuova classe chiamata Fragment .

Nei video, Google suggerisce che, laddove possibile ( link1 , link2 ), dovremmo utilizzare i frammenti anziché le attività, ma non hanno spiegato esattamente perché.

Qual è lo scopo dei frammenti e alcuni possibili usi di essi (diversi da alcuni esempi di interfaccia utente che possono essere facilmente ottenuti con viste / layout semplici)?

La mia domanda riguarda i frammenti:

  1. Quali sono gli scopi dell'utilizzo di un frammento?
  2. Quali sono i vantaggi e gli svantaggi dell'utilizzo dei frammenti rispetto all'utilizzo di attività / viste / layout?

Domande bonus:

  1. Puoi dare alcuni usi davvero interessanti per i frammenti? Cose che Google non ha menzionato nei loro video?
  2. Qual è il modo migliore per comunicare tra i frammenti e le attività che li contengono?
  3. Quali sono le cose più importanti da ricordare quando usi i frammenti? Eventuali suggerimenti e avvertenze sulla tua esperienza?

Le attività sono i componenti a schermo intero nell'app con la barra degli strumenti, tutto il resto sono preferibilmente Frammenti. Un'attività principale a schermo intero con una barra degli strumenti può avere più riquadri, pagine scorrevoli, finestre di dialogo, ecc. (Tutti i frammenti) a cui è possibile accedere dal genitore e comunicare tramite il genitore.

Esempio -

Attività A, Attività B, Attività C -

  • Tutte le attività devono avere lo stesso codice ripetuto, per mostrare una barra degli strumenti di base per esempio o ereditare da un'attività principale (diventa scomodo da gestire).
  • Per passare da un'attività all'altra, è necessario che tutti siano in memoria (in alto) o che uno debba essere distrutto affinché l'altro possa aprirsi.
  • La comunicazione tra le attività può essere effettuata tramite Intenti.

vs

Attività A, Frammento 1, Frammento 2, Frammento 3 -

  • Nessuna ripetizione del codice, tutti gli schermi hanno barre degli strumenti ecc. Da quella attività.
  • Diversi modi per passare da un frammento a quello successivo - visualizzare il cercapersone, il multi riquadro ecc.
  • L'attività ha la maggior parte dei dati, quindi è necessaria una comunicazione inter-frammento minima. Se ancora necessario, può essere fatto facilmente tramite le interfacce.
  • I frammenti non hanno bisogno di essere a schermo intero, carico di flessibilità nel progettarli.
  • I frammenti non hanno bisogno di gonfiare il layout se le viste non sono necessarie.
  • Diverse attività possono utilizzare lo stesso frammento.

1. Obiettivi dell'utilizzo di un frammento?

  • Ans:
    1. Affrontare le differenze di fattore di forma del dispositivo.
    2. Trasmissione delle informazioni tra le schermate dell'app.
    3. Organizzazione dell'interfaccia utente.
    4. Metafore avanzate dell'interfaccia utente.

Non sono sicuro di quale video si stia riferendo, ma dubito che stiano dicendo che dovresti usare i frammenti invece delle attività, perché non sono direttamente intercambiabili. C'è in realtà una voce abbastanza dettagliata nella Guida Dev, prendere in considerazione la lettura per i dettagli.

In breve, i frammenti vivono all'interno delle attività e ogni attività può ospitare molti frammenti. Come le attività, hanno uno specifico ciclo di vita, a differenza delle attività, non sono componenti applicativi di primo livello. I vantaggi dei frammenti includono il riutilizzo del codice e la modularità (ad esempio, utilizzando la stessa visualizzazione elenco in molte attività), inclusa la possibilità di creare interfacce multi-riquadro (utili soprattutto sui tablet). Lo svantaggio principale è (alcuni) una maggiore complessità. Generalmente puoi ottenere la stessa cosa con viste (personalizzate) in un modo non standard e meno affidabile.


Un frammento vive all'interno di un'attività.

Mentre un'attività vive su se stessa.


# 1 e # 2 quali sono gli scopi dell'utilizzo di un frammento e quali sono i vantaggi e gli svantaggi dell'utilizzo di frammenti rispetto all'utilizzo di attività / viste / layout?

I frammenti sono la soluzione di Android per la creazione di interfacce utente riutilizzabili. È possibile ottenere alcune delle stesse cose utilizzando le attività e i layout (ad esempio utilizzando include). Però; i frammenti sono collegati all'API di Android, da HoneyComb e successivi. Lasciami elaborare;

  • ActionBar . Se desideri schede per ActionBar.TabListener nella tua app, vedi rapidamente che ActionBar.TabListener interfaccia ActionBar.TabListener ti offre un FragmentTransaction come argomento di input per il metodo onTabSelected . Probabilmente potresti ignorarlo e fare qualcosa di diverso e intelligente, ma dovresti lavorare contro l'API, non con esso.

  • FragmentManager gestisce «indietro» per te in modo molto intelligente. Indietro non significa tornare all'ultima attività, come per le attività regolari. Significa tornare allo stato del frammento precedente.

  • Puoi utilizzare il fantastico ViewPager con FragmentPagerAdapter per creare interfacce di scorrimento. Il codice FragmentPagerAdapter è molto più pulito di un normale adattatore e controlla le istanze dei singoli frammenti.

  • La tua vita sarà molto più facile se usi Fragments quando provi a creare applicazioni per telefoni e tablet. Dato che i frammenti sono così legati alle API Honeycomb +, ti consigliamo di usarli anche sui telefoni per riutilizzare il codice. È qui che la libreria di compatibilità è utile.

  • Potresti anche e dovresti usare i frammenti per le app pensate solo per i telefoni. Se hai in mente la portabilità. Uso ActionBarSherlock e le librerie di compatibilità per creare app "ICS in cerca", che sembrano identiche fino alla versione 1.6. Ottieni le ultime funzionalità come ActionBar , con schede, overflow, barra delle azioni divise, viewpager ecc.

Bonus 2

Il modo migliore per comunicare tra i frammenti è intento. Quando si preme qualcosa in un frammento, in genere si chiama StartActivity() con i dati su di esso. L'intento viene trasmesso a tutti i frammenti dell'attività avviata.


Questa è un'informazione importante che ho trovato sui frammenti:

Storicamente ogni schermata in un'app per Android è stata implementata come un'attività separata. Ciò crea una sfida nel passare le informazioni tra le schermate perché il meccanismo Android Intent non consente il passaggio di un tipo di riferimento (ad es. Oggetto) direttamente tra le attività. Invece l'oggetto deve essere serializzato o un riferimento accessibile globalmente reso disponibile.

Rendendo ogni schermo un frammento separato, questo mal di testa che passa i dati è completamente evitato. I frammenti esistono sempre nel contesto di una determinata attività e possono sempre accedere a tale attività. Memorizzando le informazioni di interesse all'interno dell'Attività, il frammento di ciascuna schermata può semplicemente accedere al riferimento dell'oggetto tramite l'attività.


Un frammento rappresenta un comportamento o una parte dell'interfaccia utente in un'attività. È possibile combinare più frammenti in un'unica attività per creare un'interfaccia utente a più riquadri e riutilizzare un frammento in più attività. È possibile pensare a un frammento come a una sezione modulare di un'attività, che ha il proprio ciclo di vita, riceve i propri eventi di input e che è possibile aggiungere o rimuovere mentre l'attività è in esecuzione.

  • puoi manipolare ciascun frammento in modo indipendente, come aggiungerlo o rimuoverlo. Quando si esegue una transazione di questo tipo, è possibile aggiungerla anche a uno stack posteriore gestito dall'attività: ogni voce dello stack secondario dell'attività è un record della transazione del frammento che si è verificata. Lo stack posteriore consente all'utente di invertire una transazione frammento (navigare all'indietro), premendo il pulsante Indietro.

  • Quando si aggiunge un frammento come parte del proprio layout di attività, esso vive in un ViewGroup all'interno della gerarchia di visualizzazione dell'attività e il frammento definisce il proprio layout di visualizzazione. È possibile inserire un frammento nel layout dell'attività dichiarando il frammento nel file di layout dell'attività, come elemento o dal codice dell'applicazione aggiungendolo a un ViewGroup esistente. Tuttavia, non è richiesto che un frammento faccia parte del layout dell'attività; puoi anche usare un frammento senza la sua interfaccia utente come lavoratore invisibile per l'attività.

  • Ad esempio: se dovessi utilizzare NavigationDrawer senza Fragments, sarebbe meglio mantenere l'istanza di NavigationDrawer in una singola attività e quando navighi nell'app scegliendo tra gli elementi in NavigationDrawer, ognuna delle attività avviate non dovrebbe implementare NavigationDrawer, ma invece dovrebbe implementare il pulsante Indietro per tornare alla "principale" / singola attività in cui è stato implementato NavigationDrawer.

    Nota: se si desidera implementare NavigationDrawer in più attività, è necessario ricreare una nuova istanza di NavigationDrawer in ogni attività che si desidera visualizzarla.

    Suppongo che questo sarebbe uno svantaggio rispetto all'utilizzo di Frammenti, mentre se hai usato un frammento non avresti bisogno di molte istanze del cassetto ne avresti bisogno solo uno.

    Cassetto con frammenti anziché attività

    Se si utilizza NavigationDrawer con Fragments, il cassetto deve essere implementato in una singola attività e quando viene selezionato ciascun elemento del cassetto, il loro contenuto viene visualizzato in ciascuno dei propri frammenti.

  • Comunicare tra frammento alla sua attività : Per consentire a un frammento di comunicare fino alla sua attività, è possibile definire un'interfaccia nella classe Fragment e implementarla all'interno dell'attività. Il frammento acquisisce l'implementazione dell'interfaccia durante il suo ciclo di vita onAttach () e può quindi chiamare i metodi di interfaccia per comunicare con l'attività.

    public class YourFragment extends ListFragment {
    OnSelectedListener mCallback;
    
    // Container Activity must implement this interface
    public interface OnSelectedListener {
        public void onItemSelected(int position);
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.your_view, container, false);
    }
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    
        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnSelectedListener");
        }
    }
    
    }...
    

Ora il frammento può recapitare messaggi all'attività chiamando il metodo onItemSelected () (o altri metodi nell'interfaccia) utilizzando l'istanza mCallback dell'interfaccia OnSelectedListener.

public static class MainActivity extends Activity
        implements YourFragment.OnSelectedListener{
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
    }

    public void onItemSelected(int position) {
        // The user selected the headline of an article from the YourFragment
        // Do something here to display that article

        YourFragment yourFrag = (YourFragment)
                getSupportFragmentManager().findFragmentById(R.id.your_fragment);

        if (yourFrag != null) {
            // If your frag is available, we're in two-pane layout...

            // Call a method in the YourFragment to update its content
            yourFrag.updateView(position);
        } else {
            // Otherwise, we're in the one-pane layout and must swap frags...

            // Create fragment and give it an argument for the selected item
            YourFragment newFragment = new YourFragment();
            Bundle args = new Bundle();
            args.putInt(YourFragment.ARG_POSITION, position);
            newFragment.setArguments(args);

            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

            // Replace whatever is in the fragment_container view with this fragment,
            // and add the transaction to the back stack so the user can navigate back
            transaction.replace(R.id.fragment_container, newFragment);
            transaction.addToBackStack(null);

            // Commit the transaction
            transaction.commit();
        }
    }
}

So che questo è già stato discusso a morte, ma vorrei aggiungere qualche altro punto:

  • I frags possono essere utilizzati per popolare Menu s e possono gestire i clic MenuItem da soli. Dando così ulteriori opzioni di modulazione per le tue attività. Puoi fare cose di ContextualActionBar e così via senza che la tua attività ne sia a conoscenza e in pratica può disaccoppiarla dalle cose di base che la tua attività gestisce (Navigazione / Impostazioni / Informazioni).

  • Un genitore Frag con bambino Frags può darti ulteriori opzioni per modulare i tuoi componenti. Ad esempio puoi facilmente scambiare i Frags, inserire nuovi Frags all'interno di un Pager o rimuoverli, riordinandoli. Tutto senza che la tua attività ne sappia nulla, concentrandosi solo sulle cose di livello superiore.


Un frammento è una parte dell'interfaccia utente o del comportamento di un'applicazione che può essere inserita in un'attività che consente una progettazione di attività più modulare. Non sarà sbagliato se diciamo che un frammento è una specie di subattività.

Di seguito sono riportati i punti importanti su un frammento:

  1. Un frammento ha il proprio layout e il proprio comportamento con i propri callback del ciclo di vita.

  2. È possibile aggiungere o rimuovere frammenti in un'attività mentre l'attività è in esecuzione.

  3. È possibile combinare più frammenti in un'unica attività per creare un'interfaccia utente a più riquadri.

  4. Un frammento può essere utilizzato in più attività.

  5. Il ciclo di vita del frammento è strettamente correlato al ciclo di vita della sua attività ospite.

  6. Quando l'attività viene messa in pausa, anche tutti i frammenti disponibili nell'account verranno fermati.

  7. Un frammento può implementare un comportamento senza componente dell'interfaccia utente.

  8. I frammenti sono stati aggiunti all'API Android in Android 3 (Honeycomb) con l'API versione 11.

Per maggiori dettagli, visita il sito ufficiale, Fragments .


Se stai solo passando oggetti, Parcelable stato progettato per questo. Richiede uno sforzo leggermente maggiore rispetto all'uso della serializzazione nativa di Java, ma è molto più veloce (e intendo molto, WAY più veloce).

Dai documenti, un semplice esempio su come implementare è:

// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
    private int mData;

    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    @Override
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

        public MyParcelable[] newArray(int size) {
            return new MyParcelable[size];
        }
    };

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private MyParcelable(Parcel in) {
        mData = in.readInt();
    }
}

Osservare che nel caso in cui si abbia più di un campo da recuperare da un determinato pacco, è necessario farlo nello stesso ordine in cui li si inserisce (vale a dire, in un approccio FIFO).

Una volta che i tuoi oggetti hanno implementato Parcelable , è solo questione di metterli nei tuoi Intents con putExtra() :

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);

Quindi puoi estrarli nuovamente con getParcelableExtra() :

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");

Se la classe dell'oggetto implementa Parcelable e Serializable, assicurati di eseguire il cast in uno dei seguenti modi:

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);






android android-layout android-fragments android-activity android-3.0-honeycomb