Introduction de la section

Bien, dans le chapitre précédent, nous avons passé en revue les quatre composants majeurs d'Android : Activity, Service, BroadCastReceiver, ContentProvider, et le lien entre eux : Intent. Et dans ce chapitre, nous apportons quelque chose appelé Fragment (fragment). Dans cette section, nous présenterons quelques concepts de base et utilisations de ce Fragment ! Documentation officielle :Fragment


1. Concepts de base

1) Qu'est-ce que c'est que ce truc ? À quoi cela sert-il ?

Réponse : Fragment est une nouvelle API introduite après Android 3.0. Son intention initiale était de s'adapter aux tablettes à grand écran. Bien sûr, il reste le chouchou de la conception d'interface utilisateur des applis pour tablettes, et notre développement pour téléphones ordinaires ajoute également ce Fragment. Nous pouvons le considérer comme une petite Activity, aussi appelée fragment d'Activity ! Réfléchissez : si une très grande interface n'a qu'une seule mise en page, quelle galère ce serait d'écrire l'interface, et s'il y a beaucoup de composants, c'est aussi très pénible à gérer ! Avec Fragment, nous pouvons diviser l'écran en plusieurs blocs, puis les regrouper et effectuer une gestion modulaire ! Cela permet de mettre à jour plus facilement l'interface utilisateur de l'Activity de manière dynamique pendant l'exécution ! De plus, Fragment ne peut pas être utilisé seul ; il doit être imbriqué dans une Activity. Bien qu'il ait son propre cycle de vie, il est toujours affecté par le cycle de vie de l'Activity hôte. Par exemple, si l'Activity est détruite, il sera également détruit !

La figure ci-dessous est un diagramme de la documentation montrant comment un Fragment correspond à différentes situations entre un téléphone et une tablette :

PS : une simple page de consultation d'actualités utilise deux Fragments pour afficher respectivement la liste des actualités et le contenu des actualités ;


2) Schéma du cycle de vie d'un Fragment


3) Points clés :

Voici quelques points clés pour l'utilisation de Fragment :

  • Introduit après la version 3.0, c'est-à-dire que minSdk doit être supérieur à 11
  • Fragment doit être imbriqué dans une Activity pour être utilisé. Bien sûr, il peut aussi être imbriqué dans un autre Fragment, mais ce Fragment imbriqué doit également être imbriqué dans une Activity. Indirectement, Fragment doit toujours être imbriqué dans une Activity !! Il est affecté par le cycle de vie de l'Activity hôte, mais bien sûr il a aussi son propre cycle de vie ! De plus, il n'est pas recommandé d'imbriquer un Fragment dans un Fragment, car le cycle de vie du Fragment imbriqué est incontrôlable !!!
  • Selon la documentation officielle, lors de la création d'un Fragment, vous devez implémenter au moins trois méthodes : onCreate(), onCreateView() et OnPause() ; cependant, il semble que n'écrire que onCreateView() soit également acceptable...
  • Le cycle de vie d'un Fragment est assez similaire à celui d'une Activity : trois états :
    Reprise : Le Fragment en cours d'exécution est visible
    En pause : L'Activity dans laquelle il réside est visible, mais il ne peut pas obtenir le focus
    Arrêté : 1) En appelant addToBackStack(), le Fragment est ajouté à la pile de retour 2) L'Activity passe en arrière-plan, ou le Fragment est remplacé/supprimé
    PS : Un fragment à l'état arrêté est toujours vivant (tous les états et toutes les données membres sont conservés par le système), cependant, il n'est plus visible pour l'utilisateur, et si l'Activity est tuée, il sera également tué.

4) Plusieurs sous-classes de Fragment :

PS : La plupart du temps, nous redéfinissons directement Fragment et gonflons les layouts pour implémenter la logique métier correspondante. Les sous-classes ne sont pas beaucoup utilisées. En cas de besoin, nous pouvons les étudier en profondeur !

  • Dialogue :DialogFragment
  • Liste :ListFragment
  • Paramètres de préférence :PreferenceFragment
  • Interface WebView :WebViewFragment

5) Faut-il utiliser le Fragment du package App ou celui du package v4 :

Présentation du problème :

Je pense que beaucoup de personnes rencontreront la situation suivante lors de l'utilisation de Fragment :

Alors, devons-nous utiliser le Fragment sous android.app ou le Fragment sous le package android.support.v4.app ?

Réponse : En fait, les deux conviennent. Comme mentionné précédemment, Fragment a été introduit après Android 3.0 (API 11). Que se passe-t-il si l'application développée doit fonctionner sur des versions inférieures à 3.0 ? Par exemple, 2.3 a encore une petite part de marché ! Le package v4 a donc vu le jour, et il peut être compatible jusqu'à la version 1.6 ! Quant au package à utiliser, cela dépend de vos besoins. Aujourd'hui, la part de marché des téléphones inférieurs à 3.0 n'est en fait pas très élevée ; partout où vous allez, il y a des téléphones supérieurs à 4.0, et 6.0 est sorti en octobre. Alors, qu'en pensez-vous ? À ce stade, vous pouvez directement utiliser le Fragment du package app, puis appeler les méthodes associées. Généralement, il n'y aura pas de problème ; si vous utilisez le Fragment du package app, alors FragmentManager et FragmentTransaction doivent aussi provenir du package app ! Soit tout utiliser depuis app, soit tout depuis v4, sinon vous obtiendrez des erreurs ! Bien sûr, si vous voulez que votre application soit compatible avec les téléphones de version inférieure, vous pouvez choisir le package v4 !

Points à noter lors de l'utilisation de Fragment du package v4 :

  • 1) Si vous utilisez Fragment du package v4, alors l'Activity dans laquelle il réside doit hériter de FragmentActivity ! Cas : Aujourd'hui, j'ai chargé statiquement un fragment dans un fichier XML, puis j'ai redéfini Fragment, mais une erreur a été signalée lors du chargement de l'Activity. L'erreur disait probablement quelque chose comme erreur Fragment ou introuvable. J'ai changé plusieurs fois l'attribut name, mais c'était toujours incorrect ! Finalement, j'ai découvert que c'était à cause du package v4. Il suffit de changer votre Activity en FragmentActivity !
  • 2) J'ai écrit précédemment le code suivant, puis cela a signalé une erreur :C'est un peu déroutant. Fragment, FragmentManager et FragmentTransaction utilisent tous le package v4, et Activity hérite aussi de FragmentActivity, n'est-ce pas ? Tout changer pour le package app fonctionnerait, mais cela n'entre-t-il pas en conflit avec notre prémisse d'utiliser le package v4 ? En fait, il existe une solution, n'est-ce pas ?
    Réponse : Il vous suffit de remplacergetFragmentManager( ) pargetSupportFragmentManager( ) et c'est tout.

2. Création d'un Fragment

1) Chargement statique d'un Fragment

Processus d'implémentation :

Exemple de code :

Étape 1 :Définir le layout du Fragment, qui est le contenu affiché par le fragment.
Étape 2 :Définir une classe Fragment personnalisée qui doit hériter de Fragment ou de ses sous-classes, redéfinir la méthode onCreateView(), et dans cette méthode appeler : la méthode inflater.inflate() pour charger le fichier de layout du Fragment, puis retourner l'objet view chargé.

public class Fragmentone extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment1, container,false);
        return view;
    }   
}

Étape 3 :Dans le fichier de layout correspondant à l'Activity qui doit charger le Fragment, ajouter la balise fragment. N'oubliez pas, l'attribut name est le nom de classe pleinement qualifié, c'est-à-dire qu'il doit inclure le nom du package du Fragment, par exemple :

<fragment
    android:id="@+id/fragment1"
    android:name="com.jay.example.fragmentdemo.Fragmentone"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />

Étape 4 :L'Activity peut simplement appeler setContentView() dans la méthode onCreate() pour charger le fichier de layout !


2) Chargement dynamique d'un Fragment

Processus d'implémentation :

Exemple de code :Ceci montre le passage d'un Fragment à un autre lorsque l'orientation de l'écran change entre portrait et paysage :

Je ne vais pas coller le code du Fragment et du layout ici ; je vais directement coller le code clé de MainActivity :

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Display dis = getWindowManager().getDefaultDisplay();
        if(dis.getWidth() > dis.getHeight())
        {
            Fragment1 f1 = new Fragment1();
            getFragmentManager().beginTransaction().replace(R.id.LinearLayout1, f1).commit();
        }
        
        else
        {
            Fragment2 f2 = new Fragment2();
            getFragmentManager().beginTransaction().replace(R.id.LinearLayout1, f2).commit();
        }
    }   
}

3. Gestion des fragments et transactions de fragments


4. Interaction entre Fragment et Activity

Certains amis n'aiment peut-être pas regarder des figures, alors laissez-moi vous le présenter en texte ci-dessous :

1) Obtention des composants

Le Fragment obtient les composants dans l'Activity :getActivity().findViewById(R.id.list);
L'Activity obtient les composants dans le Fragment (par id ou par tag, les deux fonctionnent) :getFragmentManager.findFragmentByid(R.id.fragment1);


2) Transmission de données

1) L'Activity transmet des données au Fragment :

Dans l'Activity, créez un paquet de données Bundle, appelez setArguments(bundle) sur l'instance de Fragment pour transmettre le paquet de données Bundle au Fragment, puis dans le Fragment appelez getArguments pour obtenir l'objet Bundle, puis analysez-le.

② Le Fragment transmet des données à l'Activity

Dans le Fragment, définissez une interface de rappel interne, et faites en sorte que l'Activity qui contient le Fragment implémente l'interface de rappel. Le Fragment peut alors transmettre des données via l'interface de rappel. Les callbacks — je pense que beaucoup de personnes savent ce que c'est, mais n'arrivent pas à écrire le code. Quand vous recherchez « fragment passes data to Activity » en ligne, tout ce que vous obtenez est le code de Li Gang, ce qui est vraiment frustrant. Tant pis, laissez-moi écrire un peu de code partiel ici. Je pense que les lecteurs comprendront au premier coup d'œil :

Étape 1 : Définir une interface de rappel (dans le Fragment)

/*接口*/  
public interface CallBack{  
    /*定义一个获取信息的方法*/  
    public void getResult(String result);  
}  

Étape 2 : Callback d'interface (dans le Fragment)

/*接口回调*/  
public void getData(CallBack callBack){  
    /*获取文本框的信息,当然你也可以传其他类型的参数,看需求咯*/  
    String msg = editText.getText().toString();  
    callBack.getResult(msg);  
}  

Étape 3 : Utiliser la méthode de callback d'interface pour lire les données (dans l'Activity)

/* 使用接口回调的方法获取数据 */  
leftFragment.getData(new CallBack() {  
 @Override  
       public void getResult(String result) {              /*打印信息*/  
            Toast.makeText(MainActivity.this, "-->>" + result, 1).show();  
            }
        }); 

Résumé de la méthode: ->Dans le Fragment, définissez une interface, et définissez des méthodes abstraites dans l'interface. Définissez le type du paramètre de données sur le type de données que vous souhaitez transmettre;
->Ensuite, vous devez également écrire une méthode qui appelle la méthode abstraite dans l'interface, en transmettant les données à transmettre.
->Ensuite vient l'Activity. Appelez la méthode fournie par le Fragment, et lisez les données lors de la redéfinition de la méthode abstraite, c'est tout !!!

③ Transfert de données entre Fragments

En fait, c'est très simple. Trouvez l'objet Fragment qui doit recevoir les données, et appelez directement setArguments pour transmettre les données. Habituellement, les données sont transmises lors du replace, c'est-à-dire lors de la navigation entre Fragments. Il vous suffit d'initialiser le Fragment cible et d'appeler sa méthode setArguments pour transmettre les données !
Si deux Fragments doivent transmettre des données en temps réel, plutôt que lors de la navigation, vous devez d'abord récupérer les données transmises depuis f1 dans l'Activity, puis les transmettre à f2. C'est-à-dire, utiliser l'Activity comme intermédiaire~

L'exemple de code est le suivant :

FragmentManager fManager = getSupportFragmentManager( );
FragmentTransaction fTransaction = fManager.beginTransaction();
Fragmentthree t1 = new Fragmentthree();
Fragmenttwo t2 = new Fragmenttwo();
Bundle bundle = new Bundle();
bundle.putString("key",id);
t2.setArguments(bundle); 
fTransaction.add(R.id.fragmentRoot, t2, "~~~");  
fTransaction.addToBackStack(t1);  
fTransaction.commit(); 

5. Parcourir le diagramme du cycle de vie:

Après mûre réflexion, j'ai décidé de vous faire parcourir simplement le diagramme du cycle de vie, pour approfondir votre compréhension du cycle de vie des Fragments:

① Lorsque l'Activity charge un Fragment, les méthodes suivantes sont appelées dans l'ordre:onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume

② Lorsque nous créons une Activity de style boîte de dialogue flottante, ou autre chose, rendant l'Activity contenant le Fragment visible mais sans prendre le focus :onPause

③ Lorsque la boîte de dialogue se ferme et que l'Activity reprend le focus :onResume

④ Lorsque nous remplaçons le Fragment et appelons addToBackStack() pour l'ajouter à la pile de retouronPause -> onStop -> onDestoryView !!Remarque, le Fragment n'a pas encore été détruit à ce stade !!!

⑤ Lorsque nous appuyons sur la touche retour du clavier, le Fragment sera à nouveau affiché :onCreateView -> onActivityCreated -> onStart -> onResume

⑥ Si, après avoir remplacé, avant que la transaction ne soit validéenous n'appelons pas addToBackStack()pour ajouter le Fragment à la pile de retour ; ou si l'Activity est quittée, alors le Fragment sera complètement terminé, et le Fragment entrera dans l'état détruit.onPause -> onStop -> onDestoryView -> onDestory -> onDetach


Résumé de la section :

Dans cette section, nous avons expliqué quelques concepts de base et une utilisation simple de Fragment. Je crois que vous tomberez progressivement amoureux de Fragment. En raison de limitations d'espace, cette section se limite à cela. Dans la section suivante, nous écrirons quelques exemples courants concernant Fragment. Restez à l'écoute, merci~