mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0adb1b35e8 | ||
|
|
0756c663bc | ||
|
|
9d6087ffc3 | ||
|
|
8b4d2376f5 | ||
|
|
3cdb567908 | ||
|
|
39eddc1a56 | ||
|
|
c72a44874b |
@@ -77,7 +77,9 @@ class FlatListExample extends React.PureComponent {
|
||||
}
|
||||
render() {
|
||||
const filterRegex = new RegExp(String(this.state.filterText), 'i');
|
||||
const filter = (item) => (filterRegex.test(item.text) || filterRegex.test(item.title));
|
||||
const filter = (item) => (
|
||||
filterRegex.test(item.text) || filterRegex.test(item.title)
|
||||
);
|
||||
const filteredData = this.state.data.filter(filter);
|
||||
return (
|
||||
<UIExplorerPage
|
||||
@@ -112,9 +114,14 @@ class FlatListExample extends React.PureComponent {
|
||||
data={filteredData}
|
||||
debug={this.state.debug}
|
||||
disableVirtualization={!this.state.virtualized}
|
||||
getItemLayout={this.state.fixedHeight ? this._getItemLayout : undefined}
|
||||
getItemLayout={this.state.fixedHeight ?
|
||||
this._getItemLayout :
|
||||
undefined
|
||||
}
|
||||
horizontal={this.state.horizontal}
|
||||
key={(this.state.horizontal ? 'h' : 'v') + (this.state.fixedHeight ? 'f' : 'd')}
|
||||
key={(this.state.horizontal ? 'h' : 'v') +
|
||||
(this.state.fixedHeight ? 'f' : 'd')
|
||||
}
|
||||
legacyImplementation={false}
|
||||
numColumns={1}
|
||||
onRefresh={this._onRefresh}
|
||||
@@ -145,22 +152,31 @@ class FlatListExample extends React.PureComponent {
|
||||
};
|
||||
_shouldItemUpdate(prev, next) {
|
||||
/**
|
||||
* Note that this does not check state.horizontal or state.fixedheight because we blow away the
|
||||
* whole list by changing the key in those cases. Make sure that you do the same in your code,
|
||||
* or incorporate all relevant data into the item data, or skip this optimization entirely.
|
||||
* Note that this does not check state.horizontal or state.fixedheight
|
||||
* because we blow away the whole list by changing the key in those cases.
|
||||
* Make sure that you do the same in your code, or incorporate all relevant
|
||||
* data into the item data, or skip this optimization entirely.
|
||||
*/
|
||||
return prev.item !== next.item;
|
||||
}
|
||||
// This is called when items change viewability by scrolling into or out of the viewable area.
|
||||
// This is called when items change viewability by scrolling into or out of
|
||||
// the viewable area.
|
||||
_onViewableItemsChanged = (info: {
|
||||
changed: Array<{
|
||||
key: string, isViewable: boolean, item: any, index: ?number, section?: any
|
||||
key: string,
|
||||
isViewable: boolean,
|
||||
item: any,
|
||||
index: ?number,
|
||||
section?: any,
|
||||
}>
|
||||
}
|
||||
) => {
|
||||
// Impressions can be logged here
|
||||
if (this.state.logViewable) {
|
||||
infoLog('onViewableItemsChanged: ', info.changed.map((v) => ({...v, item: '...'})));
|
||||
infoLog(
|
||||
'onViewableItemsChanged: ',
|
||||
info.changed.map((v) => ({...v, item: '...'})),
|
||||
);
|
||||
}
|
||||
};
|
||||
_pressItem = (key: number) => {
|
||||
|
||||
-486
@@ -1,486 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
|
||||
/**
|
||||
* Basic example that shows how to use <NavigationCardStack /> to build
|
||||
* an app with composite navigation system.
|
||||
* @providesModule NavigationCardStack-NavigationHeader-Tabs-example
|
||||
*/
|
||||
|
||||
const {
|
||||
Component,
|
||||
PropTypes,
|
||||
} = React;
|
||||
|
||||
const {
|
||||
NavigationExperimental,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
const {
|
||||
CardStack: NavigationCardStack,
|
||||
Header: NavigationHeader,
|
||||
PropTypes: NavigationPropTypes,
|
||||
StateUtils: NavigationStateUtils,
|
||||
} = NavigationExperimental;
|
||||
|
||||
// First Step.
|
||||
// Define what app navigation state will look like.
|
||||
function createAppNavigationState(): Object {
|
||||
return {
|
||||
// Three tabs.
|
||||
tabs: {
|
||||
index: 0,
|
||||
routes: [
|
||||
{key: 'apple'},
|
||||
{key: 'banana'},
|
||||
{key: 'orange'},
|
||||
],
|
||||
},
|
||||
// Scenes for the `apple` tab.
|
||||
apple: {
|
||||
index: 0,
|
||||
routes: [{key: 'Apple Home'}],
|
||||
},
|
||||
// Scenes for the `banana` tab.
|
||||
banana: {
|
||||
index: 0,
|
||||
routes: [{key: 'Banana Home'}],
|
||||
},
|
||||
// Scenes for the `orange` tab.
|
||||
orange: {
|
||||
index: 0,
|
||||
routes: [{key: 'Orange Home'}],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Next step.
|
||||
// Define what app navigation state shall be updated.
|
||||
function updateAppNavigationState(
|
||||
state: Object,
|
||||
action: Object,
|
||||
): Object {
|
||||
let {type} = action;
|
||||
if (type === 'BackAction') {
|
||||
type = 'pop';
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'push': {
|
||||
// Push a route into the scenes stack.
|
||||
const route: Object = action.route;
|
||||
const {tabs} = state;
|
||||
const tabKey = tabs.routes[tabs.index].key;
|
||||
const scenes = state[tabKey];
|
||||
const nextScenes = NavigationStateUtils.push(scenes, route);
|
||||
if (scenes !== nextScenes) {
|
||||
return {
|
||||
...state,
|
||||
[tabKey]: nextScenes,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'pop': {
|
||||
// Pops a route from the scenes stack.
|
||||
const {tabs} = state;
|
||||
const tabKey = tabs.routes[tabs.index].key;
|
||||
const scenes = state[tabKey];
|
||||
const nextScenes = NavigationStateUtils.pop(scenes);
|
||||
if (scenes !== nextScenes) {
|
||||
return {
|
||||
...state,
|
||||
[tabKey]: nextScenes,
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'selectTab': {
|
||||
// Switches the tab.
|
||||
const tabKey: string = action.tabKey;
|
||||
const tabs = NavigationStateUtils.jumpTo(state.tabs, tabKey);
|
||||
if (tabs !== state.tabs) {
|
||||
return {
|
||||
...state,
|
||||
tabs,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
// Next step.
|
||||
// Defines a helper function that creates a HOC (higher-order-component)
|
||||
// which provides a function `navigate` through component props. The
|
||||
// `navigate` function will be used to invoke navigation changes.
|
||||
// This serves a convenient way for a component to navigate.
|
||||
function createAppNavigationContainer(ComponentClass) {
|
||||
const key = '_yourAppNavigationContainerNavigateCall';
|
||||
|
||||
class Container extends Component {
|
||||
static contextTypes = {
|
||||
[key]: PropTypes.func,
|
||||
};
|
||||
|
||||
static childContextTypes = {
|
||||
[key]: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
navigate: PropTypes.func,
|
||||
};
|
||||
|
||||
getChildContext(): Object {
|
||||
return {
|
||||
[key]: this.context[key] || this.props.navigate,
|
||||
};
|
||||
}
|
||||
|
||||
render(): React.Element {
|
||||
const navigate = this.context[key] || this.props.navigate;
|
||||
return <ComponentClass {...this.props} navigate={navigate} />;
|
||||
}
|
||||
}
|
||||
|
||||
return Container;
|
||||
}
|
||||
|
||||
// Next step.
|
||||
// Define a component for your application that owns the navigation state.
|
||||
class YourApplication extends Component {
|
||||
|
||||
static propTypes = {
|
||||
onExampleExit: PropTypes.func,
|
||||
};
|
||||
|
||||
// This sets up the initial navigation state.
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
// This sets up the initial navigation state.
|
||||
this.state = createAppNavigationState();
|
||||
this._navigate = this._navigate.bind(this);
|
||||
}
|
||||
|
||||
render(): React.Element {
|
||||
// User your own navigator (see next step).
|
||||
return (
|
||||
<YourNavigator
|
||||
appNavigationState={this.state}
|
||||
navigate={this._navigate}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// This public method is optional. If exists, the UI explorer will call it
|
||||
// the "back button" is pressed. Normally this is the cases for Android only.
|
||||
handleBackAction(): boolean {
|
||||
return this._navigate({type: 'pop'});
|
||||
}
|
||||
|
||||
// This handles the navigation state changes. You're free and responsible
|
||||
// to define the API that changes that navigation state. In this exmaple,
|
||||
// we'd simply use a `updateAppNavigationState` to update the navigation
|
||||
// state.
|
||||
_navigate(action: Object): void {
|
||||
if (action.type === 'exit') {
|
||||
// Exits the example. `this.props.onExampleExit` is provided
|
||||
// by the UI Explorer.
|
||||
this.props.onExampleExit && this.props.onExampleExit();
|
||||
return;
|
||||
}
|
||||
|
||||
const state = updateAppNavigationState(
|
||||
this.state,
|
||||
action,
|
||||
);
|
||||
|
||||
// `updateAppNavigationState` (which uses NavigationStateUtils) gives you
|
||||
// back the same `state` if nothing has changed. You could use
|
||||
// that to avoid redundant re-rendering.
|
||||
if (this.state !== state) {
|
||||
this.setState(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Next step.
|
||||
// Define your own controlled navigator.
|
||||
const YourNavigator = createAppNavigationContainer(class extends Component {
|
||||
static propTypes = {
|
||||
appNavigationState: PropTypes.shape({
|
||||
apple: NavigationPropTypes.navigationState.isRequired,
|
||||
banana: NavigationPropTypes.navigationState.isRequired,
|
||||
orange: NavigationPropTypes.navigationState.isRequired,
|
||||
tabs: NavigationPropTypes.navigationState.isRequired,
|
||||
}),
|
||||
navigate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
// This sets up the methods (e.g. Pop, Push) for navigation.
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
this._back = this._back.bind(this);
|
||||
this._renderHeader = this._renderHeader.bind(this);
|
||||
this._renderScene = this._renderScene.bind(this);
|
||||
}
|
||||
|
||||
// Now use the `NavigationCardStack` to render the scenes.
|
||||
render(): React.Element {
|
||||
const {appNavigationState} = this.props;
|
||||
const {tabs} = appNavigationState;
|
||||
const tabKey = tabs.routes[tabs.index].key;
|
||||
const scenes = appNavigationState[tabKey];
|
||||
|
||||
return (
|
||||
<View style={styles.navigator}>
|
||||
<NavigationCardStack
|
||||
key={'stack_' + tabKey}
|
||||
onNavigateBack={this._back}
|
||||
navigationState={scenes}
|
||||
renderHeader={this._renderHeader}
|
||||
renderScene={this._renderScene}
|
||||
style={styles.navigatorCardStack}
|
||||
/>
|
||||
<YourTabs
|
||||
navigationState={tabs}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
// Render the header.
|
||||
// The detailed spec of `sceneProps` is defined at `NavigationTypeDefinition`
|
||||
// as type `NavigationSceneRendererProps`.
|
||||
_renderHeader(sceneProps: Object): React.Element {
|
||||
return (
|
||||
<YourHeader
|
||||
{...sceneProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Render a scene for route.
|
||||
// The detailed spec of `sceneProps` is defined at `NavigationTypeDefinition`
|
||||
// as type `NavigationSceneRendererProps`.
|
||||
_renderScene(sceneProps: Object): React.Element {
|
||||
return (
|
||||
<YourScene
|
||||
{...sceneProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_back() {
|
||||
this.props.navigate({type: 'pop'});
|
||||
}
|
||||
});
|
||||
|
||||
// Next step.
|
||||
// Define your own header.
|
||||
const YourHeader = createAppNavigationContainer(class extends Component {
|
||||
static propTypes = {
|
||||
...NavigationPropTypes.SceneRendererProps,
|
||||
navigate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
constructor(props: Object, context: any) {
|
||||
super(props, context);
|
||||
this._back = this._back.bind(this);
|
||||
this._renderTitleComponent = this._renderTitleComponent.bind(this);
|
||||
}
|
||||
|
||||
render(): React.Element {
|
||||
return (
|
||||
<NavigationHeader
|
||||
{...this.props}
|
||||
renderTitleComponent={this._renderTitleComponent}
|
||||
onNavigateBack={this._back}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_back(): void {
|
||||
this.props.navigate({type: 'pop'});
|
||||
}
|
||||
|
||||
_renderTitleComponent(props: Object): React.Element {
|
||||
return (
|
||||
<NavigationHeader.Title>
|
||||
{props.scene.route.key}
|
||||
</NavigationHeader.Title>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Next step.
|
||||
// Define your own scene.
|
||||
const YourScene = createAppNavigationContainer(class extends Component {
|
||||
static propTypes = {
|
||||
...NavigationPropTypes.SceneRendererProps,
|
||||
navigate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
constructor(props: Object, context: any) {
|
||||
super(props, context);
|
||||
this._exit = this._exit.bind(this);
|
||||
this._popRoute = this._popRoute.bind(this);
|
||||
this._pushRoute = this._pushRoute.bind(this);
|
||||
}
|
||||
|
||||
render(): React.Element {
|
||||
return (
|
||||
<ScrollView>
|
||||
<NavigationExampleRow
|
||||
text="Push Route"
|
||||
onPress={this._pushRoute}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Pop Route"
|
||||
onPress={this._popRoute}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Exit Header + Scenes + Tabs Example"
|
||||
onPress={this._exit}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
_pushRoute(): void {
|
||||
// Just push a route with a new unique key.
|
||||
const route = {key: '[' + this.props.scenes.length + ']-' + Date.now()};
|
||||
this.props.navigate({type: 'push', route});
|
||||
}
|
||||
|
||||
_popRoute(): void {
|
||||
this.props.navigate({type: 'pop'});
|
||||
}
|
||||
|
||||
_exit(): void {
|
||||
this.props.navigate({type: 'exit'});
|
||||
}
|
||||
});
|
||||
|
||||
// Next step.
|
||||
// Define your own tabs.
|
||||
const YourTabs = createAppNavigationContainer(class extends Component {
|
||||
static propTypes = {
|
||||
navigationState: NavigationPropTypes.navigationState.isRequired,
|
||||
navigate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
constructor(props: Object, context: any) {
|
||||
super(props, context);
|
||||
}
|
||||
|
||||
render(): React.Element {
|
||||
return (
|
||||
<View style={styles.tabs}>
|
||||
{this.props.navigationState.routes.map(this._renderTab, this)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_renderTab(route: Object, index: number): React.Element {
|
||||
return (
|
||||
<YourTab
|
||||
key={route.key}
|
||||
route={route}
|
||||
selected={this.props.navigationState.index === index}
|
||||
/>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Next step.
|
||||
// Define your own Tab
|
||||
const YourTab = createAppNavigationContainer(class extends Component {
|
||||
|
||||
static propTypes = {
|
||||
navigate: PropTypes.func.isRequired,
|
||||
route: NavigationPropTypes.navigationRoute.isRequired,
|
||||
selected: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
constructor(props: Object, context: any) {
|
||||
super(props, context);
|
||||
this._onPress = this._onPress.bind(this);
|
||||
}
|
||||
|
||||
render(): React.Element {
|
||||
const style = [styles.tabText];
|
||||
if (this.props.selected) {
|
||||
style.push(styles.tabSelected);
|
||||
}
|
||||
return (
|
||||
<TouchableOpacity style={styles.tab} onPress={this._onPress}>
|
||||
<Text style={style}>
|
||||
{this.props.route.key}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
_onPress() {
|
||||
this.props.navigate({type: 'selectTab', tabKey: this.props.route.key});
|
||||
}
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
navigator: {
|
||||
flex: 1,
|
||||
},
|
||||
navigatorCardStack: {
|
||||
flex: 20,
|
||||
},
|
||||
tabs: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
},
|
||||
tab: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#fff',
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
tabText: {
|
||||
color: '#222',
|
||||
fontWeight: '500',
|
||||
},
|
||||
tabSelected: {
|
||||
color: 'blue',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = YourApplication;
|
||||
-198
@@ -1,198 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule NavigationCardStack-NoGesture-example
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
|
||||
/**
|
||||
* Basic example that shows how to use <NavigationCardStack /> to build
|
||||
* an app with controlled navigation system but without gestures.
|
||||
*/
|
||||
const {
|
||||
NavigationExperimental,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
} = ReactNative;
|
||||
|
||||
const {
|
||||
CardStack: NavigationCardStack,
|
||||
StateUtils: NavigationStateUtils,
|
||||
} = NavigationExperimental;
|
||||
|
||||
// Step 1:
|
||||
// Define a component for your application.
|
||||
class YourApplication extends React.Component {
|
||||
|
||||
// This sets up the initial navigation state.
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
// This defines the initial navigation state.
|
||||
navigationState: {
|
||||
index: 0, // starts with first route focused.
|
||||
routes: [{key: 'Welcome'}], // starts with only one route.
|
||||
},
|
||||
};
|
||||
|
||||
this._exit = this._exit.bind(this);
|
||||
this._onNavigationChange = this._onNavigationChange.bind(this);
|
||||
}
|
||||
|
||||
// User your own navigator (see Step 2).
|
||||
render(): React.Element {
|
||||
return (
|
||||
<YourNavigator
|
||||
navigationState={this.state.navigationState}
|
||||
onNavigationChange={this._onNavigationChange}
|
||||
onExit={this._exit}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// This handles the navigation state changes. You're free and responsible
|
||||
// to define the API that changes that navigation state. In this exmaple,
|
||||
// we'd simply use a `function(type: string)` to update the navigation state.
|
||||
_onNavigationChange(type: string): void {
|
||||
let {navigationState} = this.state;
|
||||
switch (type) {
|
||||
case 'push':
|
||||
// push a new route.
|
||||
const route = {key: 'route-' + Date.now()};
|
||||
navigationState = NavigationStateUtils.push(navigationState, route);
|
||||
break;
|
||||
|
||||
case 'pop':
|
||||
navigationState = NavigationStateUtils.pop(navigationState);
|
||||
break;
|
||||
}
|
||||
|
||||
// NavigationStateUtils gives you back the same `navigationState` if nothing
|
||||
// has changed. You could use that to avoid redundant re-rendering.
|
||||
if (this.state.navigationState !== navigationState) {
|
||||
this.setState({navigationState});
|
||||
}
|
||||
}
|
||||
|
||||
// Exits the example. `this.props.onExampleExit` is provided
|
||||
// by the UI Explorer.
|
||||
_exit(): void {
|
||||
this.props.onExampleExit && this.props.onExampleExit();
|
||||
}
|
||||
|
||||
// This public method is optional. If exists, the UI explorer will call it
|
||||
// the "back button" is pressed. Normally this is the cases for Android only.
|
||||
handleBackAction(): boolean {
|
||||
return this._onNavigationChange('pop');
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2:
|
||||
// Define your own controlled navigator.
|
||||
//
|
||||
// +------------+
|
||||
// +-+ |
|
||||
// +-+ | |
|
||||
// | | | |
|
||||
// | | | Active |
|
||||
// | | | Scene |
|
||||
// | | | |
|
||||
// +-+ | |
|
||||
// +-+ |
|
||||
// +------------+
|
||||
//
|
||||
class YourNavigator extends React.Component {
|
||||
|
||||
// This sets up the methods (e.g. Pop, Push) for navigation.
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
|
||||
this._onPushRoute = this.props.onNavigationChange.bind(null, 'push');
|
||||
this._onPopRoute = this.props.onNavigationChange.bind(null, 'pop');
|
||||
|
||||
this._renderScene = this._renderScene.bind(this);
|
||||
}
|
||||
|
||||
// Now use the `NavigationCardStack` to render the scenes.
|
||||
render(): React.Element {
|
||||
return (
|
||||
<NavigationCardStack
|
||||
onNavigateBack={this._onPopRoute}
|
||||
navigationState={this.props.navigationState}
|
||||
renderScene={this._renderScene}
|
||||
style={styles.navigator}
|
||||
enableGestures={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Render a scene for route.
|
||||
// The detailed spec of `sceneProps` is defined at `NavigationTypeDefinition`
|
||||
// as type `NavigationSceneRendererProps`.
|
||||
_renderScene(sceneProps: Object): React.Element {
|
||||
return (
|
||||
<YourScene
|
||||
route={sceneProps.scene.route}
|
||||
onPushRoute={this._onPushRoute}
|
||||
onPopRoute={this._onPopRoute}
|
||||
onExit={this.props.onExit}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3:
|
||||
// Define your own scene.
|
||||
class YourScene extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ScrollView>
|
||||
<NavigationExampleRow
|
||||
text={'route = ' + this.props.route.key}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Push Route"
|
||||
onPress={this.props.onPushRoute}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Pop Route"
|
||||
onPress={this.props.onPopRoute}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Exit Card Stack Example"
|
||||
onPress={this.props.onExit}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
navigator: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = YourApplication;
|
||||
@@ -1,196 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* @providesModule NavigationCardStack-example
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
|
||||
/**
|
||||
* Basic example that shows how to use <NavigationCardStack /> to build
|
||||
* an app with controlled navigation system.
|
||||
*/
|
||||
const {
|
||||
NavigationExperimental,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
} = ReactNative;
|
||||
|
||||
const {
|
||||
CardStack: NavigationCardStack,
|
||||
StateUtils: NavigationStateUtils,
|
||||
} = NavigationExperimental;
|
||||
|
||||
// Step 1:
|
||||
// Define a component for your application.
|
||||
class YourApplication extends React.Component {
|
||||
|
||||
// This sets up the initial navigation state.
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
// This defines the initial navigation state.
|
||||
navigationState: {
|
||||
index: 0, // starts with first route focused.
|
||||
routes: [{key: 'Welcome'}], // starts with only one route.
|
||||
},
|
||||
};
|
||||
|
||||
this._exit = this._exit.bind(this);
|
||||
this._onNavigationChange = this._onNavigationChange.bind(this);
|
||||
}
|
||||
|
||||
// User your own navigator (see Step 2).
|
||||
render(): React.Element {
|
||||
return (
|
||||
<YourNavigator
|
||||
navigationState={this.state.navigationState}
|
||||
onNavigationChange={this._onNavigationChange}
|
||||
onExit={this._exit}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// This handles the navigation state changes. You're free and responsible
|
||||
// to define the API that changes that navigation state. In this exmaple,
|
||||
// we'd simply use a `function(type: string)` to update the navigation state.
|
||||
_onNavigationChange(type: string): void {
|
||||
let {navigationState} = this.state;
|
||||
switch (type) {
|
||||
case 'push':
|
||||
// push a new route.
|
||||
const route = {key: 'route-' + Date.now()};
|
||||
navigationState = NavigationStateUtils.push(navigationState, route);
|
||||
break;
|
||||
|
||||
case 'pop':
|
||||
navigationState = NavigationStateUtils.pop(navigationState);
|
||||
break;
|
||||
}
|
||||
|
||||
// NavigationStateUtils gives you back the same `navigationState` if nothing
|
||||
// has changed. You could use that to avoid redundant re-rendering.
|
||||
if (this.state.navigationState !== navigationState) {
|
||||
this.setState({navigationState});
|
||||
}
|
||||
}
|
||||
|
||||
// Exits the example. `this.props.onExampleExit` is provided
|
||||
// by the UI Explorer.
|
||||
_exit(): void {
|
||||
this.props.onExampleExit && this.props.onExampleExit();
|
||||
}
|
||||
|
||||
// This public method is optional. If exists, the UI explorer will call it
|
||||
// the "back button" is pressed. Normally this is the cases for Android only.
|
||||
handleBackAction(): boolean {
|
||||
return this._onNavigationChange('pop');
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2:
|
||||
// Define your own controlled navigator.
|
||||
//
|
||||
// +------------+
|
||||
// +-+ |
|
||||
// +-+ | |
|
||||
// | | | |
|
||||
// | | | Active |
|
||||
// | | | Scene |
|
||||
// | | | |
|
||||
// +-+ | |
|
||||
// +-+ |
|
||||
// +------------+
|
||||
//
|
||||
class YourNavigator extends React.Component {
|
||||
|
||||
// This sets up the methods (e.g. Pop, Push) for navigation.
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
|
||||
this._onPushRoute = this.props.onNavigationChange.bind(null, 'push');
|
||||
this._onPopRoute = this.props.onNavigationChange.bind(null, 'pop');
|
||||
|
||||
this._renderScene = this._renderScene.bind(this);
|
||||
}
|
||||
|
||||
// Now use the `NavigationCardStack` to render the scenes.
|
||||
render(): React.Element {
|
||||
return (
|
||||
<NavigationCardStack
|
||||
onNavigateBack={this._onPopRoute}
|
||||
navigationState={this.props.navigationState}
|
||||
renderScene={this._renderScene}
|
||||
style={styles.navigator}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Render a scene for route.
|
||||
// The detailed spec of `sceneProps` is defined at `NavigationTypeDefinition`
|
||||
// as type `NavigationSceneRendererProps`.
|
||||
_renderScene(sceneProps: Object): React.Element {
|
||||
return (
|
||||
<YourScene
|
||||
route={sceneProps.scene.route}
|
||||
onPushRoute={this._onPushRoute}
|
||||
onPopRoute={this._onPopRoute}
|
||||
onExit={this.props.onExit}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3:
|
||||
// Define your own scene.
|
||||
class YourScene extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ScrollView>
|
||||
<NavigationExampleRow
|
||||
text={'route = ' + this.props.route.key}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Push Route"
|
||||
onPress={this.props.onPushRoute}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Pop Route"
|
||||
onPress={this.props.onPopRoute}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Exit Card Stack Example"
|
||||
onPress={this.props.onExit}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
navigator: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = YourApplication;
|
||||
@@ -1,74 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* @providesModule NavigationExampleRow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactNative = require('react-native');
|
||||
var {
|
||||
Text,
|
||||
PixelRatio,
|
||||
StyleSheet,
|
||||
View,
|
||||
TouchableHighlight,
|
||||
} = ReactNative;
|
||||
|
||||
class NavigationExampleRow extends React.Component {
|
||||
render() {
|
||||
if (this.props.onPress) {
|
||||
return (
|
||||
<TouchableHighlight
|
||||
style={styles.row}
|
||||
underlayColor="#D0D0D0"
|
||||
onPress={this.props.onPress}>
|
||||
<Text style={styles.buttonText}>
|
||||
{this.props.text}
|
||||
</Text>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View style={styles.row}>
|
||||
<Text style={styles.rowText}>
|
||||
{this.props.text}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
row: {
|
||||
padding: 15,
|
||||
backgroundColor: 'white',
|
||||
borderBottomWidth: 1 / PixelRatio.get(),
|
||||
borderBottomColor: '#CDCDCD',
|
||||
},
|
||||
rowText: {
|
||||
fontSize: 17,
|
||||
},
|
||||
buttonText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '500',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationExampleRow;
|
||||
@@ -1,153 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* @providesModule NavigationExperimentalExample
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const AsyncStorage = require('AsyncStorage');
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const React = require('react');
|
||||
const ScrollView = require('ScrollView');
|
||||
const StyleSheet = require('StyleSheet');
|
||||
const View = require('View');
|
||||
|
||||
/*
|
||||
* Heads up! This file is not the real navigation example- only a utility to switch between them.
|
||||
*
|
||||
* To learn how to use the Navigation API, take a look at the following example files:
|
||||
*/
|
||||
const EXAMPLES = {
|
||||
'CardStack + Header + Tabs Example': require('./NavigationCardStack-NavigationHeader-Tabs-example'),
|
||||
'CardStack Example': require('./NavigationCardStack-example'),
|
||||
'CardStack Without Gestures Example': require('./NavigationCardStack-NoGesture-example'),
|
||||
'Transitioner + Animated View Example': require('./NavigationTransitioner-AnimatedView-example'),
|
||||
'Transitioner + Animated View Pager Example': require('./NavigationTransitioner-AnimatedView-pager-example'),
|
||||
};
|
||||
|
||||
const EXAMPLE_STORAGE_KEY = 'NavigationExperimentalExample';
|
||||
|
||||
class NavigationExperimentalExample extends React.Component {
|
||||
static title = 'Navigation (Experimental)';
|
||||
static description = 'Upcoming navigation APIs and animated navigation views';
|
||||
static external = true;
|
||||
|
||||
state = {
|
||||
example: null,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
AsyncStorage.getItem(EXAMPLE_STORAGE_KEY, (err, example) => {
|
||||
if (err || !example || !EXAMPLES[example]) {
|
||||
this.setState({
|
||||
example: 'menu',
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
example,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setExample = (example) => {
|
||||
this.setState({
|
||||
example,
|
||||
});
|
||||
AsyncStorage.setItem(EXAMPLE_STORAGE_KEY, example);
|
||||
};
|
||||
|
||||
_renderMenu = () => {
|
||||
let exitRow = null;
|
||||
if (this.props.onExampleExit) {
|
||||
exitRow = (
|
||||
<NavigationExampleRow
|
||||
text="Exit Navigation Examples"
|
||||
onPress={this.props.onExampleExit}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View style={styles.menu}>
|
||||
<ScrollView>
|
||||
{this._renderExampleList()}
|
||||
{exitRow}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
_renderExampleList = () => {
|
||||
return Object.keys(EXAMPLES).map(exampleName => (
|
||||
<NavigationExampleRow
|
||||
key={exampleName}
|
||||
text={exampleName}
|
||||
onPress={() => {
|
||||
this.setExample(exampleName);
|
||||
}}
|
||||
/>
|
||||
));
|
||||
};
|
||||
|
||||
_exitInnerExample = () => {
|
||||
this.setExample('menu');
|
||||
};
|
||||
|
||||
handleBackAction = () => {
|
||||
const wasHandledByExample = (
|
||||
this.exampleRef &&
|
||||
this.exampleRef.handleBackAction &&
|
||||
this.exampleRef.handleBackAction()
|
||||
);
|
||||
if (wasHandledByExample) {
|
||||
return true;
|
||||
}
|
||||
if (this.state.example && this.state.example !== 'menu') {
|
||||
this._exitInnerExample();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
render() {
|
||||
if (this.state.example === 'menu') {
|
||||
return this._renderMenu();
|
||||
}
|
||||
if (EXAMPLES[this.state.example]) {
|
||||
const Component = EXAMPLES[this.state.example];
|
||||
return (
|
||||
<Component
|
||||
onExampleExit={this._exitInnerExample}
|
||||
ref={exampleRef => { this.exampleRef = exampleRef; }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
menu: {
|
||||
backgroundColor: '#E9E9EF',
|
||||
flex: 1,
|
||||
marginTop: 20,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = NavigationExperimentalExample;
|
||||
-256
@@ -1,256 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
* @providesModule NavigationTransitioner-AnimatedView-example
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
|
||||
/**
|
||||
* Basic example that shows how to use <NavigationTransitioner /> and
|
||||
* <Animated.View /> to build a stack of animated scenes that render the
|
||||
* navigation state.
|
||||
*/
|
||||
|
||||
|
||||
import type {
|
||||
NavigationSceneRendererProps,
|
||||
NavigationState,
|
||||
NavigationTransitionProps,
|
||||
NavigationTransitionSpec,
|
||||
} from 'NavigationTypeDefinition';
|
||||
|
||||
const {
|
||||
Component,
|
||||
PropTypes,
|
||||
} = React;
|
||||
|
||||
const {
|
||||
Animated,
|
||||
Easing,
|
||||
NavigationExperimental,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
} = ReactNative;
|
||||
|
||||
const {
|
||||
PropTypes: NavigationPropTypes,
|
||||
StateUtils: NavigationStateUtils,
|
||||
Transitioner: NavigationTransitioner,
|
||||
} = NavigationExperimental;
|
||||
|
||||
function reducer(state: ?NavigationState, action: any): NavigationState {
|
||||
if (!state) {
|
||||
return {
|
||||
index: 0,
|
||||
routes: [{key: 'route-1'}],
|
||||
};
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case 'push':
|
||||
const route = {key: 'route-' + (state.routes.length + 1)};
|
||||
return NavigationStateUtils.push(state, route);
|
||||
case 'pop':
|
||||
return NavigationStateUtils.pop(state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
class Example extends Component {
|
||||
state: NavigationState;
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
this.state = reducer();
|
||||
}
|
||||
|
||||
render(): React.Element<any> {
|
||||
return (
|
||||
<ExampleNavigator
|
||||
navigationState={this.state}
|
||||
navigate={action => this._navigate(action)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_navigate(action: any): boolean {
|
||||
if (action === 'exit') {
|
||||
// Exits the example. `this.props.onExampleExit` is provided
|
||||
// by the UI Explorer.
|
||||
this.props.onExampleExit && this.props.onExampleExit();
|
||||
return false;
|
||||
}
|
||||
|
||||
const state = reducer(this.state, action);
|
||||
if (state === this.state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.setState(state);
|
||||
return true;
|
||||
}
|
||||
|
||||
// This public method is optional. If exists, the UI explorer will call it
|
||||
// the "back button" is pressed. Normally this is the cases for Android only.
|
||||
handleBackAction(): boolean {
|
||||
return this._navigate('pop');
|
||||
}
|
||||
}
|
||||
|
||||
class ExampleNavigator extends Component {
|
||||
props: {
|
||||
navigate: Function,
|
||||
navigationState: NavigationState,
|
||||
};
|
||||
|
||||
static propTypes: {
|
||||
navigationState: NavigationPropTypes.navigationState.isRequired,
|
||||
navigate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
render(): React.Element<any> {
|
||||
return (
|
||||
<NavigationTransitioner
|
||||
navigationState={this.props.navigationState}
|
||||
render={(transitionProps) => this._render(transitionProps)}
|
||||
configureTransition={this._configureTransition}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_render(
|
||||
transitionProps: NavigationTransitionProps,
|
||||
): Array<React.Element<any>> {
|
||||
return transitionProps.scenes.map((scene) => {
|
||||
const sceneProps = {
|
||||
...transitionProps,
|
||||
scene,
|
||||
};
|
||||
return this._renderScene(sceneProps);
|
||||
});
|
||||
}
|
||||
|
||||
_renderScene(
|
||||
sceneProps: NavigationSceneRendererProps,
|
||||
): React.Element<any> {
|
||||
return (
|
||||
<ExampleScene
|
||||
{...sceneProps}
|
||||
key={sceneProps.scene.key}
|
||||
navigate={this.props.navigate}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_configureTransition(): NavigationTransitionSpec {
|
||||
const easing: any = Easing.inOut(Easing.ease);
|
||||
return {
|
||||
duration: 500,
|
||||
easing,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class ExampleScene extends Component {
|
||||
props: NavigationSceneRendererProps & {
|
||||
navigate: Function,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
...NavigationPropTypes.SceneRendererProps,
|
||||
navigate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
render(): React.Element<any> {
|
||||
const {scene, navigate} = this.props;
|
||||
return (
|
||||
<Animated.View
|
||||
style={[styles.scene, this._getAnimatedStyle()]}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<NavigationExampleRow
|
||||
text={scene.route.key}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Push Route"
|
||||
onPress={() => navigate('push')}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Pop Route"
|
||||
onPress={() => navigate('pop')}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Exit NavigationTransitioner Example"
|
||||
onPress={() => navigate('exit')}
|
||||
/>
|
||||
</ScrollView>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
|
||||
_getAnimatedStyle(): Object {
|
||||
const {
|
||||
layout,
|
||||
position,
|
||||
scene,
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
index,
|
||||
} = scene;
|
||||
|
||||
const inputRange = [index - 1, index, index + 1];
|
||||
const width = layout.initWidth;
|
||||
const translateX = position.interpolate({
|
||||
inputRange,
|
||||
outputRange: ([width, 0, -10]: Array<number>),
|
||||
});
|
||||
|
||||
return {
|
||||
transform: [
|
||||
{ translateX },
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
scene: {
|
||||
backgroundColor: '#E9E9EF',
|
||||
bottom: 0,
|
||||
flex: 1,
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
shadowColor: 'black',
|
||||
shadowOffset: {width: 0, height: 0},
|
||||
shadowOpacity: 0.4,
|
||||
shadowRadius: 10,
|
||||
top: 0,
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = Example;
|
||||
-265
@@ -1,265 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
* @providesModule NavigationTransitioner-AnimatedView-pager-example
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const NavigationExampleRow = require('./NavigationExampleRow');
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
|
||||
/**
|
||||
* Basic example that shows how to use <NavigationTransitioner /> and
|
||||
* <Animated.View /> to build a list of animated scenes that render the
|
||||
* navigation state.
|
||||
*/
|
||||
|
||||
import type {
|
||||
NavigationSceneRendererProps,
|
||||
NavigationState,
|
||||
NavigationTransitionProps,
|
||||
} from 'NavigationTypeDefinition';
|
||||
|
||||
const {
|
||||
Component,
|
||||
PropTypes,
|
||||
} = React;
|
||||
|
||||
const {
|
||||
Animated,
|
||||
NavigationExperimental,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
const {
|
||||
PropTypes: NavigationPropTypes,
|
||||
StateUtils: NavigationStateUtils,
|
||||
Transitioner: NavigationTransitioner,
|
||||
Card: NavigationCard,
|
||||
} = NavigationExperimental;
|
||||
|
||||
const {
|
||||
PagerPanResponder: NavigationPagerPanResponder,
|
||||
PagerStyleInterpolator: NavigationPagerStyleInterpolator,
|
||||
} = NavigationCard;
|
||||
|
||||
function reducer(state: ?NavigationState, action: any): NavigationState {
|
||||
if (!state) {
|
||||
return {
|
||||
index: 0,
|
||||
routes: [
|
||||
{key: 'Step 1', color: '#ff0000'},
|
||||
{key: 'Step 2', color: '#ff7f00'},
|
||||
{key: 'Step 3', color: '#ffff00'},
|
||||
{key: 'Step 4', color: '#00ff00'},
|
||||
{key: 'Step 5', color: '#0000ff'},
|
||||
{key: 'Step 6', color: '#4b0082'},
|
||||
{key: 'Step 7', color: '#8f00ff'},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case 'back':
|
||||
return NavigationStateUtils.back(state);
|
||||
case 'forward':
|
||||
return NavigationStateUtils.forward(state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
class Example extends Component {
|
||||
state: NavigationState;
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
this.state = reducer();
|
||||
}
|
||||
|
||||
render(): React.Element<any> {
|
||||
return (
|
||||
<View style={styles.example}>
|
||||
<ExampleNavigator
|
||||
navigationState={this.state}
|
||||
navigate={action => this._navigate(action)}
|
||||
/>
|
||||
<NavigationExampleRow
|
||||
text="Exit"
|
||||
onPress={() => this._navigate('exit')}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_navigate(action: string): boolean {
|
||||
if (action === 'exit') {
|
||||
// Exits the example. `this.props.onExampleExit` is provided
|
||||
// by the UI Explorer.
|
||||
this.props.onExampleExit && this.props.onExampleExit();
|
||||
return false;
|
||||
}
|
||||
|
||||
const state = reducer(this.state, action);
|
||||
if (state === this.state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.setState(state);
|
||||
return true;
|
||||
}
|
||||
|
||||
// This public method is optional. If exists, the UI explorer will call it
|
||||
// the "back button" is pressed. Normally this is the cases for Android only.
|
||||
handleBackAction(): boolean {
|
||||
return this._navigate('back');
|
||||
}
|
||||
}
|
||||
|
||||
class ExampleNavigator extends Component {
|
||||
_render: Function;
|
||||
_renderScene: Function;
|
||||
|
||||
props: {
|
||||
navigate: Function,
|
||||
navigationState: NavigationState,
|
||||
};
|
||||
|
||||
static propTypes: {
|
||||
navigationState: NavigationPropTypes.navigationState.isRequired,
|
||||
navigate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
this._render = this._render.bind(this);
|
||||
this._renderScene = this._renderScene.bind(this);
|
||||
}
|
||||
|
||||
render(): React.Element<any> {
|
||||
return (
|
||||
<NavigationTransitioner
|
||||
navigationState={this.props.navigationState}
|
||||
render={this._render}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_render(
|
||||
transitionProps: NavigationTransitionProps,
|
||||
): React.Element<any> {
|
||||
const scenes = transitionProps.scenes.map((scene) => {
|
||||
const sceneProps = {
|
||||
...transitionProps,
|
||||
scene,
|
||||
};
|
||||
return this._renderScene(sceneProps);
|
||||
});
|
||||
return (
|
||||
<View style={styles.navigator}>
|
||||
{scenes}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
_renderScene(
|
||||
sceneProps: NavigationSceneRendererProps,
|
||||
): React.Element<any> {
|
||||
return (
|
||||
<ExampleScene
|
||||
{...sceneProps}
|
||||
key={sceneProps.scene.key + 'scene'}
|
||||
navigate={this.props.navigate}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ExampleScene extends Component {
|
||||
props: NavigationSceneRendererProps & {
|
||||
navigate: Function,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
...NavigationPropTypes.SceneRendererProps,
|
||||
navigate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
render(): React.Element<any> {
|
||||
const {scene, navigate} = this.props;
|
||||
|
||||
const panHandlers = NavigationPagerPanResponder.forHorizontal({
|
||||
...this.props,
|
||||
onNavigateBack: () => navigate('back'),
|
||||
onNavigateForward: () => navigate('forward'),
|
||||
});
|
||||
|
||||
const route: any = scene.route;
|
||||
const style = [
|
||||
styles.scene,
|
||||
{backgroundColor: route.color},
|
||||
NavigationPagerStyleInterpolator.forHorizontal(this.props),
|
||||
];
|
||||
|
||||
return (
|
||||
<Animated.View
|
||||
{...panHandlers}
|
||||
style={style}>
|
||||
<View style={styles.heading}>
|
||||
<Text style={styles.headingText}>
|
||||
{scene.route.key}
|
||||
</Text>
|
||||
</View>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
example: {
|
||||
flex: 1,
|
||||
},
|
||||
navigator: {
|
||||
flex: 1,
|
||||
},
|
||||
scene: {
|
||||
backgroundColor: '#000',
|
||||
bottom: 0,
|
||||
flex: 1,
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: 0,
|
||||
},
|
||||
heading: {
|
||||
alignItems : 'center',
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
headingText: {
|
||||
color: '#222',
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = Example;
|
||||
@@ -81,7 +81,9 @@ class SectionListExample extends React.PureComponent {
|
||||
};
|
||||
render() {
|
||||
const filterRegex = new RegExp(String(this.state.filterText), 'i');
|
||||
const filter = (item) => (filterRegex.test(item.text) || filterRegex.test(item.title));
|
||||
const filter = (item) => (
|
||||
filterRegex.test(item.text) || filterRegex.test(item.title)
|
||||
);
|
||||
const filteredData = this.state.data.filter(filter);
|
||||
return (
|
||||
<UIExplorerPage
|
||||
@@ -104,8 +106,12 @@ class SectionListExample extends React.PureComponent {
|
||||
<SectionList
|
||||
ListHeaderComponent={HeaderComponent}
|
||||
ListFooterComponent={FooterComponent}
|
||||
SectionSeparatorComponent={() => <CustomSeparatorComponent text="SECTION SEPARATOR" />}
|
||||
ItemSeparatorComponent={() => <CustomSeparatorComponent text="ITEM SEPARATOR" />}
|
||||
SectionSeparatorComponent={() =>
|
||||
<CustomSeparatorComponent text="SECTION SEPARATOR" />
|
||||
}
|
||||
ItemSeparatorComponent={() =>
|
||||
<CustomSeparatorComponent text="ITEM SEPARATOR" />
|
||||
}
|
||||
enableVirtualization={this.state.virtualized}
|
||||
onRefresh={() => alert('onRefresh: nothing to refresh :P')}
|
||||
onViewableItemsChanged={this._onViewableItemsChanged}
|
||||
@@ -117,8 +123,8 @@ class SectionListExample extends React.PureComponent {
|
||||
{title: 'Item In Header Section', text: 'Section s1', key: '0'},
|
||||
]},
|
||||
{key: 's2', data: [
|
||||
{noImage: true, title: 'First item', text: 'Section s2', key: '0'},
|
||||
{noImage: true, title: 'Second item', text: 'Section s2', key: '1'},
|
||||
{noImage: true, title: '1st item', text: 'Section s2', key: '0'},
|
||||
{noImage: true, title: '2nd item', text: 'Section s2', key: '1'},
|
||||
]},
|
||||
{key: 'Filtered Items', data: filteredData},
|
||||
]}
|
||||
@@ -127,11 +133,18 @@ class SectionListExample extends React.PureComponent {
|
||||
</UIExplorerPage>
|
||||
);
|
||||
}
|
||||
_renderItemComponent = ({item}) => <ItemComponent item={item} onPress={this._pressItem} />;
|
||||
// This is called when items change viewability by scrolling into our out of the viewable area.
|
||||
_renderItemComponent = ({item}) => (
|
||||
<ItemComponent item={item} onPress={this._pressItem} />
|
||||
);
|
||||
// This is called when items change viewability by scrolling into our out of
|
||||
// the viewable area.
|
||||
_onViewableItemsChanged = (info: {
|
||||
changed: Array<{
|
||||
key: string, isViewable: boolean, item: {columns: Array<*>}, index: ?number, section?: any
|
||||
key: string,
|
||||
isViewable: boolean,
|
||||
item: {columns: Array<*>},
|
||||
index: ?number,
|
||||
section?: any
|
||||
}>},
|
||||
) => {
|
||||
// Impressions can be logged here
|
||||
|
||||
@@ -192,10 +192,6 @@ const APIExamples: Array<UIExplorerExample> = [
|
||||
key: 'NativeAnimationsExample',
|
||||
module: require('./NativeAnimationsExample'),
|
||||
},
|
||||
{
|
||||
key: 'NavigationExperimentalExample',
|
||||
module: require('./NavigationExperimental/NavigationExperimentalExample'),
|
||||
},
|
||||
{
|
||||
key: 'NetInfoExample',
|
||||
module: require('./NetInfoExample'),
|
||||
|
||||
@@ -298,11 +298,6 @@ const APIExamples: Array<UIExplorerExample> = [
|
||||
module: require('./NativeAnimationsExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'NavigationExperimentalExample',
|
||||
module: require('./NavigationExperimental/NavigationExperimentalExample'),
|
||||
supportsTVOS: true,
|
||||
},
|
||||
{
|
||||
key: 'NetInfoExample',
|
||||
module: require('./NetInfoExample'),
|
||||
|
||||
@@ -46,19 +46,24 @@ const requireNativeComponent = require('requireNativeComponent');
|
||||
* view from becoming the responder.
|
||||
*
|
||||
*
|
||||
* `<ScrollView>` vs `<ListView>` - which one to use?
|
||||
* ScrollView simply renders all its react child components at once. That
|
||||
* makes it very easy to understand and use.
|
||||
* On the other hand, this has a performance downside. Imagine you have a very
|
||||
* long list of items you want to display, worth of couple of your ScrollView’s
|
||||
* heights. Creating JS components and native views upfront for all its items,
|
||||
* which may not even be shown, will contribute to slow rendering of your
|
||||
* screen and increased memory usage.
|
||||
* `<ScrollView>` vs [`<FlatList>`](/react-native/docs/flatlist.html) - which one to use?
|
||||
*
|
||||
* This is where ListView comes into play. ListView renders items lazily,
|
||||
* just when they are about to appear. This laziness comes at cost of a more
|
||||
* complicated API, which is worth it unless you are rendering a small fixed
|
||||
* set of items.
|
||||
* `ScrollView` simply renders all its react child components at once. That
|
||||
* makes it very easy to understand and use.
|
||||
*
|
||||
* On the other hand, this has a performance downside. Imagine you have a very
|
||||
* long list of items you want to display, maybe several screens worth of
|
||||
* content. Creating JS components and native views for everythign all at once,
|
||||
* much of which may not even be shown, will contribute to slow rendering and
|
||||
* increased memory usage.
|
||||
*
|
||||
* This is where `FlatList` comes into play. `FlatList` renders items lazily,
|
||||
* just when they are about to appear, and removes items that scroll way off
|
||||
* screen to save memory and processing time.
|
||||
*
|
||||
* `FlatList` is also handy if you want to render separators between your items,
|
||||
* multiple columns, infinite scroll loading, or any number of other features it
|
||||
* supports out of the box.
|
||||
*/
|
||||
const ScrollView = React.createClass({
|
||||
propTypes: {
|
||||
|
||||
@@ -49,19 +49,6 @@ import type {ViewabilityConfig, ViewToken} from 'ViewabilityHelper';
|
||||
type Item = any;
|
||||
type renderItemType = (info: {item: Item, index: number}) => ?React.Element<any>;
|
||||
|
||||
/**
|
||||
* Renders a virtual list of items given a data blob and accessor functions. Items that are outside
|
||||
* the render window (except for the initial items at the top) are 'virtualized' e.g. unmounted or
|
||||
* never rendered in the first place. This improves performance and saves memory for large data
|
||||
* sets, but will reset state on items that scroll too far out of the render window.
|
||||
*
|
||||
* TODO: Note that LayoutAnimation and sticky section headers both have bugs when used with this and
|
||||
* are therefor not supported, but new Animated impl might work?
|
||||
* https://github.com/facebook/react-native/pull/11315
|
||||
*
|
||||
* TODO: removeClippedSubviews might not be necessary and may cause bugs?
|
||||
*
|
||||
*/
|
||||
type RequiredProps = {
|
||||
renderItem: renderItemType,
|
||||
/**
|
||||
@@ -76,7 +63,7 @@ type OptionalProps = {
|
||||
SeparatorComponent?: ?ReactClass<any>,
|
||||
/**
|
||||
* `debug` will turn on extra logging and visual overlays to aid with debugging both usage and
|
||||
* implementation.
|
||||
* implementation, but with a significant perf hit.
|
||||
*/
|
||||
debug?: ?boolean,
|
||||
/**
|
||||
@@ -85,13 +72,28 @@ type OptionalProps = {
|
||||
* this for debugging purposes.
|
||||
*/
|
||||
disableVirtualization: boolean,
|
||||
getItem: (items: any, index: number) => ?Item,
|
||||
getItemCount: (items: any) => number,
|
||||
getItemLayout?: (items: any, index: number) =>
|
||||
/**
|
||||
* A generic accessor for extracting an item from any sort of data blob.
|
||||
*/
|
||||
getItem: (data: any, index: number) => ?Item,
|
||||
/**
|
||||
* Determines how many items are in the data blob.
|
||||
*/
|
||||
getItemCount: (data: any) => number,
|
||||
getItemLayout?: (data: any, index: number) =>
|
||||
{length: number, offset: number, index: number}, // e.g. height, y
|
||||
horizontal?: ?boolean,
|
||||
/**
|
||||
* How many items to render in the initial batch. This should be enough to fill the screen but not
|
||||
* much more.
|
||||
*/
|
||||
initialNumToRender: number,
|
||||
keyExtractor: (item: Item, index: number) => string,
|
||||
/**
|
||||
* The maximum number of items to render in each incremental render batch. The more rendered at
|
||||
* once, the better the fill rate, but responsiveness my suffer because rendering content may
|
||||
* interfere with responding to button taps or other interactions.
|
||||
*/
|
||||
maxToRenderPerBatch: number,
|
||||
onEndReached?: ?(info: {distanceFromEnd: number}) => void,
|
||||
onEndReachedThreshold?: ?number, // units of visible length
|
||||
@@ -110,15 +112,34 @@ type OptionalProps = {
|
||||
* Set this true while waiting for new data from a refresh.
|
||||
*/
|
||||
refreshing?: ?boolean,
|
||||
/**
|
||||
* A native optimization that removes clipped subviews (those outside the parent) from the view
|
||||
* hierarchy to offload work from the native rendering system. They are still kept around so no
|
||||
* memory is saved and state is preserved.
|
||||
*/
|
||||
removeClippedSubviews?: boolean,
|
||||
/**
|
||||
* Render a custom scroll component, e.g. with a differently styled `RefreshControl`.
|
||||
*/
|
||||
renderScrollComponent: (props: Object) => React.Element<any>,
|
||||
shouldItemUpdate: (
|
||||
props: {item: Item, index: number},
|
||||
nextProps: {item: Item, index: number}
|
||||
) => boolean,
|
||||
/**
|
||||
* Amount of time between low-pri item render batches, e.g. for rendering items quite a ways off
|
||||
* screen. Similar fill rate/responsiveness tradeoff as `maxToRenderPerBatch`.
|
||||
*/
|
||||
updateCellsBatchingPeriod: number,
|
||||
viewabilityConfig?: ViewabilityConfig,
|
||||
windowSize: number, // units of visible length
|
||||
/**
|
||||
* Determines the maximum number of items rendered outside of the visible area, in units of
|
||||
* visible lengths. So if your list fills the screen, then `windowSize={21}` (the default) will
|
||||
* render the visible screen area plus up to 10 screens above and 10 below the viewport. Reducing
|
||||
* this number will reduce memory consumption and may improve performance, but will increase the
|
||||
* chance that fast scrolling may reveal momentary blank areas of unrendered content.
|
||||
*/
|
||||
windowSize: number,
|
||||
};
|
||||
export type Props = RequiredProps & OptionalProps;
|
||||
|
||||
@@ -148,6 +169,12 @@ type State = {first: number, last: number};
|
||||
* and we are working on improving it behind the scenes.
|
||||
* - By default, the list looks for a `key` prop on each item and uses that for the React key.
|
||||
* Alternatively, you can provide a custom keyExtractor prop.
|
||||
*
|
||||
* NOTE: `LayoutAnimation` and sticky section headers both have bugs when used with this and are
|
||||
* therefore not officially supported yet.
|
||||
*
|
||||
* NOTE: `removeClippedSubviews` might not be necessary and may cause bugs. If you see issues with
|
||||
* content not rendering, try disabling it, and we may change the default there.
|
||||
*/
|
||||
class VirtualizedList extends React.PureComponent<OptionalProps, Props, State> {
|
||||
props: Props;
|
||||
|
||||
@@ -18,6 +18,18 @@ const NavigationPropTypes = require('NavigationPropTypes');
|
||||
const NavigationStateUtils = require('NavigationStateUtils');
|
||||
const NavigationTransitioner = require('NavigationTransitioner');
|
||||
|
||||
const warning = require('fbjs/lib/warning');
|
||||
|
||||
// This warning will only be reached if the user has required the module
|
||||
warning(
|
||||
false,
|
||||
'NavigationExperimental is deprecated and will be removed in a future ' +
|
||||
'version of React Native. The NavigationExperimental views live on in ' +
|
||||
'the React-Navigation project, which also makes it easy to declare ' +
|
||||
'navigation logic for your app. Learn more at https://reactnavigation.org/'
|
||||
);
|
||||
|
||||
|
||||
const NavigationExperimental = {
|
||||
// Core
|
||||
StateUtils: NavigationStateUtils,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION_NAME=1000.0.0-master
|
||||
VERSION_NAME=0.43.0-rc.1
|
||||
GROUP=com.facebook.react
|
||||
|
||||
POM_NAME=ReactNative
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native",
|
||||
"version": "1000.0.0",
|
||||
"version": "0.43.0-rc.1",
|
||||
"description": "A framework for building native apps using React",
|
||||
"license": "BSD-3-Clause",
|
||||
"repository": {
|
||||
@@ -228,4 +228,4 @@
|
||||
"shelljs": "0.6.0",
|
||||
"sinon": "^2.0.0-pre.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user