debug overlay
Reviewed By: yungsters Differential Revision: D4534822 fbshipit-source-id: ceef5bc5c0dc8cdc0d3927e198273b4411045bde
This commit is contained in:
parent
12b228c5d9
commit
0a86c1cb15
|
@ -52,6 +52,7 @@ class FlatListExample extends React.PureComponent {
|
|||
|
||||
state = {
|
||||
data: genItemData(1000),
|
||||
debug: false,
|
||||
horizontal: false,
|
||||
filterText: '',
|
||||
fixedHeight: true,
|
||||
|
@ -90,6 +91,7 @@ class FlatListExample extends React.PureComponent {
|
|||
{renderSmallSwitchOption(this, 'horizontal')}
|
||||
{renderSmallSwitchOption(this, 'fixedHeight')}
|
||||
{renderSmallSwitchOption(this, 'logViewable')}
|
||||
{renderSmallSwitchOption(this, 'debug')}
|
||||
</View>
|
||||
</View>
|
||||
<FlatList
|
||||
|
@ -98,6 +100,7 @@ class FlatListExample extends React.PureComponent {
|
|||
ItemComponent={this._renderItemComponent}
|
||||
SeparatorComponent={SeparatorComponent}
|
||||
data={filteredData}
|
||||
debug={this.state.debug}
|
||||
disableVirtualization={!this.state.virtualized}
|
||||
getItemLayout={this.state.fixedHeight ? this._getItemLayout : undefined}
|
||||
horizontal={this.state.horizontal}
|
||||
|
@ -105,9 +108,9 @@ class FlatListExample extends React.PureComponent {
|
|||
legacyImplementation={false}
|
||||
numColumns={1}
|
||||
onRefresh={() => alert('onRefresh: nothing to refresh :P')}
|
||||
refreshing={false}
|
||||
onViewableItemsChanged={this._onViewableItemsChanged}
|
||||
ref={this._captureRef}
|
||||
refreshing={false}
|
||||
shouldItemUpdate={this._shouldItemUpdate}
|
||||
/>
|
||||
</UIExplorerPage>
|
||||
|
|
|
@ -74,6 +74,11 @@ type OptionalProps = {
|
|||
FooterComponent?: ?ReactClass<*>,
|
||||
HeaderComponent?: ?ReactClass<*>,
|
||||
SeparatorComponent?: ?ReactClass<*>,
|
||||
/**
|
||||
* `debug` will turn on extra logging and visual overlays to aid with debugging both usage and
|
||||
* implementation.
|
||||
*/
|
||||
debug?: ?boolean,
|
||||
/**
|
||||
* DEPRECATED: Virtualization provides significant performance and memory optimizations, but fully
|
||||
* unmounts react instances that are outside of the render window. You should only need to disable
|
||||
|
@ -272,6 +277,7 @@ class VirtualizedList extends React.PureComponent {
|
|||
item={item}
|
||||
key={key}
|
||||
onLayout={this._onCellLayout}
|
||||
onUnmount={this._onCellUnmount}
|
||||
parentProps={this.props}
|
||||
/>
|
||||
);
|
||||
|
@ -345,7 +351,11 @@ class VirtualizedList extends React.PureComponent {
|
|||
},
|
||||
cells,
|
||||
);
|
||||
return ret;
|
||||
if (this.props.debug) {
|
||||
return <View style={{flex: 1}}>{ret}{this._renderDebugOverlay()}</View>;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
|
@ -375,7 +385,7 @@ class VirtualizedList extends React.PureComponent {
|
|||
|
||||
_onCellLayout = (e, cellKey, index) => {
|
||||
const layout = e.nativeEvent.layout;
|
||||
const next = {offset: this._selectOffset(layout), length: this._selectLength(layout), index};
|
||||
const next = {offset: this._selectOffset(layout), length: this._selectLength(layout), index, inLayout: true};
|
||||
const curr = this._frames[cellKey];
|
||||
if (!curr ||
|
||||
next.offset !== curr.offset ||
|
||||
|
@ -391,6 +401,13 @@ class VirtualizedList extends React.PureComponent {
|
|||
}
|
||||
};
|
||||
|
||||
_onCellUnmount = (cellKey: string) => {
|
||||
const curr = this._frames[cellKey];
|
||||
if (curr) {
|
||||
this._frames[cellKey] = {...curr, inLayout: false};
|
||||
}
|
||||
};
|
||||
|
||||
_onLayout = (e: Object) => {
|
||||
this._scrollMetrics.visibleLength = this._selectLength(e.nativeEvent.layout);
|
||||
this.props.onLayout && this.props.onLayout(e);
|
||||
|
@ -405,6 +422,53 @@ class VirtualizedList extends React.PureComponent {
|
|||
this._headerLength = this._selectLength(e.nativeEvent.layout);
|
||||
};
|
||||
|
||||
_renderDebugOverlay() {
|
||||
const normalize = this._scrollMetrics.visibleLength / this._scrollMetrics.contentLength;
|
||||
const framesInLayout = [];
|
||||
const itemCount = this.props.getItemCount(this.props.data);
|
||||
for (let ii = 0; ii < itemCount; ii++) {
|
||||
const frame = this._getFrameMetricsApprox(ii);
|
||||
if (frame.inLayout) {
|
||||
framesInLayout.push(frame);
|
||||
}
|
||||
}
|
||||
const windowTop = this._getFrameMetricsApprox(this.state.first).offset;
|
||||
const frameLast = this._getFrameMetricsApprox(this.state.last);
|
||||
const windowLen = frameLast.offset + frameLast.length - windowTop;
|
||||
const visTop = this._scrollMetrics.offset;
|
||||
const visLen = this._scrollMetrics.visibleLength;
|
||||
const baseStyle = {position: 'absolute', top: 0, right: 0};
|
||||
return (
|
||||
<View style={{...baseStyle, bottom: 0, width: 20, borderColor: 'blue', borderWidth: 1}}>
|
||||
{framesInLayout.map((f, ii) =>
|
||||
<View key={'f' + ii} style={{
|
||||
...baseStyle,
|
||||
left: 0,
|
||||
top: f.offset * normalize,
|
||||
height: f.length * normalize,
|
||||
backgroundColor: 'orange',
|
||||
}} />
|
||||
)}
|
||||
<View style={{
|
||||
...baseStyle,
|
||||
left: 0,
|
||||
top: windowTop * normalize,
|
||||
height: windowLen * normalize,
|
||||
borderColor: 'green',
|
||||
borderWidth: 2,
|
||||
}} />
|
||||
<View style={{
|
||||
...baseStyle,
|
||||
left: 0,
|
||||
top: visTop * normalize,
|
||||
height: visLen * normalize,
|
||||
borderColor: 'red',
|
||||
borderWidth: 2,
|
||||
}} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_selectLength(metrics: {height: number, width: number}): number {
|
||||
return !this.props.horizontal ? metrics.height : metrics.width;
|
||||
}
|
||||
|
@ -572,6 +636,7 @@ class CellRenderer extends React.Component {
|
|||
index: number,
|
||||
item: Item,
|
||||
onLayout: (event: Object, cellKey: string, index: number) => void,
|
||||
onUnmount: (cellKey: string) => void,
|
||||
parentProps: {
|
||||
ItemComponent: ItemComponentType,
|
||||
getItemLayout?: ?Function,
|
||||
|
@ -584,6 +649,9 @@ class CellRenderer extends React.Component {
|
|||
_onLayout = (e) => {
|
||||
this.props.onLayout(e, this.props.cellKey, this.props.index);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
this.props.onUnmount(this.props.cellKey);
|
||||
}
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const curr = {item: this.props.item, index: this.props.index};
|
||||
const next = {item: nextProps.item, index: nextProps.index};
|
||||
|
@ -593,7 +661,7 @@ class CellRenderer extends React.Component {
|
|||
const {item, index, parentProps} = this.props;
|
||||
const {ItemComponent, getItemLayout} = parentProps;
|
||||
const element = <ItemComponent item={item} index={index} />;
|
||||
if (getItemLayout) {
|
||||
if (getItemLayout && !parentProps.debug) {
|
||||
return element;
|
||||
}
|
||||
return (
|
||||
|
|
Loading…
Reference in New Issue