#react-native #react-navigation #react-navigation-stack
#react-native #реакция-навигация #react-navigation-stack
Вопрос:
Последние несколько дней я работал над добавлением анимированного заголовка на свои экраны. Мне это удалось, однако теперь я хотел бы применить это в качестве своего заголовка по умолчанию, а не копировать и вставлять код во все экраны, которые я хочу использовать. На данный момент анимированный заголовок реализован на экране следующим образом:
Для отображения заголовка:
static navigationOptions = ({ navigation }) => {
return {
header: () => {
return (
<SafeAreaView style={{
height: 0,
overflow: 'visible',
}}>
<Animated.View style={{height: 80, width: 80,
transform: [ {translateY: navigation.getParam('headerScrollY', 0)}]
}}>
<TouchableOpacity style={{padding: 20}} onPress={() => navigation.goBack()}>
<Icon.Ionicons style={{color: '#ffffff', width: 50, height: 50}} name={'ios-arrow-round-back'} size={50} />
</TouchableOpacity>
</Animated.View>
</SafeAreaView>
)
}
}
};
Для настройки состояния:
constructor() {
super();
this.state = {
headerScrollY: new Animated.Value(0),
};
}
Чтобы установить интерполяцию анимации
и передать значение в навигационные реквизиты (это то, к чему мне нужно будет получить доступ позже при рендеринге заголовка)
componentWillMount() {
this.props.navigation.setParams({
headerScrollY: this.state.headerScrollY.interpolate({
inputRange: [0, 80],
outputRange: [0, -80],
})
});
}
Основной метод рендеринга с «ScrollView», вызывающий событие «onScroll» для запуска действия прокрутки
render() {
return (
<ScrollView
style={Styles.wholePageContainer}
showsVerticalScrollIndicator={false}
scrollEventThrottle={16}
onScroll={Animated.event( [{nativeEvent:{contentOffset: {y: this.state.headerScrollY}}}])}
>
...
</ScrollView>
);
}
Чтобы установить заголовок по умолчанию, я должен установить значение «header» в «defaultNavigationOptions» при использовании «createStackNavigator». Я могу использовать это для создания простого заголовка по умолчанию красного цвета высотой 100 (код и изображение ниже):
const HomeStack = createStackNavigator({
Home: HomeScreen,
Category: CategoryScreen,
Venue: VenueScreen,
Activity: ActivityScreen,
}, {
headerMode: 'screen',
defaultNavigationOptions: {
header: <View style={{backgroundColor: '#ff0000', height: 100}} />
,
},
});
Симулятор, демонстрирующий применение простого заголовка по умолчанию
К сожалению, для моего анимированного заголовка мне требуется реквизит «навигация», поскольку он используется для хранения значений анимации. Я перепробовал много подходов для передачи этого туда, где мне нужны значения, и мне было интересно, знает ли кто-нибудь, как это сделать, или возможно ли это вообще, или у кого-нибудь есть какие-либо предложения.
Комментарии:
1. вы пробовали это:
defaultNavigationOptions: ({ navigation }) => ({ header: <YourHeader navigation={navigation} /> })
2. Фантастика, это сработало! Большое вам спасибо. Я перепробовал много подобных вариантов, однако из-за документации, в которой говорится, что заголовок должен быть функцией, я всегда делал эту функцию, в которой я пытался получить навигационные реквизиты там, где я должен был быть на 1 ступень выше по ссылке, как вы предложили. Я опубликую рабочий код ниже.
3. Удачного кодирования 🙂
Ответ №1:
Благодаря Хенду Эль-Сахли теперь у меня есть код, который работает так, как задумано. Результат (для дальнейшего использования другими) такой же, как и раньше, однако удаление определений заголовков в параметрах навигации для каждого экрана и вызов «createStackNavigator» выглядит следующим образом:
const HomeStack = createStackNavigator({
Home: HomeScreen,
Category: CategoryScreen,
Venue: VenueScreen,
Activity: ActivityScreen,
}, {
headerMode: 'screen',
defaultNavigationOptions: ({ navigation }) => ({
header:
<SafeAreaView style={{
height: 0,
overflow: 'visible',
}}>
<Animated.View style={{height: 80, width: 80,
transform: [ {translateY: navigation.getParam('headerScrollY', 0)}]
}}>
<TouchableOpacity style={{padding: 20}} onPress={() => navigation.goBack()}>
<Icon.Ionicons style={{color: '#ffffff', width: 50, height: 50}} name={'ios-arrow-round-back'} size={50} />
</TouchableOpacity>
</Animated.View>
</SafeAreaView>
}),
});
Комментарии:
1. Моя (глупая) ошибка заключалась в том, что я использовал
headerLeft: ({navigation}) =>
то, чего не существует ! ИспользованиеdefaultNavigationOptions: ({ navigation }) =>
решило проблему! Спасибо!