react-native-reanimated 中的可折叠 header,在 React Native 中具有多个选项卡
Collapsible header in react-native-reanimated with multiple tabs in React Native
我正在尝试在 React Native 中创建一个带有 2 个选项卡的屏幕(使用 react-native-tab-view
),布局如下:
------------------------
| Collapsible Header |
|------------------------|
| Tab A | Tab B |
|------------------------|
| |
| |
| FlatList |
| in Tab |
| Content |
| |
| |
| |
| |
------------------------
我想要的布局是可折叠 header 和标签栏的绝对定位,FlatList 实际上覆盖了整个屏幕(并且 header 和标签栏都打开了上面)。为了将可滚动部分放在标签栏之后,我在 FlatList 的 contentContainerStyle
中添加了一个 paddingTop
。这是问题的根源 - 在选项卡 A 中滚动,然后移动到选项卡 B 时,由于填充,将会出现空白 space。
我创建了一个完整的 Expo 项目来展示这个问题:https://expo.io/@bartzy/collapsible-tab-view-example
这是 Expo 项目的 Github 存储库:https://github.com/bartzy/CollapsibleTabViewExample
这是示例应用的快速视频,显示了切换到选项卡 2 后的空白填充 space:
对于如何在选项卡之间移动时消除空白 space,同时保持所需的折叠行为,我将不胜感激。
您需要保留平面列表的引用和未处于焦点的选项卡的 scolltoOffset。 https://gist.github.com/maitham/6e0841800d88bf9c289fc45bbc903b1d。这似乎对我有用。
这是一个常见问题,关于如何解决这个问题的示例很少,但最近我发布了 react-native-tab-view 的包装器来解决这个问题。
演示
例子
示例来自 quick start。
import * as React from 'react';
import { StyleSheet, View, Text, Animated } from 'react-native';
import {
CollapsibleTabView,
useCollapsibleScene,
} from 'react-native-collapsible-tab-view';
import { SceneMap } from 'react-native-tab-view';
type Route = {
key: string;
title: string;
};
const SomeRoute: React.FC<{ routeKey: string; color: string }> = ({
routeKey,
color,
}) => {
const scrollPropsAndRef = useCollapsibleScene(routeKey);
return (
<Animated.ScrollView
style={{ backgroundColor: color }}
{...scrollPropsAndRef}
>
<View style={styles.content} />
</Animated.ScrollView>
);
};
const FirstScene = () => <SomeRoute routeKey="first" color="white" />;
const SecondScene = () => <SomeRoute routeKey="second" color="black" />;
const HEADER_HEIGHT = 250;
const renderHeader = () => (
<View style={styles.header}>
<Text style={styles.headerText}>COLLAPSIBLE</Text>
</View>
);
const renderScene = SceneMap({
first: FirstScene,
second: SecondScene,
});
const App: React.FC<object> = () => {
const [index, setIndex] = React.useState(0);
const [routes] = React.useState<Route[]>([
{ key: 'first', title: 'First' },
{ key: 'second', title: 'Second' },
]);
const handleIndexChange = (index: number) => {
setIndex(index);
};
return (
<CollapsibleTabView<Route>
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={handleIndexChange}
renderHeader={renderHeader} // optional
headerHeight={HEADER_HEIGHT} // optional, will be computed.
/>
);
};
export default App;
const styles = StyleSheet.create({
header: {
height: HEADER_HEIGHT,
backgroundColor: '#2196f3',
justifyContent: 'center',
alignItems: 'center',
elevation: 4,
},
headerText: {
color: 'white',
fontSize: 24,
},
content: {
height: 1500,
},
});
我正在尝试在 React Native 中创建一个带有 2 个选项卡的屏幕(使用 react-native-tab-view
),布局如下:
------------------------
| Collapsible Header |
|------------------------|
| Tab A | Tab B |
|------------------------|
| |
| |
| FlatList |
| in Tab |
| Content |
| |
| |
| |
| |
------------------------
我想要的布局是可折叠 header 和标签栏的绝对定位,FlatList 实际上覆盖了整个屏幕(并且 header 和标签栏都打开了上面)。为了将可滚动部分放在标签栏之后,我在 FlatList 的 contentContainerStyle
中添加了一个 paddingTop
。这是问题的根源 - 在选项卡 A 中滚动,然后移动到选项卡 B 时,由于填充,将会出现空白 space。
我创建了一个完整的 Expo 项目来展示这个问题:https://expo.io/@bartzy/collapsible-tab-view-example 这是 Expo 项目的 Github 存储库:https://github.com/bartzy/CollapsibleTabViewExample
这是示例应用的快速视频,显示了切换到选项卡 2 后的空白填充 space:
对于如何在选项卡之间移动时消除空白 space,同时保持所需的折叠行为,我将不胜感激。
您需要保留平面列表的引用和未处于焦点的选项卡的 scolltoOffset。 https://gist.github.com/maitham/6e0841800d88bf9c289fc45bbc903b1d。这似乎对我有用。
这是一个常见问题,关于如何解决这个问题的示例很少,但最近我发布了 react-native-tab-view 的包装器来解决这个问题。
演示
例子
示例来自 quick start。
import * as React from 'react';
import { StyleSheet, View, Text, Animated } from 'react-native';
import {
CollapsibleTabView,
useCollapsibleScene,
} from 'react-native-collapsible-tab-view';
import { SceneMap } from 'react-native-tab-view';
type Route = {
key: string;
title: string;
};
const SomeRoute: React.FC<{ routeKey: string; color: string }> = ({
routeKey,
color,
}) => {
const scrollPropsAndRef = useCollapsibleScene(routeKey);
return (
<Animated.ScrollView
style={{ backgroundColor: color }}
{...scrollPropsAndRef}
>
<View style={styles.content} />
</Animated.ScrollView>
);
};
const FirstScene = () => <SomeRoute routeKey="first" color="white" />;
const SecondScene = () => <SomeRoute routeKey="second" color="black" />;
const HEADER_HEIGHT = 250;
const renderHeader = () => (
<View style={styles.header}>
<Text style={styles.headerText}>COLLAPSIBLE</Text>
</View>
);
const renderScene = SceneMap({
first: FirstScene,
second: SecondScene,
});
const App: React.FC<object> = () => {
const [index, setIndex] = React.useState(0);
const [routes] = React.useState<Route[]>([
{ key: 'first', title: 'First' },
{ key: 'second', title: 'Second' },
]);
const handleIndexChange = (index: number) => {
setIndex(index);
};
return (
<CollapsibleTabView<Route>
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={handleIndexChange}
renderHeader={renderHeader} // optional
headerHeight={HEADER_HEIGHT} // optional, will be computed.
/>
);
};
export default App;
const styles = StyleSheet.create({
header: {
height: HEADER_HEIGHT,
backgroundColor: '#2196f3',
justifyContent: 'center',
alignItems: 'center',
elevation: 4,
},
headerText: {
color: 'white',
fontSize: 24,
},
content: {
height: 1500,
},
});