Reactnative provides a Refreshcontrol drop-down refresh component, but does not provide a pull-up refresh component, and pull-up refreshes are very common in the app.
Today we are going to implement an iOS and Android Universal pull-up refresh feature.
The following is a brief introduction of my idea of implementation.
If your basic knowledge of the ListView is not very clear, it is recommended to move first: "React-native series" 16, RN components of the ListView
Ideas:
1, constant definition:
Const MORETEXT = "Loaded complete"; Foot display copy//page number var pagenum = 1;//Number of bars per page const PAGESIZE = 10;//Page total data var pagecount = 0;//Page List total data var totallist = new ARR Ay (); Foot: 0 hidden 1 loaded complete 2 display in load
2. Define the ListView
<listview enableemptysections={true} datasource={this.state.datasource} renderrow={this._ Renderrow.bind (This)} Renderfooter={this._renderfooter.bind (This)} Onendreached={this._endreached.bind (this)} Onendreachedthreshold={0}/>
3. Declaring State machine variables
Listview.datasource instances (List-dependent data sources)
Constructor (props) { super (props); This.state = { datasource:new listview.datasource ({ rowhaschanged: (r1, r2) = R1!== R2, }), loaded:false,//control whether request requests are loaded foot:0,//control foot, 0: Hide foot 1: Loaded complete 2: Display loading in error:false,}
Here we mainly declare datasource, this is nothing to say
Loaded: A daisy used to control the entire page
Error: If request error, an error page is displayed
Foot: Controlling the view of footer
4. Before rendering the page, load the data
Componentwillmount () { this._fetchlistdata (); }
5. Load Server Data
_fetchlistdata () {if (Pagenum > 1) {this.setstate ({loaded:true}); } fetch (Requesturl, {method: ' Get ', Headers:headerobj,}). Then (response =>{if (re Sponse.ok) {return Response.json (); } else {this.setstate ({error:true,loaded:true}); }}). Then (<span style= "font-family:arial, Helvetica, Sans-serif;" >json</span>=>{Let responsecode = Json.code; if (Responsecode = = 0) {Let responsedata = Json.data; <span style= "font-family:arial, Helvetica, Sans-serif;" >pagecount</span><span style= "font-family:arial, Helvetica, Sans-serif;" > = responsedata.count;</span> Let list = Responsedata.data; if (orderlist = = null) {orderlist = []; Currentcount = 0; } else {currentcount = list.length; } if (CurreNtcount < PageSize) {//When the currently returned data is less than pageSize, it is considered loaded this.setstate ({Foot:1,moretext:morete XT}); }else{//set foot Hide footer This.setstate ({foot:0}); } for (var i=0; i < list.length; i++) {Totallist.push (list[i]); } this.setstate ({dataSource:this.state.dataSource.cloneWithRows (totallist), Loaded:true,}); }else{this.setstate ({error:true,loaded:true}); }}). catch (function (error) {this.setstate ({error:true,loaded:true}); }); }
There's a lot of detail here:
1, when pagenum > 1 , do not have the entire page of Chrysanthemum, at this time loaded has been true, this is mainly for the page effect, otherwise did not load a page of data, this screen will flash a bit.
2. Compare the size of the list that is currently returned, whether it is less than pagesize, control whether the footer is hidden, or display has been loaded
3, the Declaration of a global totallist object, each time there is new data, push in.
If you don't use push, the second page will overwrite the first page of data by using the SetState method directly.
6. Define the Renderrow methodRenderrow={this._renderrow.bind (This)} List component render function, where page logic is omitted.
7. Define the Renderfooter method
Renderfooter footers are re-rendered during each rendering process.
_renderfooter () { if (this.state.foot = = = 1) {//Load complete return ( <view style={{height:40,alignitems: ' Center ', justifycontent: ' Flex-start ',}}> <text style={{color: ' #999999 ',fontsize:12,margintop:10}}> {this.state.moreText} </Text> </View>); } else if (this.state.foot = = = 2) {//Load in return ( <view style={{height:40,alignitems: ' Center ', Justifycontent: ' Center ',}}> <image source={{uri:loadgif}} style={{width:20,height:20}}/> < /view>); } }
Control the display of footer according to the state machine variable foot
8. onendreached definition
ONENDREACHEDTHRESHOLD={0}
Called when all the data has been rendered and the list is scrolled to a distance of less than onendreachedthreshold pixels from the bottom. Native scrolling events are passed as parameters. When the first rendering, if the data is not one screen (such as the initial value is empty), this event will also be triggered
_endreached () { if (this.state.foot! = 0) { return; } This.setstate ({ foot:2, }); This.timer = SetTimeout ( () = { pagenum + +; This._fetchlistdata (); },500); }
Here are a few things to look at
1, the first screen may also trigger the _endreached method, so you need to determine that foot is not 0 (that is, loading and loading completed), the direct return
2, pull, trigger the _endreached method, the server interface may respond quickly, almost do not see chrysanthemum effect, specially added a 500 milliseconds waiting
9. Uninstall Timer
Componentwillunmount () { //If This.timer is present, use cleartimeout to clear. //If you use more than one timer, use multiple variables, or save the reference with a number of groups, then clear this.timer && cleartimeout (this.timer) individually; }
Points to optimize:
1, if the ListView page more words, the global variable totallist will be very large, memory is the test.
If you have any questions, you can contact us by message.
"React-native Series" 19, the ListView component Pull Refresh (iOS and Android Universal)