Add renderSeparator support to ListView
This commit is contained in:
parent
b839ab32be
commit
84783dbac4
|
@ -34,7 +34,10 @@ var MovieCell = React.createClass({
|
||||||
var criticsScore = this.props.movie.ratings.critics_score;
|
var criticsScore = this.props.movie.ratings.critics_score;
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<TouchableHighlight onPress={this.props.onSelect}>
|
<TouchableHighlight
|
||||||
|
onPress={this.props.onSelect}
|
||||||
|
onShowUnderlay={this.props.onHighlight}
|
||||||
|
onHideUnderlay={this.props.onUnhighlight}>
|
||||||
<View style={styles.row}>
|
<View style={styles.row}>
|
||||||
<Image
|
<Image
|
||||||
source={getImageSource(this.props.movie, 'det')}
|
source={getImageSource(this.props.movie, 'det')}
|
||||||
|
@ -54,7 +57,6 @@ var MovieCell = React.createClass({
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</TouchableHighlight>
|
</TouchableHighlight>
|
||||||
<View style={styles.cellBorder} />
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
140D9B661AC36C42004F25EE /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14312D241AC3654D00CDC950 /* libRCTLinking.a */; };
|
140D9B661AC36C42004F25EE /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14312D241AC3654D00CDC950 /* libRCTLinking.a */; };
|
||||||
14A2D4421AC3E43800CC738A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14A2D4411AC3E41A00CC738A /* libReact.a */; };
|
14A2D4421AC3E43800CC738A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14A2D4411AC3E41A00CC738A /* libReact.a */; };
|
||||||
58C5726B1AA6239E00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5725B1AA6236500CDF9C8 /* libRCTText.a */; };
|
58C5726B1AA6239E00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5725B1AA6236500CDF9C8 /* libRCTText.a */; };
|
||||||
|
67C95F201B0E64A30040BCE2 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67C95F1E1B0E647A0040BCE2 /* libRCTWebSocket.a */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -54,6 +55,13 @@
|
||||||
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||||
remoteInfo = RCTText;
|
remoteInfo = RCTText;
|
||||||
};
|
};
|
||||||
|
67C95F1D1B0E647A0040BCE2 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||||
|
remoteInfo = RCTWebSocket;
|
||||||
|
};
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
@ -69,6 +77,7 @@
|
||||||
14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
|
14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
|
||||||
14A2D43C1AC3E41A00CC738A /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
|
14A2D43C1AC3E41A00CC738A /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
|
||||||
587650F61A9EB120008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = SOURCE_ROOT; };
|
587650F61A9EB120008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = SOURCE_ROOT; };
|
||||||
|
67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -76,6 +85,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
67C95F201B0E64A30040BCE2 /* libRCTWebSocket.a in Frameworks */,
|
||||||
14A2D4421AC3E43800CC738A /* libReact.a in Frameworks */,
|
14A2D4421AC3E43800CC738A /* libReact.a in Frameworks */,
|
||||||
140D9B661AC36C42004F25EE /* libRCTLinking.a in Frameworks */,
|
140D9B661AC36C42004F25EE /* libRCTLinking.a in Frameworks */,
|
||||||
1341801E1AA91750003F314A /* libRCTNetwork.a in Frameworks */,
|
1341801E1AA91750003F314A /* libRCTNetwork.a in Frameworks */,
|
||||||
|
@ -135,6 +145,7 @@
|
||||||
58C571FC1AA6124500CDF9C8 /* Libraries */ = {
|
58C571FC1AA6124500CDF9C8 /* Libraries */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */,
|
||||||
14A2D43C1AC3E41A00CC738A /* React.xcodeproj */,
|
14A2D43C1AC3E41A00CC738A /* React.xcodeproj */,
|
||||||
14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */,
|
14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */,
|
||||||
134180151AA91740003F314A /* RCTNetwork.xcodeproj */,
|
134180151AA91740003F314A /* RCTNetwork.xcodeproj */,
|
||||||
|
@ -152,6 +163,14 @@
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
67C95F161B0E647A0040BCE2 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
67C95F1E1B0E647A0040BCE2 /* libRCTWebSocket.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
83CBB9F61A601CBA00E9B192 = {
|
83CBB9F61A601CBA00E9B192 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -228,6 +247,10 @@
|
||||||
ProductGroup = 58C572571AA6236500CDF9C8 /* Products */;
|
ProductGroup = 58C572571AA6236500CDF9C8 /* Products */;
|
||||||
ProjectRef = 587650F61A9EB120008B8F17 /* RCTText.xcodeproj */;
|
ProjectRef = 587650F61A9EB120008B8F17 /* RCTText.xcodeproj */;
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 67C95F161B0E647A0040BCE2 /* Products */;
|
||||||
|
ProjectRef = 67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */;
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ProductGroup = 14A2D43D1AC3E41A00CC738A /* Products */;
|
ProductGroup = 14A2D43D1AC3E41A00CC738A /* Products */;
|
||||||
ProjectRef = 14A2D43C1AC3E41A00CC738A /* React.xcodeproj */;
|
ProjectRef = 14A2D43C1AC3E41A00CC738A /* React.xcodeproj */;
|
||||||
|
@ -276,6 +299,13 @@
|
||||||
remoteRef = 58C5725A1AA6236500CDF9C8 /* PBXContainerItemProxy */;
|
remoteRef = 58C5725A1AA6236500CDF9C8 /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
|
67C95F1E1B0E647A0040BCE2 /* libRCTWebSocket.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libRCTWebSocket.a;
|
||||||
|
remoteRef = 67C95F1D1B0E647A0040BCE2 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
/* End PBXReferenceProxy section */
|
/* End PBXReferenceProxy section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
|
|
@ -237,10 +237,31 @@ var SearchScreen = React.createClass({
|
||||||
return <ActivityIndicatorIOS style={styles.scrollSpinner} />;
|
return <ActivityIndicatorIOS style={styles.scrollSpinner} />;
|
||||||
},
|
},
|
||||||
|
|
||||||
renderRow: function(movie: Object) {
|
renderSeparator: function(
|
||||||
|
sectionID: number | string,
|
||||||
|
rowID: number | string,
|
||||||
|
adjacentRowHighlighted: boolean
|
||||||
|
) {
|
||||||
|
var style = styles.rowSeparator;
|
||||||
|
if (adjacentRowHighlighted) {
|
||||||
|
style = [style, styles.rowSeparatorHide];
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<View key={"SEP_" + sectionID + "_" + rowID} style={style}/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderRow: function(
|
||||||
|
movie: Object,
|
||||||
|
sectionID: number | string,
|
||||||
|
rowID: number | string,
|
||||||
|
highlightRowFunc: (sectionID: ?number | string, rowID: ?number | string) => void,
|
||||||
|
) {
|
||||||
return (
|
return (
|
||||||
<MovieCell
|
<MovieCell
|
||||||
onSelect={() => this.selectMovie(movie)}
|
onSelect={() => this.selectMovie(movie)}
|
||||||
|
onHighlight={() => highlightRowFunc(sectionID, rowID)}
|
||||||
|
onUnhighlight={() => highlightRowFunc(null, null)}
|
||||||
movie={movie}
|
movie={movie}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -254,6 +275,7 @@ var SearchScreen = React.createClass({
|
||||||
/> :
|
/> :
|
||||||
<ListView
|
<ListView
|
||||||
ref="listview"
|
ref="listview"
|
||||||
|
renderSeparator={this.renderSeparator}
|
||||||
dataSource={this.state.dataSource}
|
dataSource={this.state.dataSource}
|
||||||
renderFooter={this.renderFooter}
|
renderFooter={this.renderFooter}
|
||||||
renderRow={this.renderRow}
|
renderRow={this.renderRow}
|
||||||
|
@ -352,6 +374,14 @@ var styles = StyleSheet.create({
|
||||||
scrollSpinner: {
|
scrollSpinner: {
|
||||||
marginVertical: 20,
|
marginVertical: 20,
|
||||||
},
|
},
|
||||||
|
rowSeparator: {
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
||||||
|
height: 1,
|
||||||
|
marginLeft: 4,
|
||||||
|
},
|
||||||
|
rowSeparatorHide: {
|
||||||
|
opacity: 0.0,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = SearchScreen;
|
module.exports = SearchScreen;
|
||||||
|
|
|
@ -70,6 +70,14 @@ var TouchableHighlight = React.createClass({
|
||||||
*/
|
*/
|
||||||
underlayColor: React.PropTypes.string,
|
underlayColor: React.PropTypes.string,
|
||||||
style: View.propTypes.style,
|
style: View.propTypes.style,
|
||||||
|
/**
|
||||||
|
* Called immediately after the underlay is shown
|
||||||
|
*/
|
||||||
|
onShowUnderlay: React.PropTypes.func,
|
||||||
|
/**
|
||||||
|
* Called immediately after the underlay is hidden
|
||||||
|
*/
|
||||||
|
onHideUnderlay: React.PropTypes.func,
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [NativeMethodsMixin, TimerMixin, Touchable.Mixin],
|
mixins: [NativeMethodsMixin, TimerMixin, Touchable.Mixin],
|
||||||
|
@ -159,6 +167,7 @@ var TouchableHighlight = React.createClass({
|
||||||
_showUnderlay: function() {
|
_showUnderlay: function() {
|
||||||
this.refs[UNDERLAY_REF].setNativeProps(this.state.activeUnderlayProps);
|
this.refs[UNDERLAY_REF].setNativeProps(this.state.activeUnderlayProps);
|
||||||
this.refs[CHILD_REF].setNativeProps(this.state.activeProps);
|
this.refs[CHILD_REF].setNativeProps(this.state.activeProps);
|
||||||
|
this.props.onShowUnderlay && this.props.onShowUnderlay();
|
||||||
},
|
},
|
||||||
|
|
||||||
_hideUnderlay: function() {
|
_hideUnderlay: function() {
|
||||||
|
@ -170,6 +179,7 @@ var TouchableHighlight = React.createClass({
|
||||||
...INACTIVE_UNDERLAY_PROPS,
|
...INACTIVE_UNDERLAY_PROPS,
|
||||||
style: this.state.underlayStyle,
|
style: this.state.underlayStyle,
|
||||||
});
|
});
|
||||||
|
this.props.onHideUnderlay && this.props.onHideUnderlay();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ var ListView = React.createClass({
|
||||||
* You must provide a renderRow function. If you omit any of the other render
|
* You must provide a renderRow function. If you omit any of the other render
|
||||||
* functions, ListView will simply skip rendering them.
|
* functions, ListView will simply skip rendering them.
|
||||||
*
|
*
|
||||||
* - renderRow(rowData, sectionID, rowID);
|
* - renderRow(rowData, sectionID, rowID, highlightRow);
|
||||||
* - renderSectionHeader(sectionData, sectionID);
|
* - renderSectionHeader(sectionData, sectionID);
|
||||||
*/
|
*/
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -116,11 +116,22 @@ var ListView = React.createClass({
|
||||||
|
|
||||||
dataSource: PropTypes.instanceOf(ListViewDataSource).isRequired,
|
dataSource: PropTypes.instanceOf(ListViewDataSource).isRequired,
|
||||||
/**
|
/**
|
||||||
* (rowData, sectionID, rowID) => renderable
|
* (sectionID, rowID, adjacentRowHighlighted) => renderable
|
||||||
|
* If provided, a renderable component to be rendered as the separator
|
||||||
|
* below each row but not the last row if there is a section header below.
|
||||||
|
* Take a sectionID and rowID of the row above and whether its adjacent row
|
||||||
|
* is highlighted.
|
||||||
|
*/
|
||||||
|
renderSeparator: PropTypes.func,
|
||||||
|
/**
|
||||||
|
* (rowData, sectionID, rowID, highlightRow) => renderable
|
||||||
* Takes a data entry from the data source and its ids and should return
|
* Takes a data entry from the data source and its ids and should return
|
||||||
* a renderable component to be rendered as the row. By default the data
|
* a renderable component to be rendered as the row. By default the data
|
||||||
* is exactly what was put into the data source, but it's also possible to
|
* is exactly what was put into the data source, but it's also possible to
|
||||||
* provide custom extractors.
|
* provide custom extractors. ListView can be notified when a row is
|
||||||
|
* being highlighted by calling highlightRow function. The separators above and
|
||||||
|
* below will be hidden when a row is highlighted. The highlighted state of
|
||||||
|
* a row can be reset by calling highlightRow(null).
|
||||||
*/
|
*/
|
||||||
renderRow: PropTypes.func.isRequired,
|
renderRow: PropTypes.func.isRequired,
|
||||||
/**
|
/**
|
||||||
|
@ -227,6 +238,7 @@ var ListView = React.createClass({
|
||||||
return {
|
return {
|
||||||
curRenderedRowsCount: this.props.initialListSize,
|
curRenderedRowsCount: this.props.initialListSize,
|
||||||
prevRenderedRowsCount: 0,
|
prevRenderedRowsCount: 0,
|
||||||
|
highlightedRow: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -256,6 +268,10 @@ var ListView = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onRowHighlighted: function(sectionID, rowID) {
|
||||||
|
this.setState({highlightedRow: {sectionID, rowID}});
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var bodyComponents = [];
|
var bodyComponents = [];
|
||||||
|
|
||||||
|
@ -305,11 +321,28 @@ var ListView = React.createClass({
|
||||||
null,
|
null,
|
||||||
dataSource.getRowData(sectionIdx, rowIdx),
|
dataSource.getRowData(sectionIdx, rowIdx),
|
||||||
sectionID,
|
sectionID,
|
||||||
rowID
|
rowID,
|
||||||
|
this.onRowHighlighted
|
||||||
)}
|
)}
|
||||||
/>;
|
/>;
|
||||||
bodyComponents.push(row);
|
bodyComponents.push(row);
|
||||||
totalIndex++;
|
totalIndex++;
|
||||||
|
|
||||||
|
if (this.props.renderSeparator &&
|
||||||
|
(rowIdx !== rowIDs.length - 1 || sectionIdx === allRowIDs.length -1)) {
|
||||||
|
var adjacentRowHighlighted =
|
||||||
|
this.state.highlightedRow.sectionID === sectionID && (
|
||||||
|
this.state.highlightedRow.rowID === rowID ||
|
||||||
|
this.state.highlightedRow.rowID === rowIDs[rowIdx + 1]
|
||||||
|
);
|
||||||
|
var separator = this.props.renderSeparator(
|
||||||
|
sectionID,
|
||||||
|
rowID,
|
||||||
|
adjacentRowHighlighted
|
||||||
|
);
|
||||||
|
bodyComponents.push(separator);
|
||||||
|
totalIndex++;
|
||||||
|
}
|
||||||
if (++rowCount === this.state.curRenderedRowsCount) {
|
if (++rowCount === this.state.curRenderedRowsCount) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue