recycler view reset items - android -
i've been working on app quite time now. app supposed take family names , measure visit time, constant(30 minutes). have family object holds info such name, number of members , end of visit, represented future milliseconds value.
the way i've implemented timers part create class called countdownmanager responsible updating , calculating remaining time families' view holders listed.
the problem is, if clean data(holders , dataset) , add new family, family not added countdowntimer class.
here image when family added correctly:
and here image after clean data , try add new family:
here codes adapter, view holder , counddownmanager class:
package bikurim.silverfix.com.bikurim.adapters; import android.content.context; import android.graphics.drawable.drawable; import android.support.v4.content.contextcompat; import android.support.v7.widget.helper.itemtouchhelper; import android.util.log; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.filterable; import android.widget.toast; import java.util.arraylist; import bikurim.silverfix.com.bikurim.constants; import bikurim.silverfix.com.bikurim.adapters.holders.familyviewholder; import bikurim.silverfix.com.bikurim.adapters.holders.genericviewholder; import bikurim.silverfix.com.bikurim.adapters.holders.timeupviewholder; import bikurim.silverfix.com.bikurim.models.family; import bikurim.silverfix.com.bikurim.r; import bikurim.silverfix.com.bikurim.utils.managers.mediaplayermanager; import bikurim.silverfix.com.bikurim.utils.utils; import bikurim.silverfix.com.bikurim.utils.interfaces.holderlistener; import bikurim.silverfix.com.bikurim.utils.managers.countdownmanager; import bikurim.silverfix.com.bikurim.utils.interfaces.eventlistener; public class familiesadapter extends genericadapter implements filterable, eventlistener, holderlistener { // last position holds last position of element added, animation purposes private static int lastposition = -1; private int[] viewtypes; private itemtouchhelper touchhelper; private countdownmanager countdownmanager; public familiesadapter(context context, arraylist<family> families, itemtouchhelper touchhelper) { super(context, families); this.touchhelper = touchhelper; viewtypes = constants.tags.view_types; countdownmanager = new countdownmanager(constants.values.time_interval, this); countdownmanager.start(); } @override public genericviewholder oncreateviewholder(viewgroup parent, int viewtype) { // inflating view given layout resource file log.d("a function has called", "oncreateviewholder() invoked"); view v; switch (viewtype) { case constants.tags.family_view: v = layoutinflater.from(context).inflate(r.layout.family_list_item, parent, false); familyviewholder fvh = new familyviewholder(context, v); return fvh; case constants.tags.time_up_view: v = layoutinflater.from(context).inflate(r.layout.timeup_list_item, parent, false); timeupviewholder tvh = new timeupviewholder(context, v, this); return tvh; } return null; } @override public void onbindviewholder(genericviewholder holder, int position) { // binds family object holder view family family = families.get(position); holder.binddata(family); log.d("a function has called", "onbindviewholder() invoked, family added: " + ((familyviewholder) holder).isholderadded); if(holder instanceof familyviewholder){ if(!((familyviewholder) holder).isholderadded) { countdownmanager.addholder((familyviewholder) holder); ((familyviewholder) holder).isholderadded = true; } } // sets animation on given view, in case wasn't displayed before utils.setslideanimation(context, holder.getview(), position, lastposition, false); } @override public int getitemviewtype(int position) { if(families.get(position).wheninmillis <= system.currenttimemillis()) return viewtypes[1]; return viewtypes[0]; } /* changes ui of holder time's view flickering imagebutton , textview*/ @override public void onfinish(familyviewholder holder) { // resets holder future uses holder.reset(); // play sound notifying purposes mediaplayermanager.playsound(mediaplayermanager.sound.end); // vibrates device 1.5 seconds utils.vibrate(context, constants.values.vibration_length_short); notifyitemchanged(holder.getadapterposition()); } @override public void onlessthanminute(familyviewholder holder) { // if sound option on, play swoosh sound mediaplayermanager.playsound(mediaplayermanager.sound.alert); drawable stroke = contextcompat.getdrawable(context, r.drawable.family_item_red_stroke); holder.frame.setbackground(stroke); utils.setfadeanimation(holder.frame); holder.isstrokechanged = true; } @override public void onremovetimeupviewholder(int pos, genericviewholder holder) { touchhelper.startswipe(holder); removedata(pos, holder); } public void removedata(int pos, genericviewholder holder) { // sets last position given deleted position animation purposes lastposition = pos; // removes family object data set string name = utils.getlastname(families.get(pos).name); families.remove(pos); notifyitemremoved(pos); notifyitemrangechanged(pos, getitemcount()); if(holder instanceof familyviewholder) // cancels the timer , removes entry set countdownmanager.removeholder((familyviewholder) holder); holder.reset(); toast.maketext(context, "משפחת "+name+" נמחקה מהרשימה", toast.length_short).show(); } /* cancels timers , clears entry set */ public void canceltimers() { countdownmanager.reset(); countdownmanager.clear(); countdownmanager.stop(); } /* clears adapter's data , resets last position -1 */ @override public void cleardata() { super.cleardata(); canceltimers(); lastposition = -1; } }
familyviewholder:
package bikurim.silverfix.com.bikurim.adapters.holders; import android.content.context; import android.content.res.colorstatelist; import android.graphics.drawable.drawable; import android.support.v4.content.contextcompat; import android.support.v7.widget.cardview; import android.view.view; import android.widget.imagebutton; import android.widget.imageview; import android.widget.relativelayout; import android.widget.textview; import bikurim.silverfix.com.bikurim.r; import bikurim.silverfix.com.bikurim.models.family; import bikurim.silverfix.com.bikurim.utils.utils; /** * created david on 07/07/2016. * * official view holder of adapter. holds references relevant views inside layout */ public class familyviewholder extends genericviewholder { public boolean isstrokechanged, isholderadded; public cardview cardview; public relativelayout frame; public textview name; public textview timeleft; public textview visitors; public family family; private colorstatelist colorstatelist; public familyviewholder(context context, view v) { super(v, context); // isstrokechanged represents whether holder under 60 seconds or not isstrokechanged = false; isholderadded = false; // getting references ui components cardview = (cardview) v.findviewbyid(r.id.cv); frame = (relativelayout) v.findviewbyid(r.id.card_frame); name = (textview) v.findviewbyid(r.id.person_lname); visitors = (textview) v.findviewbyid(r.id.visitors); timeleft = (textview) v.findviewbyid(r.id.person_timeleft); // sets reference old colors of text view colorstatelist = timeleft.gettextcolors(); } @override public void binddata(family family) { this.family = family; name.settext(utils.formatnamestring(family.name)); visitors.settext(" מבקרים: "+family.visitorsnum); } @override public void reset() { family = null; name.settext(""); visitors.settext(""); timeleft.settext(""); drawable drawable = contextcompat.getdrawable(context, r.drawable.family_item_blue_stroke); this.frame.clearanimation(); this.frame.setanimation(null); this.frame.setbackground(drawable); isstrokechanged = false; isholderadded = false; } public colorstatelist getoriginalcolors() { return colorstatelist; } }
countdownmanager:
package bikurim.silverfix.com.bikurim.utils.managers; import android.os.handler; import android.os.message; import android.util.log; import java.util.arraylist; import java.util.concurrentmodificationexception; import bikurim.silverfix.com.bikurim.constants; import bikurim.silverfix.com.bikurim.adapters.holders.familyviewholder; import bikurim.silverfix.com.bikurim.utils.interfaces.eventlistener; import bikurim.silverfix.com.bikurim.utils.utils; /** * created david on 07/07/2016. * @author david * inspired miguellavigne * * custom countdowntimer class, takes care of running timers */ public class countdownmanager { private final long interval; private long base; // holds references visible text views private arraylist<familyviewholder> holders; private eventlistener listener; public countdownmanager(long interval, eventlistener listener) { this.listener = listener; this.interval = interval; holders = new arraylist<>(); } public void start() { base = system.currenttimemillis(); handler.sendmessage(handler.obtainmessage(msg)); } public void stop() { handler.removemessages(msg); } public void reset() { synchronized (this) { base = system.currenttimemillis(); } } public void addholder(familyviewholder holder) { synchronized (holders) { holders.add(holder); } } public void removeholder(familyviewholder holder) { synchronized (holders) { holders.remove(holder); } } private void ontick(long elapsedtime) { try { if(!holders.isempty()) { long timeleft, lengthofvisit; (familyviewholder holder : holders) { lengthofvisit = holder.family.wheninmillis - base; timeleft = lengthofvisit - elapsedtime; if(timeleft > 0) { if(timeleft <= constants.values.alert_time && !holder.isstrokechanged) { listener.onlessthanminute(holder); } holder.family.timeleft = timeleft; holder.timeleft.settext(utils.updateformattime(timeleft)); } else { listener.onfinish(holder); removeholder(holder); } } log.d("holder length:", "" + holders.size()); } } catch (concurrentmodificationexception e) { log.d("concurrent error", "app shut down now"); e.printstacktrace(); } } public void clear() { synchronized (holders) { for(familyviewholder holder : holders) holder.reset(); holders.clear(); } } private static final int msg = 1; private handler handler = new handler() { @override public void handlemessage(message msg) { synchronized (countdownmanager.this) { long elapsedtime = system.currenttimemillis() - base; ontick(elapsedtime); sendmessagedelayed(obtainmessage(msg), interval); } } }; }
what problem?
Comments
Post a Comment