Programmation Mobile Android Master CCI Bertrand Estellon Aix-Marseille Université March 23, 2015 Bertrand Estellon (AMU) Android Master CCI March 23, 2015 1 / 266 Les fragments Un fragment : représente une portion d interface utilisateur ; peut être inséré dans une activité ; peut être utilisé dans plusieurs activités ; possède son propre cycle de vie, layout, etc ; Une activité : peut afficher plusieurs fragments ; peut utiliser une pile pour gérer la navigation entre fragments ; Bertrand Estellon (AMU) Android Master CCI March 23, 2015 80 / 266 Une application avec deux fragments Bertrand Estellon (AMU) Android Master CCI March 23, 2015 81 / 266 Premier layout : le formulaire Le layout correspondant au formulaire du premier écran : <LinearLayout xmlns:android=""> <EditText android:id="@+id/edittext1" android:inputtype="number" /> <TextView android:text="@string/plus" /> <EditText android:id="@+id/edittext2" android:inputtype="number" /> <Button android:id="@+id/button" android:text="@string/equals" /> </LinearLayout> Bertrand Estellon (AMU) Android Master CCI March 23, 2015 82 / 266
Deuxième layout : le resultat Le layout de l activité principale <TextView xmlns:android="" xmlns:tools="" android:id="@+id/textview" android:layout_height="match_parent" android:gravity="center" android:textsize="100dp" android:text="+" /> Le layout de l activité principale : <FrameLayout xmlns:android="" xmlns:tools="" android:id="@+id/container" android:layout_height="match_parent" /> Bertrand Estellon (AMU) Android Master CCI March 23, 2015 83 / 266 L activité principale Le code de l activité principale : { superoncreate(savedinstancestate); setcontentview(rlayoutactivity_main); if (savedinstancestate == null) { getfragmentmanager()begintransaction() add(ridcontainer, new FormFragment()) commit(); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 84 / 266 La création de la vue dans le premier fragment Le code du premier fragment : public View oncreateview(layoutinflater inflater, ViewGroup container, Bundle savedinstancestate) { View view = inflaterinflate(rlayoutfragment_form, container, false); return view; Bertrand Estellon (AMU) Android Master CCI March 23, 2015 85 / 266 Bertrand Estellon (AMU) Android Master CCI March 23, 2015 86 / 266
Cycle de vie d un fragment Le fragment FormFragment doit notifier l activité de la validation du formulaire lorsque l utilisateur clique sur le bouton ; Nous allons définir une interface pour rendre le fragment réutilisable : public interface FormFragmentListener { void onequals(double value1, double value2); L activité va implémenter cette interface ; Lors de l exécution de la méthode onattach du fragment, nous allons conserver une référence afin d être capable de notifier l activité (Work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 25 Attribution License) Bertrand Estellon (AMU) Android Master CCI March 23, 2015 87 / 266 Nous conservons la référence de l activité : private FormFragmentListener listener; public void onattach(activity activity) { superonattach(activity); try { listener = (FormFragmentListener)activity; catch (ClassCastException e) { throw new ClassCastException(activitytoString() + " must implement OnClickListener"); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 89 / 266 Bertrand Estellon (AMU) Android Master CCI March 23, 2015 88 / 266 Nous faisons en sorte d écouter les clics sur le bouton : private EditText edittext1, edittext2; private FormFragmentListener listener; public View oncreateview(layoutinflater inflater, ViewGroup container, Bundle savedinstancestate) { View view = inflaterinflate(rlayoutfragment_form, container, false); edittext1 = (EditText)viewfindViewById(RideditText1); edittext2 = (EditText)viewfindViewById(RideditText2); Button button = (Button)viewfindViewById(Ridbutton); buttonsetonclicklistener(new OnClickListener()); return view; Bertrand Estellon (AMU) Android Master CCI March 23, 2015 90 / 266
Réception de la notification par l activité : Nous notifions l activité si un clic se produit : private EditText edittext1, edittext2; private FormFragmentListener listener; private class OnClickListener implements ViewOnClickListener { public void onclick(view v) { double value1 = DoubleparseDouble(editText1getText()toString()); double value2 = DoubleparseDouble(editText2getText()toString()); listeneronequals(value1, value2); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 91 / 266 Le deuxième fragment implements FormFragmentListener { superoncreate(savedinstancestate); setcontentview(rlayoutactivity_main); if (savedinstancestate == null) { getfragmentmanager()begintransaction() add(ridcontainer, new FormFragment()) commit(); public void onequals(double value1, double value2) { /* TODO : afficher le résultat */ Bertrand Estellon (AMU) Android Master CCI March 23, 2015 92 / 266 Les paramètres d un fragment Mise en place du layout du deuxième fragment : public class ResultFragment extends Fragment { public View oncreateview(layoutinflater inflater, ViewGroup container, Bundle savedinstancestate) { View view = inflaterinflate(rlayoutfragment_result, container, false); TextView textview = (TextView)viewfindViewById(RidtextView); textviewsettext(""+value()); return view; public double value() { /* TODO */ Les paramètres sont conservés même si le fragment est détruit : public class ResultFragment extends Fragment { public static ResultFragment getinstance(double value) { ResultFragment fragment = new ResultFragment(); Bundle bundle = new Bundle(); bundleputdouble("value", value); fragmentsetarguments(bundle); return fragment; public double value() { return getarguments()getdouble("value"); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 93 / 266 Bertrand Estellon (AMU) Android Master CCI March 23, 2015 94 / 266
Affichage du deuxième fragment par l activité : public class ResultFragment extends Fragment implements FormFragmentListener { public void onequals(double value1, double value2) { double value = value1+value2; getfragmentmanager()begintransaction() replace(ridcontainer, ResultFragmentgetInstance(value)) addtobackstack("result") commit(); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 95 / 266 Bertrand Estellon (AMU) Android Master CCI March 23, 2015 96 / 266 Le layout de l activité par défaut : <?xml version="10" encoding="utf-8"?> <LinearLayout xmlns:android="" android:orientation="vertical" android:layout_height="match_parent"> <fragment class="comuniv_amuccimyapplicationformfragment" android:id="@+id/form" android:layout_height="wrap_content"/> <FrameLayout android:id="@+id/container" android:layout_height="wrap_content" android:background="?android:attr/detailselementbackground" /> </LinearLayout> Le layout de l activité en mode paysage (dans le répertoire layout-land) : <?xml version="10" encoding="utf-8"?> <LinearLayout xmlns:android="" android:orientation="horizontal" android:layout_height="match_parent"> <fragment class="comuniv_amuccimyapplicationformfragment" android:id="@+id/form" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent" /> <FrameLayout android:id="@+id/container" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent" android:background="?android:attr/detailselementbackground" /> </LinearLayout> Bertrand Estellon (AMU) Android Master CCI March 23, 2015 97 / 266 Bertrand Estellon (AMU) Android Master CCI March 23, 2015 98 / 266
Le code de l activité : implements FormFragmentListener { superoncreate(savedinstancestate); setcontentview(rlayoutactivity_main); public void onequals(double value1, double value2) { double value = value1+value2; getfragmentmanager()begintransaction() replace(ridcontainer, ResultFragmentgetInstance(value)) addtobackstack("result") commit(); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 99 / 266 sont des fragments particuliers : public class DialogFragment extends androidappdialogfragment { private EditText edittext; public Dialog oncreatedialog(bundle savedinstancestate) { AlertDialogBuilder builder = new AlertDialogBuilder(getActivity()); LayoutInflater inflater = getactivity()getlayoutinflater(); View view = inflaterinflate(rlayoutdialog, null); edittext = (EditText)viewfindViewById(RideditText); buildersetview(view) setpositivebutton(androidrstringok, new OnPositiveButtonClickListener()) setnegativebutton(androidrstringcancel, new MyOnNegativeButtonClickListener()); return buildercreate(); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 101 / 266 Bertrand Estellon (AMU) Android Master CCI March 23, 2015 100 / 266 Nous allons faire communiquer le fragment et l activité via l interface : public interface DialogFragmentListener { void onchangetext(string text); On redéfinit ensuite la méthode onattach : public class DialogFragment extends androidappdialogfragment { private DialogFragmentListener listener; public void onattach(activity activity) { superonattach(activity); try { listener = (DialogFragmentListener)activity; catch (ClassCastException e) { throw new ClassCastException(activitytoString() + " must implement OnClickListener"); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 102 / 266
On implémente ensuite les deux classes internes de façon à traiter correctement la validation et l annulation du formulaire : public class DialogFragment extends androidappdialogfragment { private class OnPositiveButtonClickListener implements DialogInterfaceOnClickListener { public void onclick(dialoginterface dialog, int id) { listeneronchangetext(edittextgettext()tostring()); DialogFragmentthisgetDialog()dismiss(); private class MyOnNegativeButtonClickListener implements DialogInterfaceOnClickListener { public void onclick(dialoginterface dialog, int id) { DialogFragmentthisgetDialog()cancel(); Code de l activité principale : implements DialogFragmentListener { private TextView textview; superoncreate(savedinstancestate); setcontentview(rlayoutactivity_main); textview = (TextView)findViewById(RidtextView); textviewsetonclicklistener(new MyOnClickListener()); /* */ Bertrand Estellon (AMU) Android Master CCI March 23, 2015 103 / 266 Bertrand Estellon (AMU) Android Master CCI March 23, 2015 104 / 266 Code de l activité principale : implements DialogFragmentListener { private TextView textview; /* */ public void onchangetext(string text) { textviewsettext(text); private class MyOnClickListener implements ViewOnClickListener { public void onclick(view v) { DialogFragment newfragment = new DialogFragment(); newhow(getfragmentmanager(), "dialog"); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 105 / 266