Introducing the open Source control pulltorefresh drop-down refresh list
Each drop-down will send a request to return JSON information from the interface.
If there are duplicate data in the data returned by the previous two requests, how do I get to the list?
In the previous article, we rewrote the hashcode and equals methods of entity Data
/*** Because the update time and unixtime are not unique * Here use unique identification Hashid to get the hash code*/@Override Public inthashcode () {Final intPrime = 31; intresult = 1; Result= Prime * result + ((Hashid = =NULL) ? 0: Hashid.hashcode ()); returnresult; } /*** Because the update time and unixtime are not unique * Here use unique identification Hashid to compare*/@Override Public Booleanequals (Object obj) {if( This==obj)return true; if(obj = =NULL) return false; if(GetClass ()! =Obj.getclass ())return false; Data Other=(Data) obj; if(Hashid = =NULL) { if(Other.hashid! =NULL) return false; } Else if(!hashid.equals (Other.hashid))return false; return true; }
Because only Hashid is uniquely identified in data, we use it to compare
Use the attribute in set that cannot be added to re-element as the judging condition to re-
/*** Rewrite the hashcode and equals method in data * Use the attribute of the set cannot add re-element as the judging condition * the non-repeating data element is placed in a temporary newlist * After the loop is complete, the original list is emptied, a Ddall (newlist) *@paramlist *@return */ Public StaticList<data> Removeduplicatedatainorder (list<data>list) {HashSet<Data> HashSet =NewHashset<data>(); List<Data> NewList =NewArraylist<data>(); for(Iterator Iterator =list.iterator (); Iterator.hasnext ();) {Data element=(Data) iterator.next (); if(Hashset.add (Element)) {Newlist.add (element); }} list.clear (); List.addall (NewList); returnlist; }
And in order to keep the order of the data, we should do the following before we repeat it.
1. If it is a drop-down refresh in the add data to the head of List List.addall (0,list<t>)
2. Load the data into the tail list.addall (list<t>) If it is a pull-up load
The aggregation data interface can also return a list of jokes before or after that point in time by timestamp
Sample Request: http://japi.juhe.cn/joke/content/list.from?key= you apply for the Key&page=2&pagesize=10&sort=asc&time= 1418745237
The sort param in the parameter, sort desc: Published before the specified time, ASC: Published after the specified time, time represents timestamp
So we use this request method when the pull-up loads more, to return the list of jokes before that point in time with the timestamp of the last data in the current list.
Therefore, the list does not need to be repeated when the pull-up loads more.
if(Flag = =Pull_down_refresh_flag) { //add newly refreshed data to the head of the datasetMcurrentlistitems.addall (0, Result.getresult ()); //Remove duplicate data from listMcurrentlistitems =Utilshelper.removeduplicatedatainorder (Mcurrentlistitems); }Else if(Flag = =Pull_up_refresh_flag) { //add newly loaded data to the end of the dataset//because it is the timestamp of the last data forward query, so there is no duplication, do not need a list to re -Mcurrentlistitems.addall (Result.getresult ()); Pulluppagenumber++; }
How to get the number of data updated after this request, it is very simple to save the last list, and the latest list size to do.
Using handler processing and updating the UI on the main thread
if NULL ) { int count = mcurrentlistitems.size ()- mlastlistitems.size (); New Android.os.Message (); = update_data_count_message; = count; Mhandler.sendmessage (msg);}
Then notify the adapter that the data set changed and call the ListView (ListView is an instance of Pulltorefreshlistview) Onrefreshcomplete () method
// notifies the program that the dataset has changed and will not refresh the collection of Mlistitems if no notification is made madapter.notifydatasetchanged (); Mlistview.onrefreshcomplete ();
Assuming we're in a network-free environment, it's necessary to have a cache for offline viewing, preferably caching the list data that was displayed the last time we exited the app.
No use of SQLite, temporary use of files, cache to a directory in SDcard (/storage/emulated/0/qingsongyike/cache)
Public Static voidsavejsontextinlocalfile (String jsondata) {BooleanSdcardexist =environment.getexternalstoragestate (). Equals (Android.os.Environment.MEDIA_MOUNTED);//determine if the SD card exists if(sdcardexist) {LOG.D ("Utilshelper", "sdcard exist."); File Root=environment.getexternalstoragedirectory (); String Path= Root.getpath () +file.separator+ "Qingsongyike" +file.separator+ "cache"; LOG.D ("Utilshelper", "dir path =" +path); File File=NewFile (path); if(!file.exists ()) {File.mkdirs (); LOG.D ("Utilshelper", "Cache dir had create finished."); } File cachefile=NewFile (path+file.separator+ "Cache.txt"); if(!cachefile.exists ()) { Try{cachefile.createnewfile (); LOG.D ("Utilshelper", "File path =" +path); LOG.D ("Utilshelper", "cache file is created."); } Catch(IOException e) {e.printstacktrace (); } } Try { synchronized(obj) {fileoutputstream fos=NewFileOutputStream (Cachefile,false); OutputStreamWriter writer=Newoutputstreamwriter (FOS); Writer.write (Jsondata); Writer.flush (); Writer.close (); Fos.close (); } log.d ("Utilshelper", "cache data write finished."); //Fos.write (Jsondata.getbytes ()); //Fos.flush ();}Catch(FileNotFoundException e) {e.printstacktrace (); } Catch(IOException e) {e.printstacktrace (); } }Else{LOG.D ("Utilshelper", "sdcard is not exist. Create Cache file Failed "); } }
Then we need to reassemble the list data into objects and use Gson's API function to convert the bean to a JSON string
Open a sub-thread to do IO operation
classCachethreadImplementsrunnable{@Override Public voidrun () {//perform a cache operation to reorganize the latest data into objects and convert them to JSON characters//Not enough 50 is cached//more than 50 cache only the first 50 bars//Avoid cache file large Read slowString Jsondata =NULL; List<Data> list =NewArraylist<data>(); List.addall (Mcurrentlistitems); if(List.size () > 0 && list.size () < 50) {Jsondata= Utilshelper.beanconverttojson (NewMessage (0, "Success", list)); }Else if(List.size () >= 50){ //Remove all 50 bars from the listLOG.D ("Cachethread", "list size is more than 50!"); for(inti = List.size ()-1; I >= 50; i--) {list.remove (i); } log.d ("Cachethread", "list remove finish." Size now is 50! "); Jsondata= Utilshelper.beanconverttojson (NewMessage (0, "Success", list)); }Else{LOG.D ("Cachethread", "list size is 0!"); } //save JSON characters locally so you can browse offline without a network if(Jsondata! =NULL) {utilshelper.savejsontextinlocalfile (jsondata); }Else{LOG.D ("Cachethread", "Jsondata is NULL!!"); } } }
This will only intercept up to 50 joke messages to avoid slow read and write problems caused by large data volumes.
The function where the bean is converted to a JSON string is as follows
// Bean conversion JSON Public Static String Beanconverttojson (Object obj) { new Gson (); = Gson.tojson (obj); LOG.D ("Utilshelper", "JSON =" + json); return json; }
Don't forget to add permissions for SDcard operations and file read and write in Androidimanfest.xml
<!--Create and delete file permissions in SDcard -<uses-permissionAndroid:name= "Android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><!--Write Data permission to SDcard -<uses-permissionAndroid:name= "Android.permission.WRITE_EXTERNAL_STORAGE"/><!--read data permissions from SDcard -<uses-permissionAndroid:name= "Android.permission.READ_EXTERNAL_STORAGE"/>
As soon as we have the updated data, we perform a local cache operation.
The contents of the open file have been written in.
Not to be continued ...
"Easy Moment" practical project Development (ii) list data deduplication and caching