Floy78 Posté(e) 23 août 2010 Share Posté(e) 23 août 2010 Bonjour, je rencontre un problème concernant les ListView et leur mise à jour. Je cherche à afficher une seekbar + deux textview par item de la liste afin de controler un mediaplayer. Un item de la liste représentant une piste audio. Lorsque l'on clique sur un item, le lancement de la piste est déclanché, j'ai donc un OnItemClickListener de définit, cela fonctionne bien, la piste se lance et la seekbar et les textview réagissent correctement : modeManuel.setOnItemClickListener(new OnItemClickListener() { @Override @SuppressWarnings("unchecked") public void onItemClick(AdapterView<?> a, View v, int position, long id) { if(lastItemClick != -1){ prevPiste = (PisteAudio) a.getItemAtPosition(lastItemClick); prevPiste.setClicked(false); prevPiste.getMp().stopAudio(); prevPiste.getTp().startAnimation(animHideMP); descPiste.setVisibility(View.VISIBLE); } piste = (PisteAudio) a.getItemAtPosition(position); mpPos = (TextView) v.findViewById(R.id.mp_pos_manuel); mpTotalTime = (TextView) v.findViewById(R.id.mp_totaltime_manuel); sb = (SeekBar) v.findViewById(R.id.SeekBarManuel); descPiste = (TextView)v.findViewById(R.id.mode_manuel_desc); descPiste.setVisibility(View.GONE); trans = (TransparentPanel) v.findViewById(R.id.transparent_panel_manuel); trans.setVisibility(View.VISIBLE); trans.startAnimation(animShow); mp = new MP(mpPos,mpTotalTime,sb,"/sdcard/xxx/xxx/.." + piste.getIdPiste() +".mp3",trans,animHideMP,tel); mp.startAudio(); piste.setMpPos(mpPos); piste.setMpTotalTime(mpTotalTime); piste.setSb(sb); piste.setTp(trans); piste.setMp(mp); piste.setDescPiste(descPiste); piste.setClicked(true); lastItemClick = position; } }); Mais lorsque je fais un scroll et que ma piste passe hors ecran, puis que je reviens dessus, alléatoirement je perd la référence à ma vue et à mes objets : Voici le code surchagé de getView : @Override public View getView(int position, View convertView, ViewGroup parent){ MyTag holder; if(convertView == null){ convertView = mInflater.inflate(R.layout.modemanuel,parent, false); holder = new MyTag(); holder.descPiste = (TextView)convertView.findViewById(R.id.mode_manuel_desc); holder.mpPos = (TextView)convertView.findViewById(R.id.mp_pos_manuel); holder.mpTotalTime = (TextView)convertView.findViewById(R.id.mp_totaltime_manuel); holder.noPiste = (TextView)convertView.findViewById(R.id.mode_manuel_piste); holder.sb = (SeekBar)convertView.findViewById(R.id.SeekBarManuel); holder.tp = (TransparentPanel)convertView.findViewById(R.id.transparent_panel_manuel); convertView.setTag(holder); }else{ holder = (MyTag)convertView.getTag(); } Log.d("debugModeManuel","Convert View: "+String.valueOf(convertView)); idPiste = mListPiste.get(position).getIdPiste(); holder.noPiste.setText("Piste " + idPiste); holder.descPiste.setText("bla bla bla ..."); if(mListPiste.get(position).isClicked() || mListPiste.get(position).isActivAllSB()){ holder.tp.setVisibility(View.VISIBLE); holder.descPiste.setVisibility(View.GONE); }else{ holder.tp.setVisibility(View.GONE); holder.descPiste.setVisibility(View.VISIBLE); } return convertView; } Je sais que le nombre de vue créé dans une listview est le nombre d'item maximal affiché simultanément à l'écran et que ces vues sont recyclées pour les autres Items , mais je ne comprend pas comment récupérer la vue crée pour un item donné .... Si un pro des ListView passe par là ... Merci d'avance ! Lien vers le commentaire Partager sur d’autres sites More sharing options...
akex Posté(e) 23 août 2010 Share Posté(e) 23 août 2010 via la donnée position qui correspond à la position de ton élément dans ta liste. Après, à toi d'enrichir le holder ou ta source de données en fonction du onclick. Oups. Semblerait que tu utilises déjà la donnée position. J'ai rien dit. Edit : n'oublie pas que tu peux tagguer n'importe laquelle de tes vues avec n'importe quel objet (piste, mp). De ce fait, tu peux récupérer ton élément sous condition. Exemple : dans mon cas, je chargeais des photos en asynchro. Le hic, c'est que les vues étant récyclées, certaines images ne correspondait pas à l'item. J'ai donc taggué mon ImageView avec mon id de photo. Et quand mon id obtenu via gettag correspondait à mon id obtenu depuis le curseur, je savais que j'étais sur la bonne vue ---> Chargement de la photo. Je ne sais pas si ça va t'aider, mais travaillant depuis un certain temps sur les listview j'ai appris que c'était démoniaque :). Un peu plus de code ne serait pas du luxe, car là, je peux t'aider davantage. Comment récupères tu le temps écoulé etc ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
akex Posté(e) 23 août 2010 Share Posté(e) 23 août 2010 Edit : suffit de tagguer ton Holder.noPiste (par exemple avec ton numéro de piste et un des textview avec ton objet mp. De là, si position = (int) holder.noPiste.getTag() alors tu récupères le mp via un autre getTag (ou encore mieux, tu créés un objet qui englobe ton id de piste ainsi que ton mp). En espérant que ce soit plus clair :). Lien vers le commentaire Partager sur d’autres sites More sharing options...
Floy78 Posté(e) 23 août 2010 Auteur Share Posté(e) 23 août 2010 Salut akex ! Merci pour ta réponse rapide ;) Pour le temps écoulé et la position de la seekbar tout se fait dans ma classe classe personnalisé du mediaplayer "MP". En fait cette classe attend en paramètre du constructeur les deux textview et la seekbar, puis elle se charge de leur mise à jour. Le problème c'est qu'en faisant ça, des que l'item de la listview est recyclé, ma classe MP perd les référence aux objets (enfin non elle continu de les modifier sauf qu'ils sont affectés à d'autres items, donc la seekbar d'un autre item se met à bouger ... ) 1 - Tu penses que je devrait recoder mon MP et externaliser la gestion du controle de la piste ? 2 - ou alors, re-setter les objets de contrôle dans le MP des leur modification dans la ListView ? Sinon je n'ai pas tout compris par rapport aux tags, je les ai utilisés suivant les recommandations des démos API android. J'ai compris que ça permettait de stoquer les vues de chaque item et ainsi éviter de réutiliser le "findViewById" pour optimiser les calculs. Par contre je ne voit pas comment l'utiliser pour arriver à mes fins ... EDIT: Finalement après quelques tests et en suivant tes conseils sur les holders, je met à jour les textview et la seekbar directement dans mon objet MP, qui peut continuer à les modifier ! (option 2 ) Merci beaucoup ;) Bonne soirée et à plus tard ! Lien vers le commentaire Partager sur d’autres sites More sharing options...
Recommended Posts
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.