fix: relatively position float Header if !headerTransparent (#8285)

## Motivation

Right now `headerMode: float` renders an absolutely-positioned header. To offset the content appropriately, it then measures the height of the header and compensates with a margin. This approach unfortunately doesn't work well for animations.

Before             |  After
:-------------------------:|:-------------------------:
<img src="http://ashoat.com/jerky_absolute.gif" width="300" />  |  <img src="http://ashoat.com/smooth_relative.gif" width="300" />

## Approach

When rendering the header absolutely we want to render it above (after, in sibling order) the content. But when rendering it relatively we want to render it first (before, in sibling order).

The margin compensation code is no longer necessary so I removed it.

## Test plan

I used the `StackHeaderCustomization` example to make sure transitions between `headerTransparent` and `!headerTransparent` looked good. I added a custom (taller) header to test if height transitions looked good, and toggled `headerShown` to make sure that transitioned well too.

Would be open to any other suggestions of things to test!
This commit is contained in:
Ashoat Tevosyan
2020-06-05 18:12:00 -04:00
committed by GitHub
parent 762cc44578
commit 78afbffe97
3 changed files with 72 additions and 22 deletions

View File

@@ -1,5 +1,12 @@
import * as React from 'react';
import { View, StyleSheet, ScrollView, Alert, Platform } from 'react-native';
import {
View,
StyleSheet,
ScrollView,
Alert,
Platform,
Text,
} from 'react-native';
import { Button, Appbar } from 'react-native-paper';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { RouteProp, ParamListBase } from '@react-navigation/native';
@@ -8,6 +15,8 @@ import {
StackNavigationProp,
HeaderBackground,
useHeaderHeight,
Header,
StackHeaderProps,
} from '@react-navigation/stack';
import BlurView from '../Shared/BlurView';
import Article from '../Shared/Article';
@@ -91,6 +100,20 @@ type Props = Partial<React.ComponentProps<typeof SimpleStack.Navigator>> & {
navigation: StackNavigationProp<ParamListBase>;
};
function CustomHeader(props: StackHeaderProps) {
const { navigation } = props;
return (
<>
<Header {...props} />
<View style={{ opacity: navigation.isFocused() ? 1 : 0 }}>
<Text style={{ textAlign: 'center', backgroundColor: 'pink' }}>
Why hello there, pardner!
</Text>
</View>
</>
);
}
export default function SimpleStackScreen({ navigation, ...rest }: Props) {
navigation.setOptions({
headerShown: false,
@@ -103,6 +126,7 @@ export default function SimpleStackScreen({ navigation, ...rest }: Props) {
component={ArticleScreen}
options={({ route }) => ({
title: `Article by ${route.params?.author}`,
header: CustomHeader,
headerTintColor: '#fff',
headerStyle: { backgroundColor: '#ff005d' },
headerBackTitleVisible: false,