Add image example, make shadow and translate apply to different views, hide shadow on inactive screens

This commit is contained in:
Brent Vatne 2018-10-02 16:28:30 -07:00
parent f334c7645a
commit 50e54ebaf8
7 changed files with 140 additions and 21 deletions

View File

@ -6,6 +6,7 @@ import { createStackNavigator } from 'react-navigation-stack';
import { ListSection, Divider } from 'react-native-paper';
import SimpleStack from './src/SimpleStack';
import ImageStack from './src/ImageStack';
import TransparentStack from './src/TransparentStack';
import ModalStack from './src/ModalStack';
import GestureInteraction from './src/GestureInteraction';
@ -20,6 +21,7 @@ useScreens();
const data = [
{ component: SimpleStack, title: 'Simple', routeName: 'SimpleStack' },
{ component: ImageStack, title: 'Image', routeName: 'ImageStack' },
{ component: ModalStack, title: 'Modal', routeName: 'ModalStack' },
{
component: TransparentStack,
@ -29,11 +31,15 @@ const data = [
{ component: GestureInteraction, title: 'Gesture Interaction', routeName: 'GestureInteraction' },
];
Expo.Asset.loadAsync(require('react-navigation/src/views/assets/back-icon.png'));
Expo.Asset.loadAsync(require('react-navigation/src/views/assets/back-icon-mask.png'));
class Home extends React.Component {
static navigationOptions = {
title: 'Examples',
};
_renderItem = ({ item }) => (
<ListSection.Item
title={item.title}

89
example/src/ImageStack.js Normal file
View File

@ -0,0 +1,89 @@
import React from 'react';
import { Dimensions, Button, Image, View, Text } from 'react-native';
import { createStackNavigator } from 'react-navigation-stack';
import { FlatList, BorderlessButton } from 'react-native-gesture-handler';
class ListScreen extends React.Component {
static navigationOptions = ({ navigation }) => ({
title: 'Image list',
headerBackTitle: 'Back',
headerLeft: (
<Button title="Back" onPress={() => navigation.navigate('Home')} />
),
});
state = {
items: Array.apply(null, Array(60)).map((v, i) => {
return {
id: i,
src: `https://source.unsplash.com/random/400x${400 + i}`,
};
}),
};
render() {
return (
<FlatList
data={this.state.items}
renderItem={({ item }) => (
<View style={{ flex: 1, flexDirection: 'column', margin: 1 }}>
<BorderlessButton
onPress={() =>
this.props.navigation.navigate('Details', {
id: item.id,
src: item.src,
})
}
>
<Image style={{ height: 100 }} source={{ uri: item.src }} />
</BorderlessButton>
</View>
)}
numColumns={3}
keyExtractor={(item, index) => index}
style={{ flex: 1, backgroundColor: '#fff' }}
/>
);
}
}
class DetailsScreen extends React.Component {
static navigationOptions = {
title: 'Random image from Unsplash',
};
render() {
let id = this.props.navigation.getParam('id', 0);
return (
<View
style={{
flex: 1,
backgroundColor: '#fff',
}}
>
<Image
source={{
uri: `https://source.unsplash.com/random/1080x${1920 + id}`,
}}
style={{ width: Dimensions.get('window').width, height: 400 }}
resizeMode="cover"
/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
}
export default createStackNavigator(
{
List: ListScreen,
Details: DetailsScreen,
},
{
initialRouteName: 'List',
}
);

View File

@ -5,7 +5,14 @@ import { createStackNavigator } from 'react-navigation-stack';
class ListScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: Math.random() > 0.5 ? '#eee' : '#ccc',
}}
>
<Text>List Screen</Text>
<Text>A list may go here</Text>
<Button
@ -24,7 +31,14 @@ class ListScreen extends React.Component {
class DetailsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: Math.random() > 0.5 ? '#eee' : '#ccc',
}}
>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"

View File

@ -1,6 +1,6 @@
{
"name": "react-navigation-stack",
"version": "1.0.0-alpha.10",
"version": "1.0.0-alpha.11",
"description": "Stack navigator component for React Navigation",
"main": "dist/index.js",
"files": [

View File

@ -1,5 +1,5 @@
import React from 'react';
import { StyleSheet, Platform } from 'react-native';
import { Animated, StyleSheet, Platform } from 'react-native';
import { Screen } from 'react-native-screens';
import createPointerEventsContainer from './createPointerEventsContainer';
@ -25,6 +25,7 @@ function getAccessibilityProps(isActive) {
class Card extends React.Component {
render() {
const {
animatedStyle,
children,
pointerEvents,
style,
@ -42,27 +43,35 @@ class Card extends React.Component {
extrapolate: 'clamp',
});
const { shadowOpacity, ...containerAnimatedStyle } = animatedStyle;
return (
<Screen
pointerEvents={pointerEvents}
onComponentRef={this.props.onComponentRef}
style={[transparent ? styles.transparent : styles.main, style]}
style={[StyleSheet.absoluteFill, containerAnimatedStyle, style]}
active={active}
{...getAccessibilityProps(isActive)}
>
{children}
<Animated.View
{...getAccessibilityProps(isActive)}
style={[
transparent ? styles.transparent : styles.card,
{ shadowOpacity },
]}
>
{children}
</Animated.View>
</Screen>
);
}
}
const styles = StyleSheet.create({
main: {
...StyleSheet.absoluteFillObject,
backgroundColor: '#E9E9EF',
shadowColor: '#000',
shadowOffset: { width: -4, height: 0 },
shadowRadius: 6,
card: {
flex: 1,
backgroundColor: '#fff',
shadowOffset: { width: -3, height: 0 },
shadowRadius: 5,
},
transparent: {
...StyleSheet.absoluteFillObject,

View File

@ -223,7 +223,7 @@ class StackViewLayout extends React.Component {
if (Platform.OS === 'ios' && supportsImprovedSpringAnimation()) {
Animated.spring(position, {
toValue,
stiffness: 8000,
stiffness: 7000,
damping: 600,
mass: 3,
useNativeDriver: USE_NATIVE_DRIVER,
@ -735,7 +735,8 @@ class StackViewLayout extends React.Component {
realPosition={this.props.transitionProps.position}
key={`card_${scene.key}`}
transparent={this.props.transparentCard}
style={[style, { paddingTop }, this.props.cardStyle]}
animatedStyle={style}
style={[{ paddingTop }, this.props.cardStyle]}
scene={scene}
>
{this._renderInnerScene(scene)}

View File

@ -1,6 +1,8 @@
import { I18nManager } from 'react-native';
import getSceneIndicesForInterpolationInputRange from '../../utils/getSceneIndicesForInterpolationInputRange';
const EPS = 1e-5;
/**
* Utility that builds the style for the card in the cards stack.
*
@ -56,16 +58,15 @@ function forHorizontal(props) {
: [width, 0, width * -0.3],
extrapolate: 'clamp',
});
const translateY = 0;
const shadowOpacity = position.interpolate({
inputRange: [first, index, last],
outputRange: [0.01, 0.2, 0.01],
inputRange: [first - EPS, first, index, last, last + EPS],
outputRange: [0, 0.02, 0.25, 0.02, 0],
extrapolate: 'clamp',
});
return {
transform: [{ translateX }, { translateY }],
transform: [{ translateX }],
shadowOpacity,
};
}
@ -91,10 +92,9 @@ function forVertical(props) {
outputRange: [height, 0, 0],
extrapolate: 'clamp',
});
const translateX = 0;
return {
transform: [{ translateX }, { translateY }],
transform: [{ translateY }],
};
}