@@ -24,6 +24,7 @@ export default class SortableList extends Component {
2424 refreshControl : PropTypes . element ,
2525
2626 renderRow : PropTypes . func . isRequired ,
27+ renderFooter : PropTypes . func ,
2728
2829 onChangeOrder : PropTypes . func ,
2930 onActivateRow : PropTypes . func ,
@@ -47,6 +48,8 @@ export default class SortableList extends Component {
4748 */
4849 _rowsLayouts = [ ] ;
4950
51+ _footerLayout = null ;
52+
5053 _contentOffset = { x : 0 , y : 0 } ;
5154
5255 state = {
@@ -63,7 +66,7 @@ export default class SortableList extends Component {
6366 } ;
6467
6568 componentDidMount ( ) {
66- this . _onLayoutRows ( ) ;
69+ this . _onUpdateLayouts ( ) ;
6770 }
6871
6972 componentWillReceiveProps ( nextProps ) {
@@ -91,7 +94,7 @@ export default class SortableList extends Component {
9194 const { data : prevData } = prevState ;
9295
9396 if ( data && prevData && ! shallowEqual ( data , prevData ) ) {
94- this . _onLayoutRows ( ) ;
97+ this . _onUpdateLayouts ( ) ;
9598 }
9699 }
97100
@@ -178,6 +181,7 @@ export default class SortableList extends Component {
178181 < View style = { innerContainerStyle } >
179182 { this . _renderRows ( ) }
180183 </ View >
184+ { this . _renderFooter ( ) }
181185 </ ScrollView >
182186 </ View >
183187 ) ;
@@ -252,9 +256,28 @@ export default class SortableList extends Component {
252256 } ) ;
253257 }
254258
255- _onLayoutRows ( ) {
256- Promise . all ( [ ...this . _rowsLayouts ] )
257- . then ( ( rowsLayouts ) => {
259+ _renderFooter ( ) {
260+ if ( ! this . props . renderFooter || this . props . horizontal ) {
261+ return null ;
262+ }
263+
264+ const { footerLayout} = this . state ;
265+ let resolveLayout ;
266+
267+ if ( ! footerLayout ) {
268+ this . _footerLayout = new Promise ( ( resolve ) => ( resolveLayout = resolve ) ) ;
269+ }
270+
271+ return (
272+ < View onLayout = { ! footerLayout ? this . _onLayoutFooter . bind ( this , resolveLayout ) : null } >
273+ { this . props . renderFooter ( ) }
274+ </ View >
275+ ) ;
276+ }
277+
278+ _onUpdateLayouts ( ) {
279+ Promise . all ( [ this . _footerLayout , ...this . _rowsLayouts ] )
280+ . then ( ( [ footerLayout , ...rowsLayouts ] ) => {
258281 // Can get correct container’s layout only after rows’s layouts.
259282 this . _container . measure ( ( x , y , width , height , pageX , pageY ) => {
260283 const rowsLayoutsByKey = { } ;
@@ -270,6 +293,7 @@ export default class SortableList extends Component {
270293 this . setState ( {
271294 containerLayout : { x, y, width, height, pageX, pageY} ,
272295 rowsLayouts : rowsLayoutsByKey ,
296+ footerLayout,
273297 contentHeight,
274298 contentWidth,
275299 } , ( ) => {
@@ -421,25 +445,37 @@ export default class SortableList extends Component {
421445 this . _startAutoScroll ( {
422446 direction : 1 ,
423447 shouldScroll : ( ) => {
424- const { contentHeight, contentWidth, containerLayout} = this . state ;
448+ const {
449+ contentHeight,
450+ contentWidth,
451+ containerLayout,
452+ footerLayout = { height : 0 } ,
453+ } = this . state ;
425454
426455 if ( horizontal ) {
427456 return this . _contentOffset . x < contentWidth - containerLayout . width
428457 } else {
429- return this . _contentOffset . y < contentHeight - containerLayout . height ;
458+ return this . _contentOffset . y < contentHeight + footerLayout . height - containerLayout . height ;
430459 }
431460 } ,
432461 getScrollStep : ( stepIndex ) => {
433462 const nextStep = this . _getScrollStep ( stepIndex ) ;
434- const { contentHeight, contentWidth, containerLayout} = this . state ;
463+ const {
464+ contentHeight,
465+ contentWidth,
466+ containerLayout,
467+ footerLayout = { height : 0 } ,
468+ } = this . state ;
435469
436470 if ( horizontal ) {
437471 return this . _contentOffset . x + nextStep > contentWidth - containerLayout . width
438472 ? contentWidth - containerLayout . width - this . _contentOffset . x
439473 : nextStep ;
440474 } else {
441- return this . _contentOffset . y + nextStep > contentHeight - containerLayout . height
442- ? contentHeight - containerLayout . height - this . _contentOffset . y
475+ const scrollHeight = contentHeight + footerLayout . height - containerLayout . height ;
476+
477+ return this . _contentOffset . y + nextStep > scrollHeight
478+ ? scrollHeight - this . _contentOffset . y
443479 : nextStep ;
444480 }
445481 } ,
@@ -483,6 +519,10 @@ export default class SortableList extends Component {
483519 resolveLayout ( { rowKey, layout} ) ;
484520 }
485521
522+ _onLayoutFooter ( resolveLayout , { nativeEvent : { layout} } ) {
523+ resolveLayout ( layout ) ;
524+ }
525+
486526 _onActivateRow = ( rowKey , index , e , gestureState , location ) => {
487527 this . _activeRowLocation = location ;
488528
0 commit comments