Android Chamber Federated Asynclistutil implements Recyclerview page load ORM data
I wrote a series of page loading mechanisms and technical routes for asynclistutil implementation of Recyclerview and ListView, see Appendix 4, 5. Also wrote a list of articles about the official Android ORM database: The Office technology, see appendix article 1, 2. Now combined with Android page loading framework asynclistutil, as well as the Android official ORM database room, the database data page is loaded into Recyclerview.
First give an example, to implement a simple function, in the Android Chamber database to add a batch of data, and then when the Recyclerview scrolling, trigger the page load logic, the data in the database page fragment loading, the data stored in this example is user.
Mainactivity.java:
Package Zhangphil.demo;import Android.arch.persistence.room.room;import Android.os.systemclock;import Android.support.v7.app.appcompatactivity;import Android.os.bundle;import Android.support.v7.util.AsyncListUtil; Import Android.support.v7.widget.linearlayoutmanager;import Android.support.v7.widget.recyclerview;import Android.util.log;import Android.view.layoutinflater;import Android.view.view;import Android.view.ViewGroup;import Android.widget.linearlayout;import Android.widget.textview;import Java.util.list;public class MainActivity extends appcompatactivity {private final String TAG = "Output"; Private Recyclerview.adapter Madapter; Private Linearlayoutmanager Mlinearlayoutmanager; Private asynclistutil<user> Masynclistutil; Private final int LIMIT = 10; Private Userdatabase muserdatabase; Private Userdao Muserdao; @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Muserdatabase = Room.databasEbuilder (Getapplicationcontext (), Userdatabase.class, "users"). Build (); Muserdao = Muserdatabase.getuserdao (); Setcontentview (R.layout.activity_main); Recyclerview Mrecyclerview = Findviewbyid (R.id.recycler_view); Mlinearlayoutmanager = new Linearlayoutmanager (this); Mlinearlayoutmanager.setorientation (linearlayout.vertical); Mrecyclerview.setlayoutmanager (Mlinearlayoutmanager); Madapter = new Myadapter (); Mrecyclerview.setadapter (Madapter); Myviewcallback mviewcallback = new Myviewcallback (); Mydatacallback mdatacallback = new Mydatacallback (); Masynclistutil = new Asynclistutil<> (User.class, LIMIT, Mdatacallback, Mviewcallback); Mrecyclerview.addonscrolllistener (New Recyclerview.onscrolllistener () {@Override public void Onscro Llstatechanged (Recyclerview recyclerview, int newstate) {super.onscrollstatechanged (Recyclerview, NewState ); LOG.D (TAG + "onscrollstatechanged", "onrangechanged"); Masynclistutil.onrangechanged (); } }); Findviewbyid (R.id.button). Setonclicklistener (New View.onclicklistener () {@Override public void Oncl Ick (View v) {log.d (TAG + "Refresh", "refresh"); Masynclistutil.refresh (); } }); Findviewbyid (R.id.add_data). Setonclicklistener (New View.onclicklistener () {@Override public void on Click (View v) {New Thread (new Runnable () {@Override public void run () {writedatabase (); }}). Start (); } }); Proactively refresh data. New Thread (New Runnable () {@Override public void run () {systemclock.sleep (500); Masynclistutil.refresh (); }}). Start (); } Private Class Mydatacallback extendsasynclistutil.datacallback<user> {@Override public int refreshdata () {//update the number of elements of the data. LOG.D (TAG + "RefreshData", Integer.max_value + ""); return integer.max_value; /** * The time-consuming task of completing time-consuming data loading here. * * @param data * @param startposition * @param itemCount */@Override Publi c void Filldata (user[] data, int startposition, int itemCount) {log.d (TAG + "Filldata", StartPosition + "," + ItemCount); list<user> list = Muserdao.getuserwhereuseridbigthan (startposition, ItemCount); for (int i = 0; i < list.size (); i++) {Data[i] = List.get (i); }}} Private class Myviewcallback extends Asynclistutil.viewcallback {@Override public void g Etitemrangeinto (int[] outrange) {outrange[0] = mlinearlayoutmanager.findfirstvisibleitemposition (); OUTRANGE[1] = MlinearlayOutmanager.findlastvisibleitemposition (); LOG.D (TAG + "Getitemrangeinto", outrange[0] + "~" + outrange[1]); } @Override public void Ondatarefresh () {madapter.notifyitemrangechanged (mlinearlayoutmanager.fi Ndfirstvisibleitemposition (), LIMIT); LOG.D (TAG + "Ondatarefresh", mlinearlayoutmanager.findfirstvisibleitemposition () + "," + Mlinearlayoutmanager.findlastvisibleitemposition ()); } @Override public void onitemloaded (int position) {madapter.notifyitemchanged (position); LOG.D (TAG + "onitemloaded", string.valueof (position)); }} Private class Myadapter extends Recyclerview.adapter<myviewholder> {public myadapter () { Super (); } @Override Public Myviewholder oncreateviewholder (viewgroup viewgroup, int i) {View view = Layo Utinflater.from (Getapplicationcontext ()). Inflate (R.layout.item_layout, ViewGroup, false);Myviewholder holder = new Myviewholder (view); return holder; } @Override public void Onbindviewholder (Myviewholder viewholder, int i) {User u = Masynclistuti L.getitem (i); Viewholder.setdata (U); } @Override public int getitemcount () {return masynclistutil.getitemcount (); }} Private class Myviewholder extends Recyclerview.viewholder {public TextView userId; Public TextView UserName; Public TextView Userage; Public Myviewholder (View Itemview) {super (Itemview); UserId = Itemview.findviewbyid (r.id.user_id); UserName = Itemview.findviewbyid (r.id.user_name); Userage = Itemview.findviewbyid (r.id.user_age); The public void SetData (User u) {if (U! = null) {Userid.settext ("ID:" + string.valueof (U. USERID)); Username.settext ("Name:" + string.valueof (u.name)); Userage.settext ("Age:" + string.valueof (u.age)); }}} private void Writedatabase () {LOG.D (TAG + "Writedatabase", "Start writing data ..."); for (int i = 0; i <; i++) {User user = new User (); User.Name = "Zhang" + i; User.age = (int) (Math.random () * 100); User.updatetime = System.currenttimemillis (); Muserdao.insertuser (user); } log.d (TAG + "Writedatabase", "Write Database Complete."); } @Override protected void OnDestroy () {Super.ondestroy (); Muserdatabase.close (); }}
Mainactivity Required layout file Activity_main.xml:
<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android " android:layout_width=" match_parent " android:layout_height=" match_parent " android:o rientation= "vertical" > <button android:id= "@+id/button" android:layout_width= "Wrap_content" android:layout_height= "wrap_content" android:text= "Update"/> <button android:id= "@+id/add_ Data " android:layout_width=" wrap_content " android:layout_height=" wrap_content " android:text=" Add Data "/> <android.support.v7.widget.recyclerview android:id=" @+id/recycler_view " android: Layout_width= "Match_parent" android:layout_height= "Match_parent"/></linearlayout>
Item_layout.xml:
<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android "Android:layout_width=" Match_parent "android:layout_height=" wrap_content "android:orientation=" vertical " android:padding= "20DP" > <textview android:id= "@+id/user_id" android:layout_width= "Match_parent" android:layout_height= "Wrap_content" android:background= "@android: Color/holo_red_light"/> <TextVie W android:id= "@+id/user_name" android:layout_width= "match_parent" android:layout_height= "wrap_content "Android:textcolor=" @android: Color/holo_orange_light "/> <textview android:id=" @+id/user_age " Android:layout_width= "Match_parent" android:layout_height= "wrap_content" android:textcolor= "@android: Colo R/holo_blue_light "/> <view android:layout_width=" match_parent "android:layout_height=" 1px " Android:background= "@android: color/Darker_gray "/></linearlayout>
The model, table, and Dao that relate to the Android.
User.java:
Package Zhangphil.demo;import Android.arch.persistence.room.columninfo;import Android.arch.persistence.room.entity;import android.arch.persistence.room.primarykey;/** * Created by Phil on 2017/11 /22. */@Entity (tableName = "user_table") public class User { @PrimaryKey (autoGenerate = true) public int userId; @ColumnInfo (name = "UserName") public String name; @ColumnInfo (name = "Userage") public int: age =-1; @ColumnInfo (name = "UpdateTime") public long updatetime =-1;}
Userdao.java:
Package Zhangphil.demo;import Android.arch.persistence.room.dao;import Android.arch.persistence.room.Delete; Import Android.arch.persistence.room.insert;import Android.arch.persistence.room.onconflictstrategy;import Android.arch.persistence.room.query;import Android.arch.persistence.room.update;import java.util.List;/** * Created by Phil on 2017/11/22. */@Daopublic interface Userdao {@Query ("select * from User_table") public list<user> getAllUsers (); @Query ("select * from user_table WHERE userId >:uid ORDER by userid ASC limit:limit") Public list<user> Getus Erwhereuseridbigthan (int uid, int limit); @Query ("select * from user_table WHERE userId =:uid") public list<user> getuserwhereuseridequal (int uid); @Query ("select * from user_table WHERE userid Between:minid and:maxid ORDER by userid ASC") Public list<user> Getuseridbetween (int minid, int maxid); @Insert (onconflict = onconflictstrategy.replace) public void Insertuser (User... Users); @Update public void UpdateUser (User ... users); @Delete public void DeleteUser (User ... users);
Userdatabase.java:
Package Zhangphil.demo;import Android.arch.persistence.room.database;import android.arch.persistence.room.roomdatabase;/** * Created by Phil on 2017/11/22. */@Database (entities = {User.class}, Version = 1, Exportschema = false) public abstract class Userdatabase Extends Roomdatabase {public abstract Userdao Getuserdao ();}
Code run result, initialize:
When you click "Add Data" to add the database data, after clicking the "Update" button:
Summary:
(a) In this example, when using the Android chamber to obtain paging data, the SQL query constraint limit is increased compared to the previous Userdao, as shown in Appendix 3 for more information about limit. When data is fetched from SQL, the data is divided into chunks, not the whole data in the database table as before. This improves performance.
(b) The Asynclistutil requires deferred active refresh () before it can be initialized with no scrolling recyclerview when the data is loaded. In this example, in Mainactivity OnCreate Finally, a thread is opened, which deliberately delays a certain amount of time before the Asynclistutil refresh () is started. This is partly due to the fact that UI drawing and data updates are not synchronized between Asynclistutil and Recyclerview, causing the data to not be brushed after the first initialization is loaded. The obvious phenomenon is: if the database has data, the initial opening of the entire program, Recyclerview loaded each item is empty, but obviously there is data in the database, according to the truth should be initialized loaded, but not. Tracking code will find that this happens, to a large extent, that the Asynclistutil callback was initialized before Recyclerview, resulting in Ondatarefresh and Getitemrangeinto
The first and last recyclerview that are captured and used are visible in the item position-1.
Appendix:
1, "Android official ORM Database," The technical Solution: @Embedded inline Object (ii) "Link: http://blog.csdn.net/zhangphil/article/details/78621009
2, "Android official ORM Database," Technical solution introduction (i) Link: http://blog.csdn.net/zhangphil/article/details/78611632
3, "SQL database query limit data paging" link: http://blog.csdn.net/zhangphil/article/details/78653677
4, "Android-based official Asynclistutil optimization improved Recyclerview page loading mechanism (i)" Link: http://blog.csdn.net/zhangphil/article/details/78603499
5, "Android-based official Asynclistutil Optimization Classic ListView page loading mechanism (ii)" Link: http://blog.csdn.net/zhangphil/article/details/78645089
Android Chamber Federated Asynclistutil implements Recyclerview page load ORM Data