Upload
others
View
28
Download
0
Embed Size (px)
Citation preview
ANDROID- IUT GEII
1
Juan BRAVO
ANDROID
INTERFACES GRAPHIQUES COMPLEXES
ANDROID- IUT GEII 2ANDROID-IUT GEII
Liste d'éléments
La classe RecyclerView Remplace l'ancienne classe ListView
Affichage d'éléments visuels sous forme de liste
Possibilité de personnaliser chaque élément
Notion d'adaptateur
Les adaptateurs Lien entre la source de données et l'affichage à réaliser
Objectif
Découplage entre les données et la vue
Permet de changer la mise en forme sans toucher aux classes 'métiers'RecyclerView Adapter
OnBindViewHolder link information between data source and view holder fields
onBindViewHolder(ViewHolder,3)
ANDROID- IUT GEII 3ANDROID-IUT GEII
RecyclerView
RecyclerView.Adapter Classe abstraite
Corps de certaines méthodes laissés volontairement vide
Non instantiable donc
A charge de l'utilisateur d'hériter et d'écrire de contenu des méthodes
Principales méthodes héritées
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
– Objectif : création d'une vue (View) en fonction de vos besoins
public void onBindViewHolder(ViewHolder holder, int position)
– Objectif : fait le lien entre la vue précédemment crée et vos données (data binding)
ANDROID- IUT GEII 4ANDROID-IUT GEII
RecyclerView
Les étapes Création du type d'objet 'à afficher'
Type prédéfinis : String, Int , etc...
Type Utilisateur : création de classes
public class Student { private String nom; private String prenom; private Avatar avatar;
public String getNom() { return nom; }
public String getPrenom() { return prenom; }
public Avatar getAvatar() { return avatar; }
public Student(String nom, String prenom, Avatar avatar) { this.nom = nom; this.prenom = prenom; this.avatar = avatar; }}
public class Avatar { private Drawable avatarImage;
public Avatar(Drawable avatarImage) { this.avatarImage = avatarImage; }
public Drawable getAvatarImage() { return avatarImage; }}
ANDROID- IUT GEII 5ANDROID-IUT GEII
RecyclerView
Stockage des éléments en Java
Notion de conteneur et de collection
/////////////////////////////////////////ArrayList<int> al2 = new ArrayList<int>();al2.add(3);al2.add(2); al2.add(1);// exemple 1 de parcours de collectionIterator<int> iter2 = al2.iterator();while(iter2.hasNext()){ System.out.println(iter2.next());}al2.remove(2);// exemple 2 de parcours de collection for (int unEntier:al2){System.out.println(unEntier);}
Les collections sont génériques. Elles doivent pouvoir fonctionner pour différents typesSyntaxe côté utilisateur: ArrayList<MonTypeAMoi>
Exemple ArrayList
ANDROID- IUT GEII 6ANDROID-IUT GEII
RecyclerView
Exemple du dictionnaire
– Stockage sous forme clé+objet
HashMap<String, Color> dico = new HashMap<String, Color>();dico.put("rouge", new Color(200,0,0));dico.put("blanc", new Color(200,200,200));dico.put("marron", new Color(153,135,200));dico.put("violet", new Color(153,0,200));String colorKey = "marron";// recherche sur cléColor col= dico.get(colorKey);System.out.println("Clé: " + colorKey +" Moyenne: "+ col.ColorAverage());
dico.remove("marron");//itération avec modifIterator<Map.Entry<String, Color>> iterator = dico.entrySet().iterator();
while(iterator.hasNext()){ Map.Entry<String, Color> entry = iterator.next(); System.out.printf("clé : %s and Value: %s %n", entry.getKey(), entry.getValue().ColorAverage()); if (entry.getKey()=="blanc"){ iterator.remove(); } } //itération sans modif for(Map.Entry<String, Color> entry : dico.entrySet()){ System.out.printf("clé : %s and Value: %s %n", entry.getKey(), entry.getValue().ColorAverage()); }
Clé: marron Moyenne: 162clé : rouge and Value: 66 clé : violet and Value: 117 clé : blanc and Value: 200 clé : rouge and Value: 66 clé : violet and Value: 117
ANDROID- IUT GEII 7ANDROID-IUT GEII
RecyclerView
Adaptateur Création du layout
Repertoire ressouces>layout
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeightLarge" android:orientation="horizontal"
android:gravity="center">
<ImageViewandroid:id="@+id/img_avatar"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/designer_avatar" />
<TextView android:id="@+id/tv_fullName" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Oscar Amel"
android:textColor="@color/colorPrimary"/>
</LinearLayout>
ANDROID- IUT GEII 8ANDROID-IUT GEII
RecyclerView
Adaptateur « customisé »
Création d'une classe héritée de RecyclerView.Adapter
Un constructeur pour transmettre une référence vers les données
class StudentRecyclerViewAdapter extends RecyclerView.Adapter<StudentRecyclerViewAdapter.ViewHolder> { // private reference field pointing to our data private ArrayList<Student> refStudentList;
// ctor public StudentRecyclerViewAdapter(ArrayList<Student> studentList) { refStudentList=studentList; }
// model of the UI ViewHolder // this class is inner to our adapter public class ViewHolder extends RecyclerView.ViewHolder { public TextView fullName; public ImageView avatar;
public ViewHolder(View v) { super(v); fullName = (TextView) v.findViewById(R.id.tv_fullName) ; avatar = (ImageView) v.findViewById(R.id.img_avatar); } }
ANDROID- IUT GEII 9ANDROID-IUT GEII
Suite de la classe StudentRecyclerViewAdapter
// create ViewHolder // ViewHolder can be recycled for optimsition purpose @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.student_item, parent, false); ViewHolder vh = new ViewHolder(v); return vh; }
// link the UI ViewHolder model to our object model @Override public void onBindViewHolder(ViewHolder holder, int position) { Student currentItem = refStudentList.get(position); holder.fullName.setText(currentItem.getPrenom()+" "+currentItem.getNom()); Avatar itemcurrentAvatar=currentItem.getAvatar(); holder.avatar.setImageDrawable(itemcurrentAvatar.getAvatarImage()); }
// needed to explain when to rech the end @Override public int getItemCount() { return refStudentList.size(); }}// End of StudentRecyclerViewAdapter
ANDROID- IUT GEII 10ANDROID-IUT GEII
ListView
L'activité principale On place le RecyclerView
On lie le RecyclerView à l'adapteur
public class MainActivity extends AppCompatActivity { ArrayList<Student> studentList; private RecyclerView rvView;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // STEP1: setup data (fill studentList) initStudentDataSource(); rvView = (RecyclerView) findViewById(R.id.rv_main); rvView.setHasFixedSize(true); // STEP2: CHOOSE layout LinearLayoutManager layoutManager = new LinearLayoutManager(this); rvView.setLayoutManager(layoutManager); // STEP3: instantiate StudentRecyclerViewAdapter StudentRecyclerViewAdapter adapter = new StudentRecyclerViewAdapter(studentList); // STEP4: link RecyclerView coming from activity_main to our custom adapter rvView.setAdapter(adapter); }
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:orientation="vertical">
<android.support.v7.widget.RecyclerView android:id="@+id/rv_main" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical" />
</LinearLayout>
private void initStudentDataSource(){ studentList=new ArrayList(); Avatar refAvatar=new Avatar(ContextCompat.getDrawable(this, R.drawable.grimace)); Student refStudent= new Student("AMEL","Oscar",refAvatar); studentList.add(refStudent); refAvatar=new Avatar(ContextCompat.getDrawable(this, R.drawable.designer_avatar));Etc….
ANDROID- IUT GEII 11ANDROID-IUT GEII
ListView
Gestion du clic Plusieurs solutions possibles
Implémenter la setOnclickListener dans l'adapter (le +simple!! )
Implémenter recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { ….
Implémenter le design pattern oberver entre le ViewHolder et l'activité parente
Utiliser des librairies pour la mise en place du RecyclerView
public ViewHolder(View v) { super(v); fullName = (TextView) v.findViewById(R.id.tv_fullName); avatar = (ImageView) v.findViewById(R.id.img_avatar);
v.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position=getAdapterPosition(); if (position != RecyclerView.NO_POSITION){ Snackbar.make(v, "Position "+position +" Clicked element " +refStudentList.get(position). getNom(), Snackbar.LENGTH_LONG).show(); } } });}
// Check if an item was //deleted, but the user //clicked it before the UI//removed it
https://guides.codepath.com/android/using-the-recyclerview
ANDROID- IUT GEII 12ANDROID-IUT GEII
Pour plus de fonctionnalités Librairies de la communauté open source
https://github.com/mikepenz/FastAdapter
https://github.com/davideas/FlexibleAdapter/wiki
ANDROID- IUT GEII 13ANDROID-IUT GEII
Fragments
Les fragments Permet de fragmenter la vue ( portion d'interfaces visuelles)
Objectifs :
Modularité de l'application
– Évolution application, Hétérogénéité des matériels cibles Réutilisation de portions codes
Scénario 1 Scénario 2
ANDROID- IUT GEII 14ANDROID-IUT GEII
Fragments
Cycle de vie d'un fragment Lié au cycle de vie de l'activité parente
Méthodes de callbacks des fragments appelées par l'activité parente
Cycle de vie d'une activité
Cycle de vie d'un fragment
ANDROID- IUT GEII 15ANDROID-IUT GEII
Fragments
Callbacks d'un fragmentonAttach Called when the Fragment is attached to its
parent Activity.Get a reference to the parent Activity.
onCreate Called to do the initial creation of the Fragment.
Initialize the Fragment.
onCreateView // Called once the Fragment has been created in order for it to // create its user interface.
// Create, or inflate the Fragment's UI, and return it. // If this Fragment has no UI then return null.
onActivityCreated // Called once the parent Activity and the Fragment's UI have // been created.
// Complete the Fragment initialization Ð particularly anything // that requires the parent Activity to be initialized or the // Fragment's view to be fully inflated.
onStart // Called at the start of the visible lifetime // Apply any required UI change now that the Fragment is visible.
onResume // Called at the start of the active lifetime. // Resume any paused UI updates, threads, or processes required // by the Fragment but suspended when it became inactive.
onPause // Called at the end of the active lifetime. // Suspend UI updates, threads, or CPU intensive processes // that don't need to be updated when the Activity isn't // the active foreground activity. // Persist all edits or state changes // as after this call the process is likely to be killed.
onSaveInstanceState // Called to save UI state changes at the // end of the active lifecycle.
// Save UI state changes to the savedInstanceState. // This bundle will be passed to onCreate, onCreateView, and // onCreateView if the parent Activity is killed and restarted.
onDestroyView // Called when the Fragment's View has been detached.
// Clean up resources related to the View.
onDestroy // Called at the end of the full lifetime. // Clean up any resources including ending threads, // closing database connections etc.
ANDROID- IUT GEII 16ANDROID-IUT GEII
Fragments
Exemplepublic class Fragment1 extends Fragment {
// Called when the Fragment is attached to its parent Activity.@Override
public void onAttach(Activity activity) {super.onAttach(activity);
// TODO: Get a reference to the parent Activity.Log.d("Fragment 1", "onAttach");
}
// Called to do the initial creation of the Fragment.@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//// TODO: Initialize the Fragment.Log.d("Fragment 1", "onCreate");
}
// Called once the Fragment has been created in order for it to // create its user interface.
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO:Create, or inflate the Fragment's UI, and return it. // If this Fragment has no UI then return null. Log.d("Fragment 1", "onCreateView"); return inflater.inflate(R.layout.fragment1, container, false); }…........
Déclaration de 2 fragments mode paysage (balise fragment)
Définition aspect visuel d'un fragment
Code d'un fragment (intéraction etc..)
ANDROID- IUT GEII 17ANDROID-IUT GEII
Fragments
Fragments statiques Déclaration dans les ressources layout : balises fragment
<LinearLayout xmlns:....
<fragment android:name="com.example.staticfragment.Fragment1" android:id="@+id/list" android:layout_weight="0.25" android:layout_width="0dp" android:layout_height="match_parent" /></LinearLayout>
<LinearLayout xmlns:....... <fragment android:name="com.example.staticfragment.Fragment1" android:id="@+id/list" android:layout_weight="0.25" android:layout_width="0dp" android:layout_height="match_parent" /> <fragment android:name="com.example.staticfragment.Fragment2" android:id="@+id/viewer" android:layout_weight="0.75" android:layout_width="0dp" android:layout_height="match_parent" />
rotation
Afin d’éviter plusieurs main.xml et de gérer correctement les différentes configurations cet exemple peut-être refactoriser à l’aide d’aliasing (voir poly styles)
ANDROID- IUT GEII 18ANDROID-IUT GEII
Fragments
Définition de l'interface d'un fragment
Comme d'habitude par le biais d'une ressource de type layout
Code du fragment
Surcharge des méthodes de callback
Gestion des interaction de l'IHM
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00FF00" ><TextView android:id="@+id/txtFragment1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="This is fragment #1" /> </LinearLayout>
<fragment android:name="com.example.staticfragment.Fragment1" android:id="@+id/list" ….....</LinearLayout>
ANDROID- IUT GEII 19ANDROID-IUT GEII
Fragments
Exemple de code du fragment 1
public class MainActivity extends Activity {/** Called when the activity is first created. */
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Rappel : nous avons déclaré dans le layout de l'activité principale le (les) fragment(s)En fonction de l'orientation le bon layout est appelé (1 ou 2 fragments déclarés)
public class Fragment2 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View v=inflater.inflate(R.layout.fragment2, container, false); //---text view--- TextView txtFrg2 = (TextView) v.findViewById(R.id.txtFragment2); txtFrg2.setText("this is fragment 2"); txtFrg2.setTextColor(Color.BLUE); txtFrg2.setTypeface(Typeface.DEFAULT_BOLD); return (v); }
On récupère la vue désérialisée afin d'accéder au widget
TextView lbl = (TextView) getActivity().findViewById(R.id.lblFragment1);
Il est possible d'accéder à des widget d'autres fragments par le biais de getActivity()
ANDROID- IUT GEII 20ANDROID-IUT GEII
Fragments dynamiques Approche statique : les fragments sont figées à la compilation
Approche dynamique : possibilité de remplacer au run-time un fragment par un autre en fonction du contexte de l'application !
La structure des fichiers est la même mais la balise xml fragment n'est plus utilisée
ANDROID- IUT GEII 21ANDROID-IUT GEII
Etape 1 : les ressources Pas de balise Fragment
A la place : un conteneur de vue de type FrameLayout
Le fragment sera crée dynamiquement en Java puis placée à l'intérieur du Frame Layout
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=".........." android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <FrameLayout android:id="@+id/fragmentContainer1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" >
</FrameLayout>
<FrameLayout android:id="@+id/fragmentContainer2" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="2" android:visibility="gone"> </FrameLayout></LinearLayout>
Bonne pratique 2 FrameLayout en portrait ou landspace mais visibility gone en portrait
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android= ".........." android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00FF00" ><TextView android:id="@+id/lblFragment1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="This is fragment #1" /> </LinearLayout>
ANDROID- IUT GEII 22ANDROID-IUT GEII
Etape 2 : création dynamique des fragments
public class MainActivity extends Activity {
@Overrideprotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction(); Fragment fragment1= (Fragment)fragmentManager.findFragmentById(R.id.fragmentContainer1); if (fragment1==null){ fragmentTransaction.add(R.id.fragmentContainer1, new Fragment1()); } Fragment fragment2= (Fragment)fragmentManager.findFragmentById(R.id.fragmentContainer2); if (fragment2==null){ fragmentTransaction.add(R.id.fragmentContainer2, new Fragment2()); } fragmentTransaction.commit();
}
La manipulation des fragments par le code passe par la classe FragmentManager
Création fragment et ajout dans le framelayout
Pourquoi if (fragment2==null) ?????
Lors d'une rotation l'activité et les fragments donc sont détruits puis RECREE automatiquement !!! L'astuce consiste à regarder si un fragment existe déjà dans le container.
ANDROID- IUT GEII 23ANDROID-IUT GEII
Erreur de conception courante
Analyse d'une rotation
Nous sommes en mode LANDNous passons en mode PORBOOOM
Le fragment Command Panel est détruit
Le fragment Command Panel est récrée automatiquement (indépendant de votre code)
Oui..Mais ou est le xml ????
ANDROID- IUT GEII 24ANDROID-IUT GEII
Mauvaise solution (mais fonctionnelle!)
Placer les ressources comme suit
Nous sommes en mode LANDNous passons en mode POR
Au moment de la recréation automatique des fragments (panel et détail) les layouts sont recherchés :1- layout-port : KO2- layout-xxx : KO3- layout-yyy: KO4- layout : OK ( layout = par défaut)
Il est préférable de regrouper tout les « sous-layouts » au même endroits
ANDROID- IUT GEII 25ANDROID-IUT GEII
Déclarer en mode portrait les containers pour TOUS les fragments
– Les containers non utilisés seront positionnés NON VISIBLE
En portrait 1 seul container de conservé
ANDROID- IUT GEII 26ANDROID-IUT GEII
Etape 3 : manipulation dynamique des fragments
@Overridepublic boolean onOptionsItemSelected(MenuItem item) {switch (item.getItemId()) {case R.id.item1:FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); Fragment fragmentB= (Fragment)fragmentManager.findFragmentById(R.id.fragmentContainer2);
if (fragmentB instanceof Fragment2){ fragmentTransaction.replace(R.id.fragmentContainer2, new Fragment1() ); fragmentTransaction.replace(R.id.fragmentContainer1, new Fragment2()); } else{ fragmentTransaction.replace(R.id.fragmentContainer2, new Fragment2() ); fragmentTransaction.replace(R.id.fragmentContainer1, new Fragment1()); } fragmentTransaction.commit();Toast.makeText(this, "Fragment permut", Toast.LENGTH_SHORT).show(); return true;}return super.onOptionsItemSelected(item);}
Exploitation du polymorphismeUpcast
ANDROID- IUT GEII 27ANDROID-IUT GEII
Transmission de données Deux scénarios
FragmentA ->Activité Parente ou FragmentA->Activité Parente->FragmentB
Design pattern OBSERVATEUR
C'est le fragment qui émet un évenementPour ce faire, il maintient une liste d'abonnés à cet événement
C'est notre activité parent qui à l'écoute de l'événement (c'est l'abonnée)
ANDROID- IUT GEII 28ANDROID-IUT GEII
Pattern Observateur Application 1 : GPS
// Interface implémentée par tous les observateurs.public interface Observateur{ // Méthode appelée automatiquement lorsque l'état (position ou précision) du GPS change. public void actualiser(Observable o);}
// Affiche un résumé en console des informations (position) du GPS.public class AfficheResume implements Observateur{ public void actualiser(Observable o) { if(o instanceof Gps) { Gps g = (Gps) o; System.out.println("Position : "+g.getPosition()); }
http://design-patterns.fr/observateur-en-java
ANDROID- IUT GEII 29ANDROID-IUT GEII
// Classe représentant un GPS (appareil permettant de connaître sa position).public class Gps implements Observable{ private String position; private int precision; private ArrayList tabObservateur;// Tableau d'observateurs. // Constructeur. public Gps() { position="inconnue"; precision=0; tabObservateur=new ArrayList(); } // Permet d'ajouter (abonner) un observateur à l'écoute du GPS. public void ajouterObservateur(Observateur o) { tabObservateur.add(o); }
// Interface implémentée par toutes les classes souhaitant avoir des observateurs à leur écoute.public interface Observable{ // Méthode permettant d'ajouter (abonner) un observateur. public void ajouterObservateur(Observateur o); // Méthode permettant de supprimer (résilier) un observateur. public void supprimerObservateur(Observateur o); // Méthode qui permet d'avertir tous les observateurs lors d'un changement d'état. public void notifierObservateurs();}
ANDROID- IUT GEII 30ANDROID-IUT GEII
Pattern Observateur simplifiépublic class Fragment2 extends Fragment {private OnValidateEventListener eventValidateListener;
public interface OnValidateEventListener {public void onValidateEvent(EventRecord oneRecord);}@Override// Called when the Fragment is attached to its parent Activitypublic void onAttach(Activity activity) {super.onAttach(activity);// Get reference to parent Activity and check if parent implements listenertry {eventValidateListener = (OnValidateEventListener)activity;} catch (ClassCastException e) {throw new ClassCastException(activity.toString() +"must implement OnValidateEventListener");}}
@Overridepublic void onStart() {super.onStart();Button btn=(Button) getActivity().findViewById(R.id.btnFireEvent);btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {// Fire EventeventValidateListener.onValidateEvent(new EventRecord(SimpleEvent.ALERTE_TEMPERATURE));}});
Référence vers un abonné (ici l'activité parente ,qui devra donc implémenter
OnValidateEventListener)
Définition du contrat d'appel pour les observateurs
L'enregistrement se fait lorsque le fragment est attaché à son activité parente
( opération de UPCAST)
Le fragment signale l'événementAppel de la méthode onValidateEvent implanté par
l'observateur (Activité parente)
Je suis l'Observable (celui qui est observé)
ANDROID- IUT GEII 31ANDROID-IUT GEII
port com.example.listenerfragment.Fragment2.OnValidateEventListener;public class MainActivity extends Activityimplements OnValidateEventListener{
/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); }
// since MainActivity implements OnValidateEventListener // we need to implement onValidateEventpublic void onValidateEvent(EventRecord oneRecord) {// ACTION when event is firedTextView txt=(TextView)findViewById(R.id.txtMain);txt.setText(oneRecord.getEvent().name());
} }
Je dois respecter le contrat
J'implémente la méthode onValidateEventJ'exploite la donnée transmis par le Sujet
(observable)
Je suis l'Observateur (celui qui observe)
La communication d'un Fragment vers un autre doit passer par l'activité parente qui a pour charge d'appeler la méthode souhaitée
http://developer.android.com/training/basics/fragments/communicating.html
ANDROID- IUT GEII 32ANDROID-IUT GEII
Applications typiques des fragments Les menus tabulés
Google Map API v2
Fragment List et Fragment Détails
Mode portrait Mode paysage
<fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.google.android.gms.maps.MapFragment"/>
ANDROID- IUT GEII 33ANDROID-IUT GEII
ListFragment version express Les ressources
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:........ android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" >
<fragment android:id="@+id/listFragment" android:layout_width="match_parent" android:layout_height="match_parent" class="com.example.listfragmentsimple.ListFragment" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:........ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >
<fragment android:id="@+id/detailFragment" android:layout_width="match_parent" android:layout_height="match_parent" class="com.example.listfragmentsimple.DetailFragment" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:...... android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" >
<fragment android:id="@+id/listFragment" android:layout_width="150dip" android:layout_height="match_parent" class="com.example.listfragmentsimple.ListFragment" ></fragment>
<fragment android:id="@+id/detailFragment" android:layout_width="match_parent" android:layout_height="match_parent" class="com.example.listfragmentsimple.DetailFragment" > </fragment>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="......... android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >
<TextView android:id="@+id/detailsText" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="....... android:layout_marginTop="20dip" android:textSize="30dip" />
</LinearLayout>
LANDPORT
On remarquera l'absence de xml pour la mise en forme de la liste. Version express= layout fourni par défaut
ANDROID- IUT GEII 34ANDROID-IUT GEII
Le code
Activité principale
Activité détails (mode PORT)
public class ListFragment extends android.app.ListFragment {private static final String VALUE = "value";private String[] values = {"Cupcake", "Donut", "Eclair", "Froyo", "Gingerbread", "Honeycomb", "Ice Cream Sandwich" };
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);}
@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);
ArrayAdapter<String> adapter = new ArrayAdapter<String> (getActivity(),android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);}
@Overridepublic void onListItemClick(ListView l, View v, int position, long id) {String item = (String) getListAdapter().getItem(position);
DetailFragment fragment = (DetailFragment) getFragmentManager().findFragmentById(R.id.detailFragment);
if (fragment != null && fragment.isInLayout()) {fragment.setText(item);}
Else {Intent intent = new Intent(getActivity().getApplicationContext(),DetailActivity.class);intent.putExtra(VALUE, item);startActivity(intent);}
Si fragment détail est présent et compris dans layout alors on est en mode LAND
Sinon on lance activité détails en passant par intent la donnée à afficher