android - SeekBar and ListView recycling issue -


i using project in new app shows list of tracks play button , seekbar progress. able tracks playing got issue updating seekbar.

i use runnable , handler update seekbar. when hit play, seekbar of child view, moving correctly, child @ recycled position got updated too. example, have list of 10 items, 5 visible items only. when 1st track's seekbar got updating, 6th track updated. same thing happening 11th or 16th... positions if have bigger list. suggestion how updated properly?

this adapter

public class listviewadapter extends baseadapter {     private activity activity;     private list<ring> list;     private layoutinflater inflater;     private int mediafilelengthinmilliseconds;     private final handler handler = new handler();     private mediaplayer player;     private assetmanager assetmanager;      public listviewadapter(activity activity, list<ring> list) {         this.activity = activity;         this.list = list;         this.inflater = layoutinflater.from(this.activity);         assetmanager = activity.getassets();         player = new mediaplayer();     }       @override     public int getcount() {         return list.size();     }      @override     public ring getitem(int position) {         return list.get(position);     }      @override     public long getitemid(int position) {         return position;     }       @override     public view getview(final int position, view convertview, viewgroup parent) {          final viewholder holder;         if (convertview == null) {             holder = new viewholder();             convertview = this.inflater.inflate(r.layout.list_view_item, parent, false);              holder.play = (imagebutton) convertview.findviewbyid(r.id.play);             holder.fav = (button) convertview.findviewbyid(r.id.fav);             holder.set = (button) convertview.findviewbyid(r.id.setas);             holder.title = (textview) convertview.findviewbyid(r.id.title);             holder.seekbarprogress = (seekbar) convertview.findviewbyid(r.id.bar);             holder.seekbarprogress.setmax(99);             holder.seekbarprogress.setenabled(false);             convertview.settag(holder);          }else{             holder = (viewholder) convertview.gettag();         }         holder.title.settext(list.get(position).getname());         holder.title.settypeface(typeface.createfromasset(activity.getassets(), "fonts/opensans-light.ttf"));         holder.play.setonclicklistener(new view.onclicklistener() {             @override             public void onclick(view v) {                 if (player.isplaying()) {                     player.pause();                     holder.play.setimagedrawable(resourcescompat.getdrawable(activity.getresources(), android.r.drawable.ic_media_play, null));                     holder.primaryseekbarprogressupdater();                 } else {                     player.reset();                     assetfiledescriptor afd = null;                     try {                         afd = assetmanager.openfd(list.get(position).getname() + ".mp3");                         player.setdatasource(afd.getfiledescriptor(), afd.getstartoffset(), afd.getlength());                         player.prepare();                         player.start();                         mediafilelengthinmilliseconds = player.getduration();                         player.setonbufferingupdatelistener(new mediaplayer.onbufferingupdatelistener() {                             @override                             public void onbufferingupdate(mediaplayer mp, int percent) {                                 holder.seekbarprogress.setsecondaryprogress(percent);                             }                         });                         holder.seekbarprogress.setontouchlistener(new view.ontouchlistener() {                             @override                             public boolean ontouch(view v, motionevent event) {                                 if (v.getid() == r.id.bar) {                                     if (player.isplaying()) {                                         seekbar sb = (seekbar) v;                                         int playpositioninmillisecconds = (mediafilelengthinmilliseconds / 100) * sb.getprogress();                                         player.seekto(playpositioninmillisecconds);                                     }                                 }                                 return true;                             }                         });                         player.setoncompletionlistener(new mediaplayer.oncompletionlistener() {                             @override                             public void oncompletion(mediaplayer mp) {                                 holder.play.setimagedrawable(resourcescompat.getdrawable(activity.getresources(), android.r.drawable.ic_media_play, null));                             }                         });                         holder.primaryseekbarprogressupdater();                         holder.play.setimagedrawable(resourcescompat.getdrawable(activity.getresources(), android.r.drawable.ic_media_pause, null));                     }catch (ioexception e) {                         e.printstacktrace();                     }                 }             }         });         return convertview;     }      private class viewholder {         textview title;         imagebutton play;         button set;         button fav;         seekbar seekbarprogress;          void primaryseekbarprogressupdater() {             seekbarprogress.setprogress((int) (((float) player.getcurrentposition() / mediafilelengthinmilliseconds) * 100)); // math construction give percentage of "was playing"/"song length"             if (player.isplaying()) {                 runnable notification = new runnable() {                     public void run() {                         primaryseekbarprogressupdater();                     }                 };                 handler.postdelayed(notification,100);             }         }     } } 

as pointed out, list view items recycled. such, handler should updating backing data model value of seekbar , calling notifydatasetchanged() on adapter. actual setting of seekbar value should handled adapter's getview().

this not perfect fix because there lot of problems code, should address issue of multiple list items being updated.

  1. add position variable backing list model.
  2. pass in position of item updating primaryseekbarprogressupdater
  3. call notifydatasetchanged()
  4. in getview, set seekbar position based on backing data model

void primaryseekbarprogressupdater(final int i) {     list.get(i).setposition((int) (((float) player.getcurrentposition() / mediafilelengthinmilliseconds) * 100)); // math construction give percentage of "was playing"/"song length"     notifydatasetchanged();     if (player.isplaying()) {         runnable notification = new runnable() {             public void run() {                 primaryseekbarprogressupdater(i);             }         };         handler.postdelayed(notification,100);     } } 

public view getview(final int position, view convertview, viewgroup parent) {     ...     holder.seekbarprogress.setprogress(list.get(position).getposition());     ... } 

Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -