Swipeable list view enhancements

Summary:
- Removes "flickering" on first load
- Takes in Map<rowID, slideoutView> to display customs slideout view in `SwipeableRowListView`

Reviewed By: furdei

Differential Revision: D3267262

fb-gh-sync-id: a89806138b9172b3c184cc117504e205632a36d0
fbshipit-source-id: a89806138b9172b3c184cc117504e205632a36d0
This commit is contained in:
Fred Liu 2016-05-05 20:44:48 -07:00 committed by Facebook Github Bot 5
parent 156d3ed7a2
commit 2132ad1441
2 changed files with 28 additions and 6 deletions

View File

@ -41,6 +41,13 @@ const HORIZONTAL_SWIPE_DISTANCE_THRESHOLD = 15;
* on the item hidden behind the row * on the item hidden behind the row
*/ */
const SwipeableRow = React.createClass({ const SwipeableRow = React.createClass({
/**
* In order to render component A beneath component B, A must be rendered
* before B. However, this will cause "flickering", aka we see A briefly then
* B. To counter this, _isSwipeableViewRendered flag is used to set component
* A to be transparent until component B is loaded.
*/
_isSwipeableViewRendered: false,
_panResponder: {}, _panResponder: {},
_previousLeft: CLOSED_LEFT_POSITION, _previousLeft: CLOSED_LEFT_POSITION,
@ -112,6 +119,7 @@ const SwipeableRow = React.createClass({
<View style={[ <View style={[
styles.slideOutContainer, styles.slideOutContainer,
{ {
opacity: this._isSwipeableViewRendered ? 1 : 0,
right: -this.state.scrollViewWidth, right: -this.state.scrollViewWidth,
width: this.state.scrollViewWidth, width: this.state.scrollViewWidth,
}, },
@ -121,8 +129,9 @@ const SwipeableRow = React.createClass({
); );
// The swipable item // The swipable item
const mainView = ( const swipeableView = (
<Animated.View <Animated.View
onLayout={this._onSwipeableViewLayout}
style={{ style={{
left: this.state.currentLeft, left: this.state.currentLeft,
width: this.state.scrollViewWidth, width: this.state.scrollViewWidth,
@ -137,11 +146,17 @@ const SwipeableRow = React.createClass({
style={styles.container} style={styles.container}
onLayout={this._onLayoutChange}> onLayout={this._onLayoutChange}>
{slideOutView} {slideOutView}
{mainView} {swipeableView}
</View> </View>
); );
}, },
_onSwipeableViewLayout(event: Object): void {
if (!this._isSwipeableViewRendered) {
this._isSwipeableViewRendered = true;
}
},
_handlePanResponderTerminationRequest( _handlePanResponderTerminationRequest(
event: Object, event: Object,
gestureState: Object, gestureState: Object,

View File

@ -26,7 +26,6 @@
const ListViewDataSource = require('ListViewDataSource'); const ListViewDataSource = require('ListViewDataSource');
const React = require('React'); const React = require('React');
const SwipeableRow = require('SwipeableRow'); const SwipeableRow = require('SwipeableRow');
const View = require('View');
const {PropTypes} = React; const {PropTypes} = React;
@ -45,7 +44,10 @@ const SwipeableRowListView = React.createClass({
*/ */
listView: PropTypes.func.isRequired, listView: PropTypes.func.isRequired,
maxSwipeDistance: PropTypes.number, maxSwipeDistance: PropTypes.number,
renderRow: PropTypes.func.isRequired, // Callback method to render the view that will be unveiled on swipe
renderRowSlideout: PropTypes.func.isRequired,
// Callback method to render the swipeable view
renderRowSwipeable: PropTypes.func.isRequired,
rowIDs: PropTypes.array.isRequired, rowIDs: PropTypes.array.isRequired,
sectionIDs: PropTypes.array.isRequired, sectionIDs: PropTypes.array.isRequired,
}, },
@ -82,12 +84,17 @@ const SwipeableRowListView = React.createClass({
_renderRow(rowData: Object, sectionID: string, rowID: string): ReactElement { _renderRow(rowData: Object, sectionID: string, rowID: string): ReactElement {
return ( return (
<SwipeableRow <SwipeableRow
slideoutView={rowData.slideoutView || <View />} slideoutView={this.props.renderRowSlideout(rowData, sectionID, rowID)}
isOpen={rowData.isOpen} isOpen={rowData.isOpen}
maxSwipeDistance={this.props.maxSwipeDistance} maxSwipeDistance={this.props.maxSwipeDistance}
key={rowID} key={rowID}
onOpen={() => this._onRowOpen(rowID)}> onOpen={() => this._onRowOpen(rowID)}>
{this.props.renderRow(rowData, sectionID, rowID, this.state.dataSource)} {this.props.renderRowSwipeable(
rowData,
sectionID,
rowID,
this.state.dataSource,
)}
</SwipeableRow> </SwipeableRow>
); );
}, },