thefranchise Posté(e) 3 février 2011 Share Posté(e) 3 février 2011 Bonjour tout le monde. Je suis débutant en dév' Android, donc si jamais vous voyez des ignominies sans nom dans mon code, ne me jetez pas de pierres ^^' Voilà, je développe pour les cours une appli de gestion de bibliothèque. Ce que je veux faire : une page de consultation, qui afficherait dans une listview, les titres des livres enregistrés dans la BD. Puis lors du clic sur un élément, une autre page s'afficherait avec les infos générales du livre (ou un Toast je ne sais pas encore). J'ai essayé maintes fois de le faire depuis 2 semaines, mais je n'arrive à rien (j'avais toujours des bugs avant). Aujourd'hui j'ai réussi à faire un truc sans bug, android ne plante pas, MAIS ça ne m'affiche rien -_- Voici ma fonction qui sélectionne les livres (et qui marche puisque quand j'y fais appel, et que je fais un toast, elle m'affiche bien le premier livre qui est dans ma table) public Cursor getAllLivre2(){ return bdd.rawQuery("select _id,titre from table_livres", null); } Voici mon appel dans ce qui me sert de test Cursor c = livreBdd.getAllLivre2(); startManagingCursor(c); SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.liste, c, new String[]{"titre"},new int[]{R.id.titreLivre}); Voici mon fichier liste.xml <?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" > <TextView android:id="@+id/titreLivre" android:layout_width="fill_parent" android:layout_height="fill_parent" android:textSize="16px" android:textStyle="bold" /> </LinearLayout> et enfin voici mon fichier main.xml <?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" > <ListView android:id="@+id/listelivre" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> Merci d'avance pour votre aide. Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 3 février 2011 Share Posté(e) 3 février 2011 Il faudrait un extrait de code plus complet que ce que tu donnes, pour qu'on puisse comprendre (par exemple, le code de ton Activity) Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 3 février 2011 Auteur Share Posté(e) 3 février 2011 (modifié) Voici mon fichier de test package projet.bibliotheque; import android.app.Activity; import android.database.Cursor; import android.os.Bundle; import android.widget.SimpleCursorAdapter; import android.widget.Toast; public class test extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Création d'une instance de ma classe LivresBDD LivresBDD livreBdd = new LivresBDD(this); //Création d'un livre Livre livre1 = new Livre("123456789", "Programmez pour Android", "XX XX", "Atlas"); Livre livre2 = new Livre("111111111", "Android pour les nuls", "XX XX", "Hachette"); //On ouvre la base de données pour écrire dedans livreBdd.open(); //On insère le livre que l'on vient de créer livreBdd.insertLivre(livre1); livreBdd.insertLivre(livre2); //Pour vérifier que l'on a bien créé notre livre dans la BDD //on extrait le livre de la BDD grâce au titre du livre que l'on a créé précédemment //Livre livreFromBdd = livreBdd.getLivreWithTitre(livre.getTitre()); //Livre livreFromBdd = livreBdd.getAllLivre(); Cursor c = livreBdd.getAllLivre2(); startManagingCursor(c); SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.liste, c, new String[]{"titre"},new int[]{R.id.titreLivre}); //Si un livre est retourné (donc si le livre à bien été ajouté à la BDD) /*if(livreFromBdd != null){ //On affiche les infos du livre dans un Toast Toast.makeText(this, livreFromBdd.toString(), Toast.LENGTH_LONG).show(); //On modifie le titre du livre /*livreFromBdd.setTitre("J'ai modifié le titre du livre"); //Puis on met à jour la BDD livreBdd.updateLivre(livreFromBdd.getId(), livreFromBdd); } //On extrait le livre de la BDD grâce au nouveau titre livreFromBdd = livreBdd.getLivreWithTitre("J'ai modifié le titre du livre"); //S'il existe un livre possédant ce titre dans la BDD if(livreFromBdd != null){ //On affiche les nouvelle info du livre pour vérifié que le titre du livre a bien été mis à jour Toast.makeText(this, livreFromBdd.toString(), Toast.LENGTH_LONG).show(); //on supprime le livre de la BDD grâce à son ID livreBdd.removeLivreWithID(livreFromBdd.getId()); } //On essaie d'extraire de nouveau le livre de la BDD toujours grâce à son nouveau titre livreFromBdd = livreBdd.getLivreWithTitre("J'ai modifié le titre du livre"); //Si aucun livre n'est retourné if(livreFromBdd == null){ //On affiche un message indiquant que le livre n'existe pas dans la BDD Toast.makeText(this, "Ce livre n'existe pas dans la BDD", Toast.LENGTH_LONG).show(); } //Si le livre existe (mais normalement il ne devrait pas) else{ //on affiche un message indiquant que le livre existe dans la BDD Toast.makeText(this, "Ce livre existe dans la BDD", Toast.LENGTH_LONG).show(); }*/ livreBdd.close(); } } Je sais qu'il y a beaucoup de commentaires, mais je ne préfère rien virer pour le moment, on ne sait jamais ^^' Modifié 3 février 2011 par thefranchise Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Profete162 Posté(e) 3 février 2011 Share Posté(e) 3 février 2011 C'est bien gentil de créer un adapter, mais il faut l'utiliser :P getListView().setAdapter(adapter); Me semble une idée sympathique.. Edit: n'oublie pas de faire une ListActivity et non une Activity... Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 3 février 2011 Auteur Share Posté(e) 3 février 2011 Tout d'abord, merci de ta réponse Profete. J'ai donc changé extends Activity par ListActivity et rajouté getListView().setAdapter(adapter) Mais le programme plante (la fenêtre avec force close ><") Le DDMS me dit " Caused by: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'" Or, ma listview définie dans le main.xml a bien comme "android:id="@+id/list"". Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 3 février 2011 Auteur Share Posté(e) 3 février 2011 (modifié) Ne devrais-je pas faire un truc du style ListeLivre = (ListView) findViewById(R.id.list); ListeLivre.setAdapter(adapter); edit : J'ai testé ce code, et il me dit la même erreur =( Modifié 3 février 2011 par thefranchise Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 3 février 2011 Share Posté(e) 3 février 2011 Il faut mettre android:id="@+id/android:list" Et accessoirement, il faudrait stocker dans un attribut l'instance de LivresBDD que tu instancies dans le onCreate, afin de n'appeler le close que dans la méthode onDestroy (sinon, ton accès BDD va être fermé dès la fin du onCreate, et ton adpater va avoir du mal à y accéder par la suite) Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 3 février 2011 Auteur Share Posté(e) 3 février 2011 (modifié) J'ai modifié le android:id de ma ListView. maintenant je dois l'appeler comment ? Car si je laisse SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.liste, c, new String[]{"titre"},new int[]{R.id.list}); il me dit une erreur. et idem en mettant R.id.android:list. De plus, mon attribut "list" est effacé de ma classe id dans le fichier R.java. Et accessoirement, il faudrait stocker dans un attribut l'instance de LivresBDD que tu instancies dans le onCreate, afin de n'appeler le close que dans la méthode onDestroy (sinon, ton accès BDD va être fermé dès la fin du onCreate, et ton adpater va avoir du mal à y accéder par la suite) Qu'est ce que tu veux dire par stocker dans un attribut l'instance ? Une variable ? Puis je ne vois pas il faut que je modifie mon id "list" en "android:list". Au début, j'avais fait une première fois un développement. ma page principale était une liste que je définissais. Je faisais donc appel à un simpleAdapter pour la créer. Et je n'ai eu aucun soucis avec les id =/; ils avaient bien la forme "list" et pas "android:list". le fait d'utiliser un simplecursorAdapter oblige d'avoir un certain type d'id ? Modifié 3 février 2011 par thefranchise Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 3 février 2011 Share Posté(e) 3 février 2011 (modifié) Dans ton code Java, il faut mettre android.R.id.list Ce changement de nom d'id est nécessaire parce que ListActivity (dont ton Activity hérite) se base sur un identifiant bien défini pour retrouver la ListView dans ton layout (ce qui permet à la méthode getListView() de retourner la ListView qui va bien). Tu peux ne pas hériter de ListActivity, et dans ce cas ne pas être contraint sur l'id de ta ListView, mais tu perds le bénéfice apporté par ListActivity Pour ce qui est de l'attribut pour stocker l'instance de la LivresBDD, je voulais dire que, au lieu de définir une variable livreBDD dans ta méthode onCreate, il faudrait définir un attribut livreBDD dans ta classe. Comme ceci: public class test extends Activity { private LivresBDD livreBdd; // Attribut pour stocker l'instance de LivresBDD /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Création d'une instance de ma classe LivresBDD, et stockage dans l'attribut défini plus haut livreBdd = new LivresBDD(this); // blah blah blah // Enlever la fermeture de la BDD // livreBdd.close(); } @Override protected void onDestroy() { if (livreBdd != null) { livreBdd.close(); } super.onDestroy(); } } Modifié 3 février 2011 par chpil Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 3 février 2011 Auteur Share Posté(e) 3 février 2011 (modifié) J'ai réussi à ce qu'une liste s'affiche Voici ma ListActivity de test : package projet.bibliotheque; import android.app.Activity; import android.app.ListActivity; import android.database.Cursor; import android.os.Bundle; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import android.widget.Toast; public class test extends ListActivity { /** Called when the activity is first created. */ //private ListView ListeLivres; private LivresBDD livreBdd; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Création d'une instance de ma classe LivresBDD livreBdd=new LivresBDD(this); //On ouvre la base de données pour écrire dedans livreBdd.open(); Cursor c = livreBdd.getAllLivre2(); startManagingCursor(c); //mon erreur venait de là, je faisais R.layout.liste, au lieu de R.layout.list SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.list, c, new String[]{"titre"},new int[]{android.R.id.list}); //ListeLivres = (ListView) findViewById(R.id.list); //ListeLivres.setAdapter(adapter); getListView().setAdapter(adapter); } @Override protected void onDestroy() { if (livreBdd != null) { livreBdd.close(); } super.onDestroy(); } } problème, ma liste s'affiche...mais elle est vide :/ et comme vous le voyez, il y a un grand nombre d'éléments :x Vous savez à quoi c'est dû ? Modifié 4 février 2011 par thefranchise Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 4 février 2011 Share Posté(e) 4 février 2011 En y regardant de plus près, je dirais que ça vient des paramètres du SimpleCursorAdapter, qui ne sont pas corrects Tu devrais plutôt avoir ceci: SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.list, c, new String[]{"titre"},new int[]{R.id.titreLivre}); (les deux derniers paramètres permettent de faire le parallèle entre les noms des colonnes issues de ta bdd, et le nom des View de ton layout dans lesquels sera affiché le contenu des colonnes de la base) Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 4 février 2011 Auteur Share Posté(e) 4 février 2011 (modifié) \o/ Un grand merci chpil ça marche ! Bon par contre maintenant j'ai la masse de livres dans ma liste, vu que j'ai fait X essais. Faudra j'en supprime quelques uns ^^' J'espère ne pu trop avoir à vous importuner avec mes questions ^^' Euh comment on met un tag résolu ? ^^' Modifié 4 février 2011 par thefranchise Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 4 février 2011 Auteur Share Posté(e) 4 février 2011 (modifié) Mwarf suite du problème (je recréé pas de nouveau topic ?) ma liste s'affiche bien, et j'aimerais que lorsque je clique sur un élément de ma liste (qui est donc un livre :P), ses informations (auteur, editeur etc) s'affichent dans un toast. Mais je n'arrive pas à récupérer son titre :(. Enfin...quelque soit l'élément sur lequel je clique, il me récupère le titre du tout premier élément. Voici à quoi ressemble ma classe : package projet.bibliotheque; import java.util.HashMap; import android.app.Activity; import android.app.ListActivity; import android.database.Cursor; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; public class test extends ListActivity { /** Called when the activity is first created. */ //private ListView ListeLivres; private LivresBDD livreBdd; private TextView monTitre; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Création d'une instance de ma classe LivresBDD livreBdd=new LivresBDD(this); //On ouvre la base de données pour écrire dedans livreBdd.open(); Cursor c = livreBdd.getAllLivre2(); startManagingCursor(c); //pour mettre un autre élément, rajouter un textview dans list SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.list, c, new String[]{"titre"},new int[]{R.id.titreLivre}); getListView().setAdapter(adapter); //Enfin on met un écouteur d'évènement sur notre listView getListView().setOnItemClickListener(new OnItemClickListener() { @Override @SuppressWarnings("unchecked") public void onItemClick(AdapterView<?> a, View v, int position, long id) { //on récupère la HashMap contenant les infos de notre item //final HashMap<String, String> map = (HashMap<String, String>) getListView().getItemAtPosition(position); //String titre = map.get("titre"); final TextView monTitre = (TextView) findViewById(R.id.titreLivre); //Toast.makeText(test.this, "titre : "+monTitre.getText(), Toast.LENGTH_LONG).show(); Livre livreFromBdd = livreBdd.getLivreWithTitre((String) monTitre.getText()); if(livreFromBdd != null){ //On affiche les infos du livre dans un Toast Toast.makeText(test.this, livreFromBdd.toString(), Toast.LENGTH_LONG).show(); } } }); } @Override protected void onDestroy() { if (livreBdd != null) { livreBdd.close(); } super.onDestroy(); } } Dites le moi si il faut que je recréé un nouveau sujet, je supprimerai ce message ^^ Modifié 4 février 2011 par thefranchise Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 4 février 2011 Auteur Share Posté(e) 4 février 2011 Personne ? :( Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 5 février 2011 Share Posté(e) 5 février 2011 Personne ? :( Minute papillon ! Quelle impatience... La méthode onItemClick prend en paramètre un id, qui correspond à l'id, dans la base de données, de l'élément cliqué. Tu peux donc t'en servir pour récupérer les données complètes de la base public void onItemClick(AdapterView<?> a, View v, int position, long id) { Livre livreFromBdd = livreBdd.getLivreFromId(id); // implémenter getLivreFromId pour qu'elle retourne un Livre à partir de son id if (livreFromBdd != null){ //On affiche les infos du livre dans un Toast Toast.makeText(test.this, livreFromBdd.toString(), Toast.LENGTH_LONG).show(); } } Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 5 février 2011 Auteur Share Posté(e) 5 février 2011 Encore une fois merci à toi chpil :o J'vais te vouer un culte je crois xD Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 7 février 2011 Auteur Share Posté(e) 7 février 2011 (modifié) Bonjour bonjour. Je reviens vers vous pour la dernière fois (logiquement ^^'). Mon application marche en soi. Juste j'essaye de faire quelques modifs pour grapiller des points ^^' Par exemple, pour ma page d'ajout (ou de suppression) j'aimerais tester ma requête. En gros, dire que si l'ajout (ou la suppression) a réussi, j'affiche un toast. Voici mon code (ici ça concerne le click sur un bouton OK d'un alert pour la suppression...mais vou avez du le deviner ^^') public void onItemClick(AdapterView<?> a, View v, int position, long id) { //on récupère le livre en fonction de l'id de l'élément sur lequel on clique Livre livreFromBdd = livreBdd.getLivreWithId((int) id); //on récupère l'id du livre à supprimer final int idADelete = (int) id; //on créer une boite de dialogue AlertDialog.Builder adb = new AlertDialog.Builder(suppression.this); //on attribut un titre à notre boite de dialogue adb.setTitle("suppression"); //on insère un message à notre boite de dialogue, et ici on affiche le titre de l'item cliqué adb.setMessage("Voulez-vous supprimer : "+livreFromBdd.getTitre()); //on indique que l'on veut le bouton ok à notre boite de dialogue adb.setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Livre livreFromBdd = livreBdd.getLivreWithId(idADelete); String titreDelete = livreFromBdd.getTitre(); livreBdd.removeLivreWithID(idADelete); if(livreBdd.removeLivreWithID(idADelete)==1) { Toast.makeText(suppression.this, "Le livre "+titreDelete+" a été supprimé" , Toast.LENGTH_LONG).show(); } //on recharge la page pour voir la suppression Intent nextActivity = new Intent(suppression.this, suppression.class); startActivity(nextActivity); } }); adb.show(); } }); le livre se supprime, mais le toast ne s'affiche pas. Comment peut on tester l'exécution de la requête et parvenir à afficher le toast ? :/ Edit : question alakon. Je récupère une chaine final String titre = editTextTitre.getText().toString(); pour tester si elle est vide je fais : if (titre.equals(" ")) . Mais même si je met un espace dans le champ titre, le prog ne rentre pas dans la boucle. J'ai testé avec titre.length()==0 et titre.equals("") mais toujours rien :/. Au pire si ce n'est pas résolu, ce n'est pas trop trop grave, c'est juste pour essayer d'améliorer un peu l'appli ^^ Modifié 7 février 2011 par thefranchise Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 8 février 2011 Share Posté(e) 8 février 2011 livreBdd.removeLivreWithID(idADelete); if(livreBdd.removeLivreWithID(idADelete)==1) Ben, en faisant cela, tu fais deux la suppression de ton livre, et comme tu ne testes le résultat que la deuxième fois, c'est normal qu'il te dise qu'il n'a rien supprimer vu que le livre est déjà supprimé int resSuppr = livreBdd.removeLivreWithID(idADelete); if (resSuppr == 1) a plus de chance de fonctionner //on recharge la page pour voir la suppression Intent nextActivity = new Intent(suppression.this, suppression.class); startActivity(nextActivity); Ouh la la, tu vas avoir des surprises... Là, tu ne réaffiches pas réellement ton Activity, tu demandes la création d'une nouvelle instance de ton Activity, mais l'ancienne reste toujours en mémoire puisque non fermée... Tu empiles plusieurs Activities. Et si tu fais un back, tu reviendras sur la précédente instance, etc... Dans ton cas, pas la peine de réouvrir l'Activity, il suffit de demander le raffraichissement de l'affichage de ses données. Et comme tu as un Adapter, il y a une méthode pour cela sur les Adapter : notifyDataChanged Pour tester la chaine de caractère vide ou non, tu peux utiliser la méthode trim() qui permet de supprimer les espaces en début/fin de chaine. Ton test d'égalité avec la chaine vide fonctionnera alors ensuite, même si l'utilisateur saisit des espaces final String titre = editTextTitre.getText().toString(); if (titre.equals("")) Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
thefranchise Posté(e) 8 février 2011 Auteur Share Posté(e) 8 février 2011 (modifié) Encore merci à toi chpil (je l'aurais jamais dit autant en si peu de temps à la même personne ^^) Pour le notifyDataSetChanged (notifyDataChanged n'apparait pas dans la liste des fonctions que je peux appliquer à mon adapter) je n'ai pas réussi à le faire fonctionner. J'ai réussi néanmoins à ce que le formulaire se rafraichisse en refaisant une sélection de ma table, récupérée dans un curseur, et en réappliquant un adapter à ma listView public void onClick(DialogInterface dialog, int id) { //on sélectionne le livre à supprimer puis on récupère son titre. Livre livreFromBdd = livreBdd.getLivreWithId(idADelete); String titreDelete = livreFromBdd.getTitre(); //on supprime le livre int resSuppr = livreBdd.removeLivreWithID(idADelete); //si suppression, affichage d'un toast de confirmation if (resSuppr == 1) { Toast.makeText(Suppression.this, "Le livre "+titreDelete+" a été supprimé" , Toast.LENGTH_LONG).show(); } //on resélectionne les livres de la BD pour afficher la nouvelle liste. Cursor c = livreBdd.getAllLivre2(); startManagingCursor(c); SimpleCursorAdapter adapter = new SimpleCursorAdapter(Suppression.this, R.layout.list, c, new String[]{"titre"},new int[]{R.id.titreLivre}); //on applique l'adapter à la liste getListView().setAdapter(adapter); //adapter.notifyDataSetChanged(); } }); Par contre je n'arrive toujours pas à tester ma chaine titre. Je fais ça, mais ça ne marche toujours pas :/ final String titre = editTextTitre.getText().toString(); if (titre.trim().equals("")) edit : J'avais juste oublié de ne pas laisser adb.show() en commentaire -_-''' perdre du temps là-dessus j'vous jure... Merci pour tes explications et tes conseils en tout cas chpil ;) Modifié 8 février 2011 par thefranchise Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
ercanozor Posté(e) 1 juillet 2011 Share Posté(e) 1 juillet 2011 Bonjour thefranchise, Pourrais-tu faire partager ton projet entier, zipé, en PJ. J'ai quasiment le même projet à réaliser :) le partage des connaissances apporte le succès :P See you Ercanozor Citer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Recommended Posts
Rejoignez la conversation
Vous pouvez poster maintenant et vous enregistrez plus tard. Si vous avez un compte, connectez-vous maintenant pour poster.