我在我的组件中使用 FlatList,它工作正常。所需要的是我的整个屏幕应该有一个自动高度,并且 FlatList 内容永远不会超出屏幕高度。
此外,FlatList 的高度应根据其中的内容/元素进行更改,而不是给出任何固定高度。
如何实现自动屏幕高度和 FlatList 内容自动高度等两种情况?
代码:
import React, { useState, useEffect } from 'react';
import {
View,
StyleSheet,
useWindowDimensions,
Text,
FlatList,
SafeAreaView,
TouchableOpacity,
} from 'react-native';
import { LinearGradient as LinearGradientView } from 'expo-linear-gradient';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { ActivityIndicator, ThemeProvider } from 'react-native-paper';
import { ScrollView } from 'react-native-gesture-handler';
import { useIsFocused, useNavigation } from '@react-navigation/native';
import Svg, { Path } from 'react-native-svg';
import { BASE_GRADIENT_HEAVY } from '../rooms/Background';
import { useResolution } from '../browse/useResolution';
import { OnboardingNavigationProp } from '../navigation/LinkingConfiguration';
import { LIGHT_THEME } from '../Theme';
import { OnboardingBack } from './OnboardingBack';
import {
useOnboardingYearsOfExperiencePage,
useOnboardingYearsOfExperienceSubmit,
} from './useOnboardingYearsOfExperiencePage';
export function OnboardingYearsOfExperience({ route }: { route?: any }) {
const { height } = useWindowDimensions();
const { top: safeAreaTop } = useSafeAreaInsets();
const [selectedId, setSelectedId] = useState<{ id: string }>();
const [role_id, setRoleId] = useState<number>();
const { navigate } =
useNavigation<OnboardingNavigationProp<'OnboardingConfirmAllDetails'>>();
const parentUrl = route?.params.result.onboarding._links;
const initialUrl = parentUrl.onboarding_years_of_experience.href;
const onboardingUrl = parentUrl.self.href;
useEffect(() => {
setRoleId(route?.params.role_id);
}, []);
const isFocused = useIsFocused();
const { contentType } = useResolution();
const {
data: result,
isLoading,
error,
} = useOnboardingYearsOfExperiencePage(initialUrl, contentType, role_id, {
enabled: isFocused,
notifyOnChangeProps: ['data', 'isLoading', 'error'],
});
const {
mutateAsync: updateYearsOfExperience,
isLoading: isUpdatingYearsOfExperience,
error: yearsOfExperienceUpdateError,
} = useOnboardingYearsOfExperienceSubmit(onboardingUrl);
const Arrow = ({ style }: { style: object }) => {
return (
<Svg width="7" height="11" viewBox="0 0 7 11" fill="none" style={style}>
<Path
d="M6.28711 5.53931C6.28711 5.31649 6.19783 5.12476 6.02452 4.95376L1.9911 1.07251C1.85455 0.937781 1.68649 0.865234 1.48692 0.865234C1.07728 0.865234 0.751664 1.18651 0.751664 1.58552C0.751664 1.78243 0.830441 1.96898 0.977493 2.11407L4.54875 5.53413L0.977492 8.95937C0.835692 9.10446 0.751663 9.28583 0.751662 9.48792C0.751662 9.88693 1.07728 10.2082 1.48692 10.2082C1.68649 10.2082 1.85455 10.1357 1.99635 10.0009L6.02452 6.11968C6.20308 5.93832 6.28711 5.75695 6.28711 5.53931Z"
fill="#4D4D4D"
/>
</Svg>
);
};
const Item = ({
item,
onPress,
}: {
item?: { id: string; title: string };
onPress: () => void;
}) => (
<TouchableOpacity onPress={onPress}>
<Text
style={{
color: '#4D4D4D',
fontFamily: 'Inter_400Regular',
fontStyle: 'normal',
fontWeight: '400',
fontSize: 16,
lineHeight: 32,
padding: 3,
margin: 2,
}}
>
{item?.title}
</Text>
</TouchableOpacity>
);
const renderItem = ({ item }: { item: { id: string; title: string } }) => {
return (
<React.Fragment>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
borderRadius: 5,
backgroundColor:
selectedId?.id === item?.id ? '#F2F2F2' : 'transparent',
}}
>
<View style={{ width: '90%' }}>
<Item
item={item}
onPress={() => {
setSelectedId({ id: item.id });
updateYearsOfExperience({ id: item.id, role_id })
.then((result) => {
navigate('Onboarding', {
screen: 'OnboardingConfirmAllDetails',
params: { result },
});
})
.catch(() => {});
}}
/>
</View>
<View style={{ width: '10%' }}>
<Arrow style={{ position: 'absolute', top: 16, right: 10 }} />
</View>
</View>
</React.Fragment>
);
};
return (
<ThemeProvider theme={LIGHT_THEME}>
<View style={{ height: safeAreaTop }} />
<View style={styles.topHeader}>
<LinearGradientView
{...BASE_GRADIENT_HEAVY}
style={[styles.gradiantStyle]}
/>
</View>
<View style={styles.innerContainer}>
<ScrollView
contentContainerStyle={{
marginHorizontal: 'auto',
alignSelf: 'center',
width: '100%',
backgroundColor: '#ffffff',
height: '100%',
}}
>
<OnboardingBack
style={{
left: -10,
}}
/>
<Text style={styles.topHeadline}>
How many years of experience do you have?
</Text>
<Text style={styles.middleHeadline}>
Jump-start the conversation by sharing your years of experience
within healthcare.
</Text>
{isLoading || isUpdatingYearsOfExperience ? (
<ActivityIndicator size="large" />
) : (
<SafeAreaView>
<FlatList
contentContainerStyle={{ flexGrow: 1 }}
data={Object.values(
result!['years_of_experiences']['years_of_experiences_list']
)}
renderItem={renderItem}
keyExtractor={(item) => item.id}
extraData={selectedId}
style={{
borderWidth: 1,
borderStyle: 'solid',
borderColor: '#D7D7D7',
borderRadius: 5,
padding: 12,
height: '27%',
}}
ListEmptyComponent={
<View>
<Text>No data found</Text>
</View>
}
/>
</SafeAreaView>
)}
</ScrollView>
</View>
</ThemeProvider>
);
}
const styles = StyleSheet.create({
innerContainer: {
display: 'flex',
position: 'relative',
backgroundColor: 'white',
padding: 18,
},
topHeader: {
backgroundColor: '#e5dede',
padding: 0,
width: '100%',
},
topHeadline: {
fontSize: 24,
fontFamily: 'CircularStd_Medium',
fontStyle: 'normal',
fontWeight: '500',
color: '#222222',
marginTop: 40.6,
marginBottom: 14.6,
display: 'flex',
alignItems: 'center',
lineHeight: 32,
},
middleHeadline: {
fontSize: 16,
fontFamily: 'Inter_400Regular',
fontStyle: 'normal',
fontWeight: '400',
lineHeight: 24,
color: '#4D4D4D',
marginBottom: 30,
},
gradiantStyle: {
width: 248.4,
height: 4.71,
},
});
最佳答案
将以下样式添加到您的 flatList =>
style={{maxHeight:'你想要什么',flexGrow:0}}
关于javascript - 我们如何根据 React Native 中的列表项内容为 FlatList 提供自动高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73398168/