API update and bug fixes
Reviewed By: bvaughn, yungsters Differential Revision: D4563798 fbshipit-source-id: 0591cef7c854b525d77e526af783284d9696cb48
This commit is contained in:
parent
5042bae259
commit
6283878e17
|
@ -35,7 +35,7 @@ const {
|
|||
View,
|
||||
} = ReactNative;
|
||||
|
||||
type Item = {title: string, text: string, key: number, pressed: boolean};
|
||||
type Item = {title: string, text: string, key: number, pressed: boolean, noImage?: ?boolean};
|
||||
|
||||
function genItemData(count: number): Array<Item> {
|
||||
const dataBlob = [];
|
||||
|
@ -73,7 +73,7 @@ class ItemComponent extends React.PureComponent {
|
|||
style={horizontal ? styles.horizItem : styles.item}>
|
||||
<View style={[
|
||||
styles.row, horizontal && {width: HORIZ_WIDTH}]}>
|
||||
<Image style={styles.thumb} source={imgSource} />
|
||||
{!item.noImage && <Image style={styles.thumb} source={imgSource} />}
|
||||
<Text
|
||||
style={styles.text}
|
||||
numberOfLines={(horizontal || fixedHeight) ? 3 : undefined}>
|
||||
|
@ -108,7 +108,7 @@ class FooterComponent extends React.PureComponent {
|
|||
<View>
|
||||
<SeparatorComponent />
|
||||
<View style={styles.headerFooter}>
|
||||
<Text>FOOTER</Text>
|
||||
<Text>LIST FOOTER</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
@ -120,7 +120,7 @@ class HeaderComponent extends React.PureComponent {
|
|||
return (
|
||||
<View>
|
||||
<View style={styles.headerFooter}>
|
||||
<Text>HEADER</Text>
|
||||
<Text>LIST HEADER</Text>
|
||||
</View>
|
||||
<SeparatorComponent />
|
||||
</View>
|
||||
|
@ -164,7 +164,7 @@ function hashCode(str: string): number {
|
|||
return hash;
|
||||
}
|
||||
|
||||
const HEADER = {height: 30, width: 80};
|
||||
const HEADER = {height: 30, width: 100};
|
||||
const SEPARATOR_HEIGHT = StyleSheet.hairlineWidth;
|
||||
|
||||
function getItemLayout(data: any, index: number, horizontal?: boolean) {
|
||||
|
|
|
@ -36,6 +36,7 @@ const UIExplorerPage = require('./UIExplorerPage');
|
|||
const infoLog = require('infoLog');
|
||||
|
||||
const {
|
||||
HeaderComponent,
|
||||
FooterComponent,
|
||||
ItemComponent,
|
||||
PlainInput,
|
||||
|
@ -53,10 +54,10 @@ const SectionHeaderComponent = ({section}) => (
|
|||
</View>
|
||||
);
|
||||
|
||||
const SectionSeparatorComponent = () => (
|
||||
const CustomSeparatorComponent = ({text}) => (
|
||||
<View>
|
||||
<SeparatorComponent />
|
||||
<Text style={styles.sectionSeparatorText}>SECTION SEPARATOR</Text>
|
||||
<Text style={styles.separatorText}>{text}</Text>
|
||||
<SeparatorComponent />
|
||||
</View>
|
||||
);
|
||||
|
@ -94,20 +95,25 @@ class SectionListExample extends React.PureComponent {
|
|||
</View>
|
||||
<SeparatorComponent />
|
||||
<SectionList
|
||||
FooterComponent={FooterComponent}
|
||||
ListHeaderComponent={HeaderComponent}
|
||||
ListFooterComponent={FooterComponent}
|
||||
ItemComponent={this._renderItemComponent}
|
||||
SectionHeaderComponent={SectionHeaderComponent}
|
||||
SectionSeparatorComponent={SectionSeparatorComponent}
|
||||
SeparatorComponent={SeparatorComponent}
|
||||
SectionSeparatorComponent={() => <CustomSeparatorComponent text="SECTION SEPARATOR" />}
|
||||
ItemSeparatorComponent={() => <CustomSeparatorComponent text="ITEM SEPARATOR" />}
|
||||
enableVirtualization={this.state.virtualized}
|
||||
onRefresh={() => alert('onRefresh: nothing to refresh :P')}
|
||||
onViewableItemsChanged={this._onViewableItemsChanged}
|
||||
refreshing={false}
|
||||
sections={[
|
||||
{ItemComponent: StackedItemComponent, key: 's1', data: [
|
||||
{title: 'Item In Header Section', text: 's1', key: '0'}
|
||||
{title: 'Item In Header Section', text: 'Section s1', key: '0'},
|
||||
]},
|
||||
{key: 's2', data: filteredData},
|
||||
{key: 's2', data: [
|
||||
{noImage: true, title: 'First item', text: 'Section s2', key: '0'},
|
||||
{noImage: true, title: 'Second item', text: 'Section s2', key: '1'},
|
||||
]},
|
||||
{key: 'Filtered Items', data: filteredData},
|
||||
]}
|
||||
viewablePercentThreshold={100}
|
||||
/>
|
||||
|
@ -143,11 +149,11 @@ const styles = StyleSheet.create({
|
|||
searchRow: {
|
||||
paddingHorizontal: 10,
|
||||
},
|
||||
sectionSeparatorText: {
|
||||
separatorText: {
|
||||
color: 'gray',
|
||||
alignSelf: 'center',
|
||||
padding: 4,
|
||||
fontWeight: 'bold',
|
||||
fontSize: 9,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -66,27 +66,30 @@ type RequiredProps<SectionT: SectionBase<*>> = {
|
|||
};
|
||||
|
||||
type OptionalProps<SectionT: SectionBase<*>> = {
|
||||
/**
|
||||
* Rendered after the last item in the last section.
|
||||
*/
|
||||
FooterComponent?: ?ReactClass<*>,
|
||||
/**
|
||||
* Default renderer for every item in every section.
|
||||
*/
|
||||
ItemComponent: ReactClass<{item: Item, index: number}>,
|
||||
/**
|
||||
* Rendered at the top of each section. In the future, a sticky option will be added.
|
||||
* Rendered in between adjacent Items within each section.
|
||||
*/
|
||||
ItemSeparatorComponent?: ?ReactClass<*>,
|
||||
/**
|
||||
* Rendered at the very beginning of the list.
|
||||
*/
|
||||
ListHeaderComponent?: ?ReactClass<*>,
|
||||
/**
|
||||
* Rendered at the very end of the list.
|
||||
*/
|
||||
ListFooterComponent?: ?ReactClass<*>,
|
||||
/**
|
||||
* Rendered at the top of each section. Sticky headers are not yet supported.
|
||||
*/
|
||||
SectionHeaderComponent?: ?ReactClass<{section: SectionT}>,
|
||||
/**
|
||||
* Rendered at the bottom of every Section, except the very last one, in place of the normal
|
||||
* SeparatorComponent.
|
||||
* Rendered in between each section.
|
||||
*/
|
||||
SectionSeparatorComponent?: ?ReactClass<*>,
|
||||
/**
|
||||
* Rendered at the bottom of every Item except the very last one in the last section.
|
||||
*/
|
||||
SeparatorComponent?: ?ReactClass<*>,
|
||||
/**
|
||||
* Warning: Virtualization can drastically improve memory consumption for long lists, but trashes
|
||||
* the state of items when they scroll out of the render window, so make sure all relavent data is
|
||||
|
@ -143,11 +146,16 @@ class SectionList<SectionT: SectionBase<*>>
|
|||
static defaultProps: DefaultProps = VirtualizedSectionList.defaultProps;
|
||||
|
||||
render() {
|
||||
if (this.props.legacyImplementation) {
|
||||
return <MetroListView {...this.props} items={this.props.sections} />;
|
||||
} else {
|
||||
return <VirtualizedSectionList {...this.props} />;
|
||||
}
|
||||
const {ListFooterComponent, ListHeaderComponent, ItemSeparatorComponent} = this.props;
|
||||
const List = this.props.legacyImplementation ? MetroListView : VirtualizedSectionList;
|
||||
return (
|
||||
<List
|
||||
{...this.props}
|
||||
FooterComponent={ListFooterComponent}
|
||||
HeaderComponent={ListHeaderComponent}
|
||||
SeparatorComponent={ItemSeparatorComponent}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -163,14 +163,18 @@ class VirtualizedSectionList<SectionT: SectionBase>
|
|||
const defaultKeyExtractor = this.props.keyExtractor;
|
||||
for (let ii = 0; ii < this.props.sections.length; ii++) {
|
||||
const section = this.props.sections[ii];
|
||||
const keyExtractor = section.keyExtractor || defaultKeyExtractor;
|
||||
const key = keyExtractor(section, ii);
|
||||
const key = section.key;
|
||||
warning(
|
||||
key != null,
|
||||
'VirtualizedSectionList: A `section` you supplied is missing the `key` property.'
|
||||
);
|
||||
itemIndex -= 1; // The section itself is an item
|
||||
if (itemIndex >= section.data.length) {
|
||||
itemIndex -= section.data.length;
|
||||
} else if (itemIndex === -1) {
|
||||
return {section, key, index: null};
|
||||
} else {
|
||||
const keyExtractor = section.keyExtractor || defaultKeyExtractor;
|
||||
return {
|
||||
section,
|
||||
key: key + ':' + keyExtractor(section.data[itemIndex], itemIndex),
|
||||
|
@ -216,7 +220,8 @@ class VirtualizedSectionList<SectionT: SectionBase>
|
|||
if (!info) {
|
||||
return null;
|
||||
} else if (info.index == null) {
|
||||
return <this.props.SectionHeaderComponent section={info.section} />;
|
||||
const {SectionHeaderComponent} = this.props;
|
||||
return SectionHeaderComponent ? <SectionHeaderComponent section={info.section} /> : null;
|
||||
} else {
|
||||
const ItemComponent = info.section.ItemComponent || this.props.ItemComponent;
|
||||
const SeparatorComponent = this._getSeparatorComponent(index, info);
|
||||
|
@ -236,13 +241,12 @@ class VirtualizedSectionList<SectionT: SectionBase>
|
|||
}
|
||||
const SeparatorComponent = info.section.SeparatorComponent || this.props.SeparatorComponent;
|
||||
const {SectionSeparatorComponent} = this.props;
|
||||
const lastItemIndex = this.state.childProps.getItemCount() - 1;
|
||||
if (SectionSeparatorComponent &&
|
||||
info.index === info.section.data.length - 1 &&
|
||||
index < lastItemIndex) {
|
||||
const isLastItemInList = index === this.state.childProps.getItemCount() - 1;
|
||||
const isLastItemInSection = info.index === info.section.data.length - 1;
|
||||
if (SectionSeparatorComponent && isLastItemInSection && !isLastItemInList) {
|
||||
return SectionSeparatorComponent;
|
||||
}
|
||||
if (SeparatorComponent && index < lastItemIndex) {
|
||||
if (SeparatorComponent && !isLastItemInSection && !isLastItemInList) {
|
||||
return SeparatorComponent;
|
||||
}
|
||||
return null;
|
||||
|
|
Loading…
Reference in New Issue