java - Android ListView Adapter error calling notifyDataSetChanged, Android bug? -


in app i've been working on, have custom class devicelistadapter extending baseadapter gets passed listview. in devicelistadapter class, keep own arraylist<device> use generate list's views view getview(... ). whenever app causes change in data, use custom methods in devicelistadapter update arraylist<device> reflect changes. i've used debugger , many print statements check data changed how expect to, adding , removing device objects specified. however, after each change data call notifydatasetchanged(), on ui none of elements updated. in debugger, found after calling notifydatasetchanged(), getview(... ) method not being called, explains why listview wasn't being redrawn. figure out why, used debugger's "step into" function trace program execution went android framework since have sdk sources downloaded. found interesting. path of execution went this:

devicelistadapter.notifydatasetchanged() baseadapter.notifydatasetchanged() datasetobservable.notifychanged() abslistview.oninvalidated() 

enter image description here enter image description here enter image description here enter image description here

rather calling onchanged() method, jumped tracks , executed oninvalidated() method once reached abslistview. thought error debugger perhaps reading wrong line number, restarted android studio totally uninstalled , reinstalled app, result same. can tell me if legitimately problem android's framework or if debugger unreliable tracing execution outside of own project files?

more on implementation of notifydatasetchanged()... created local method override baseadapter's notifydatasetchanged() set boolean flag mforceredraw inside of devicelistadapter whether should force redraw list entries. in getview(... ) method, typically check if second parameter, view convertview null, if redraw view , if not pass convertview through , return it. however, when 'mforceredraw' true, never return convertview, explicitly redraw view. problem arises caused earlier concern, getview() not called after execute notifydatasetchanged().

edit: here's code snippet of devicelistadapter:

    /**      * serves data current device data mdevicelistview.  manages dynamic ,      * persistent storage of configured devices , constructs views of each individual      * list item placement in list.      */     private class devicelistadapter extends baseadapter {          private boolean mforceredraw = false;          /**          * dynamic array keeps track of devices being managed.          * held in memory , readily accessible system calls          * requesting view updates can satisfied quickly.          */         private list<device> mdeviceentries;         private context mcontext;          public devicelistadapter(context context) {             this.mcontext = context;             this.mdeviceentries = new arraylist<>();             populatefromstorage();         }          /**          * inserts given device storage , notifies mdevicelistview of data update.          * @param newdevice device add memory.          */         public void put(device newdevice) {             preconditions.checknotnull(newdevice);             boolean flagupdatedexisting = false;             (device device : mdeviceentries) {                 if (newdevice.isversionof(device)) {                     int index = mdeviceentries.indexof(device);                     if(index != -1) {                         mdeviceentries.set(index, newdevice);                         flagupdatedexisting = true;                         break;                     } else {                         throw new illegalstateexception();                 }             }             //if existing device not updated, new device, add list             if (!flagupdatedexisting) {                 mdeviceentries.add(newdevice);             }             tecdataadapter.setdevices(mdeviceentries);             notifydatasetchanged();         }          /**          * if given device exists in storage, delete , remove mdevicelistview.          * @param device          */         public void delete(device device) {             preconditions.checknotnull(device);             //remove device mdeviceentries             iterator iterator = mdeviceentries.iterator();             while(iterator.hasnext()) {                 device d = (device) iterator.next();                 if(device.isversionof(d)) {                     iterator.remove();                 }             }             tecdataadapter.setdevices(mdeviceentries);             notifydatasetchanged();         }          /**          * retrieves device entries persistent storage , loads them dynamic          * array responsible displaying entries in listview.          */         public void populatefromstorage() {             list<device> temp = preconditions.checknotnull(tecdataadapter.getdevices());             mdeviceentries = temp;             notifydatasetchanged();         }          public int getcount() {             if (mdeviceentries != null) {                 return mdeviceentries.size();             }             return 0;         }          public object getitem(int position) {             return mdeviceentries.get(position);         }          public long getitemid(int position) {             return position;         }          public view getview(final int position, view convertview, viewgroup parent) {             linearlayout view;             if (convertview == null || mforceredraw) //regenerate view             {                /* draws views */              } else //reuse view             {                 view = (linearlayout) convertview;             }             return view;         }          @override         public void notifydatasetchanged() {             mforceredraw = true;             super.notifydatasetchanged();             mforceredraw = false;         }     } 

you in adapter , calling notify dataset changed.this ideally not needed.because are modifying dataset used internally adapter.the getview method of adapter called whenever view needs rendered.

the convertview approach solely recycle view(not data).it merely provides alternative expensive process of view inflation.

so code should :

public view getview(final int position, view convertview, viewgroup parent) {             linearlayout view;             if (convertview == null) //regenerate view             {                /* inflate draws views */              } else              {                 view = (linearlayout) convertview;              }              //repopulate view data needs appear @ position using getitem(position)               return view;         } 

Comments

Popular posts from this blog

c++ - No viable overloaded operator for references a map -

java - Custom OutputStreamAppender not run: LOGBACK: No context given for <MYAPPENDER> -

java - Cannot secure connection using TLS -