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
Interfaces 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 <TextView xmlns:android="" xmlns:tools="" android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textsize="100dp" android:text="+" /> Bertrand Estellon (AMU) Android Master CCI March 23, 2015 83 / 266
Interfaces Le layout de l activité principale Le layout de l activité principale : <FrameLayout xmlns:android="" xmlns:tools="" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" /> Bertrand Estellon (AMU) Android Master CCI March 23, 2015 84 / 266
L activité principale Le code de l activité principale : public class MainActivity extends Activity { protected void oncreate(bundle savedinstancestate) { superoncreate(savedinstancestate); setcontentview(rlayoutactivity_main); if (savedinstancestate == null) { getfragmentmanager()begintransaction() add(ridcontainer, new FormFragment()) commit(); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 85 / 266
La création de la vue dans le premier fragment Le code du premier fragment : public class FormFragment extends 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 86 / 266
Interfaces Cycle de vie d un fragment (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
Système de notification entre le fragment et l activité 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é Bertrand Estellon (AMU) Android Master CCI March 23, 2015 88 / 266
Système de notification entre le fragment et l activité Nous conservons la référence de l activité : public class FormFragment extends Fragment { 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
Système de notification entre le fragment et l activité Nous faisons en sorte d écouter les clics sur le bouton : public class FormFragment extends Fragment { 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
Système de notification entre le fragment et l activité Nous notifions l activité si un clic se produit : public class FormFragment extends Fragment { 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
Système de notification entre le fragment et l activité Réception de la notification par l activité : public class MainActivity extends Activity implements FormFragmentListener { protected void oncreate(bundle savedinstancestate) { 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
Le deuxième 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 */ Bertrand Estellon (AMU) Android Master CCI March 23, 2015 93 / 266
Les paramètres d un fragment 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 94 / 266
Affichage de deux fragments par l activité 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
Interfaces Affichage de deux fragments par l activité Bertrand Estellon (AMU) Android Master CCI March 23, 2015 96 / 266
Affichage de deux fragments par l activité Le layout de l activité par défaut : <?xml version="10" encoding="utf-8"?> <LinearLayout xmlns:android="" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment class="comuniv_amuccimyapplicationformfragment" android:id="@+id/form" android:layout_width="match_parent" android:layout_height="wrap_content"/> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/detailselementbackground" /> </LinearLayout> Bertrand Estellon (AMU) Android Master CCI March 23, 2015 97 / 266
Affichage de deux fragments par l activité 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_width="match_parent" 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 98 / 266
Affichage de deux fragments par l activité Le code de l activité : public class MainActivity extends Activity implements FormFragmentListener { protected void oncreate(bundle savedinstancestate) { 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
Interfaces Les boites de dialogue Bertrand Estellon (AMU) Android Master CCI March 23, 2015 100 / 266
Les boites de dialogue Les boites de dialogue 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
Les boites de dialogue 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
Les boites de dialogue 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(); Bertrand Estellon (AMU) Android Master CCI March 23, 2015 103 / 266
Les boites de dialogue Code de l activité principale : public class MainActivity extends Activity implements DialogFragmentListener { private TextView textview; protected void oncreate(bundle savedinstancestate) { superoncreate(savedinstancestate); setcontentview(rlayoutactivity_main); textview = (TextView)findViewById(RidtextView); textviewsetonclicklistener(new MyOnClickListener()); /* */ Bertrand Estellon (AMU) Android Master CCI March 23, 2015 104 / 266
Les boites de dialogue Code de l activité principale : public class MainActivity extends Activity 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