我无法包装 FlatList,它使 FlatList 高度超过包装器
I can't wrap a FlatList, it makes the FlatList height is over the wrapper
大家好!
我想在 Modal
中显示我的通知数据并使用 FlatList
,我在 Modal
组件中使用 react-native-modal,在我有的模式中3 个主要成分,如 header
、body
和 footer
。
header
只是一个标题加上底线
body
是一个 FlatList
和footer
只是一个清除通知的按钮
我用 View
组件再次包装这 3 个主要组件,并为此 (View
) 组件设置 maxHeight
body
是这里的主要问题,因为 FlatList
高度超过了我设置的 maxHeight
的 View
高度,很难解释,抱歉,但是你可以看到底部的图片
And the important one is that I can't use flex:1
inside a Modal it's because a module that I use (react-native-modal
) if I use flex: 1
it makes FlatList
disappear
图片
enter image description here
代码ModalNotificationShowcase.jsx
import React, {
forwardRef,
memo,
useContext,
useEffect,
useImperativeHandle,
useState,
} from 'react';
import {View, Dimensions, Pressable, FlatList} from 'react-native';
import {Divider, Button, Icon, List} from '@ui-kitten/components';
import {IconHelper, Text, Modal} from '../Helper';
import {useRealmInstance, useRealmObjects} from '../../hooks';
import moment from 'moment';
import util from '../../utils';
import ThemeContext from '../../themes/ThemeContext';
const NotificationItem = memo(props => {
const {currentTheme} = props;
const [bgColor, setBgColor] = useState(
currentTheme === 'light' ? '#EDF1F7' : '#1A2138',
);
const notif = props.data;
const realm = props.realm;
return (
<Pressable
onPressIn={() =>
setBgColor(currentTheme === 'light' ? '#E4E9F2' : '#151A30')
}
style={{
padding: 12,
marginBottom: 12,
backgroundColor: bgColor,
borderRadius: 4,
}}
onPress={props.onPress}
onPressOut={() =>
setBgColor(currentTheme === 'light' ? '#EDF1F7' : '#1A2138')
}
>
<View style={{flexDirection: 'row'}}>
<IconHelper
color={notif.name === 'reminder' ? '#FF3D71' : '#0095FF'}
name={
notif.name === 'reminder'
? 'alert-triangle-outline'
: 'info-outline'
}
style={{marginRight: 8}}
onPress={() => console.log('Pressed')}
/>
<Text size={14} style={{flex: 1, marginBottom: 4}}>
{notif.message}
</Text>
</View>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<Text size={12} hint>
{moment(notif.createdAt).fromNow()}
</Text>
<View style={{flex: 1, alignItems: 'flex-end'}}>
<IconHelper
size={20}
color='#FF3D71'
name='trash-2-outline'
underlayColor='#E4E9F2'
onPress={() => {
realm.write(() => {
realm.delete(notif);
});
}}
/>
</View>
</View>
</Pressable>
);
});
const NotificationShowcase = props => {
const realm = useRealmInstance();
const notifications = useRealmObjects('notifications');
const {theme} = useContext(ThemeContext);
return (
<View
style={{
width: Dimensions.get('window').width - 48,
maxHeight: Dimensions.get('window').height - 48,
borderRadius: 4,
}}
>
// =====
// Header
// =====
<Text size={14} bold align='center' style={{padding: 12}}>
Notifikasi
</Text>
<Divider />
// =====
// Body
// =====
<View style={{padding: 12, flexGrow: 1, overflow: 'hidden'}}>
{notifications.isEmpty() ? (
<Text
size={14}
align='center'
hint
style={{
padding: 8,
marginBottom: 12,
backgroundColor: theme === 'light' ? '#EDF1F7' : '#1A2138',
borderRadius: 4,
}}
>
Belum ada notifikasi untuk saat ini
</Text>
) : (
// ======================
// The main issue is here
// ======================
<FlatList
data={notifications}
initialNumToRender={0}
maxToRenderPerBatch={1}
updateCellsBatchingPeriod={120}
numColumns={1}
keyExtractor={item => item._id.toString()}
renderItem={items => {
const notif = items.item;
return (
<NotificationItem
data={notif}
realm={realm}
currentTheme={theme}
/>
);
}}
/>
)}
// =====
// Footer
// =====
{!notifications.isEmpty() && (
<View
style={{
justifyContent: 'center',
alignItems: 'center',
}}
>
<Button
size='small'
appearance='outline'
accessoryLeft={props => (
<Icon {...props} name='trash-2-outline' />
)}
onPress={() => {
realm.write(() => {
realm.delete(notifications);
});
}}
>
Hapus semua
</Button>
</View>
)}
</View>
</View>
);
};
const ModalNotificationShowcase = forwardRef((props, ref) => {
let Modal_ref;
useImperativeHandle(ref, () => ({
show: () => Modal_ref.show(),
hide: () => Modal_ref.hide(),
}));
return (
<Modal
backdropStyle={{backgroundColor: 'rgba(9, 44, 76, .32)'}}
onBackdropPress={() => Modal_ref.hide()}
ref={refs => (Modal_ref = refs)}
>
<NotificationShowcase
navigate={props.navigate}
onPressNotifItem={() => Modal_ref.hide()}
/>
</Modal>
);
});
export default ModalNotificationShowcase;
已更新
const NotificationShowcase = props => {
return (
<View
style={{
flex: 1,
margin: 24,
borderRadius: 4,
}}
>
...
// =====
// Body
// =====
<View style={{flex: 1}}>
// ...
</View>
</View>
);
};
大家好!
我想在 Modal
中显示我的通知数据并使用 FlatList
,我在 Modal
组件中使用 react-native-modal,在我有的模式中3 个主要成分,如 header
、body
和 footer
。
header
只是一个标题加上底线
body
是一个 FlatList
和footer
只是一个清除通知的按钮
我用 View
组件再次包装这 3 个主要组件,并为此 (View
) 组件设置 maxHeight
body
是这里的主要问题,因为 FlatList
高度超过了我设置的 maxHeight
的 View
高度,很难解释,抱歉,但是你可以看到底部的图片
And the important one is that I can't use
flex:1
inside a Modal it's because a module that I use (react-native-modal
) if I useflex: 1
it makesFlatList
disappear
图片
enter image description here
代码ModalNotificationShowcase.jsx
import React, {
forwardRef,
memo,
useContext,
useEffect,
useImperativeHandle,
useState,
} from 'react';
import {View, Dimensions, Pressable, FlatList} from 'react-native';
import {Divider, Button, Icon, List} from '@ui-kitten/components';
import {IconHelper, Text, Modal} from '../Helper';
import {useRealmInstance, useRealmObjects} from '../../hooks';
import moment from 'moment';
import util from '../../utils';
import ThemeContext from '../../themes/ThemeContext';
const NotificationItem = memo(props => {
const {currentTheme} = props;
const [bgColor, setBgColor] = useState(
currentTheme === 'light' ? '#EDF1F7' : '#1A2138',
);
const notif = props.data;
const realm = props.realm;
return (
<Pressable
onPressIn={() =>
setBgColor(currentTheme === 'light' ? '#E4E9F2' : '#151A30')
}
style={{
padding: 12,
marginBottom: 12,
backgroundColor: bgColor,
borderRadius: 4,
}}
onPress={props.onPress}
onPressOut={() =>
setBgColor(currentTheme === 'light' ? '#EDF1F7' : '#1A2138')
}
>
<View style={{flexDirection: 'row'}}>
<IconHelper
color={notif.name === 'reminder' ? '#FF3D71' : '#0095FF'}
name={
notif.name === 'reminder'
? 'alert-triangle-outline'
: 'info-outline'
}
style={{marginRight: 8}}
onPress={() => console.log('Pressed')}
/>
<Text size={14} style={{flex: 1, marginBottom: 4}}>
{notif.message}
</Text>
</View>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<Text size={12} hint>
{moment(notif.createdAt).fromNow()}
</Text>
<View style={{flex: 1, alignItems: 'flex-end'}}>
<IconHelper
size={20}
color='#FF3D71'
name='trash-2-outline'
underlayColor='#E4E9F2'
onPress={() => {
realm.write(() => {
realm.delete(notif);
});
}}
/>
</View>
</View>
</Pressable>
);
});
const NotificationShowcase = props => {
const realm = useRealmInstance();
const notifications = useRealmObjects('notifications');
const {theme} = useContext(ThemeContext);
return (
<View
style={{
width: Dimensions.get('window').width - 48,
maxHeight: Dimensions.get('window').height - 48,
borderRadius: 4,
}}
>
// =====
// Header
// =====
<Text size={14} bold align='center' style={{padding: 12}}>
Notifikasi
</Text>
<Divider />
// =====
// Body
// =====
<View style={{padding: 12, flexGrow: 1, overflow: 'hidden'}}>
{notifications.isEmpty() ? (
<Text
size={14}
align='center'
hint
style={{
padding: 8,
marginBottom: 12,
backgroundColor: theme === 'light' ? '#EDF1F7' : '#1A2138',
borderRadius: 4,
}}
>
Belum ada notifikasi untuk saat ini
</Text>
) : (
// ======================
// The main issue is here
// ======================
<FlatList
data={notifications}
initialNumToRender={0}
maxToRenderPerBatch={1}
updateCellsBatchingPeriod={120}
numColumns={1}
keyExtractor={item => item._id.toString()}
renderItem={items => {
const notif = items.item;
return (
<NotificationItem
data={notif}
realm={realm}
currentTheme={theme}
/>
);
}}
/>
)}
// =====
// Footer
// =====
{!notifications.isEmpty() && (
<View
style={{
justifyContent: 'center',
alignItems: 'center',
}}
>
<Button
size='small'
appearance='outline'
accessoryLeft={props => (
<Icon {...props} name='trash-2-outline' />
)}
onPress={() => {
realm.write(() => {
realm.delete(notifications);
});
}}
>
Hapus semua
</Button>
</View>
)}
</View>
</View>
);
};
const ModalNotificationShowcase = forwardRef((props, ref) => {
let Modal_ref;
useImperativeHandle(ref, () => ({
show: () => Modal_ref.show(),
hide: () => Modal_ref.hide(),
}));
return (
<Modal
backdropStyle={{backgroundColor: 'rgba(9, 44, 76, .32)'}}
onBackdropPress={() => Modal_ref.hide()}
ref={refs => (Modal_ref = refs)}
>
<NotificationShowcase
navigate={props.navigate}
onPressNotifItem={() => Modal_ref.hide()}
/>
</Modal>
);
});
export default ModalNotificationShowcase;
已更新
const NotificationShowcase = props => {
return (
<View
style={{
flex: 1,
margin: 24,
borderRadius: 4,
}}
>
...
// =====
// Body
// =====
<View style={{flex: 1}}>
// ...
</View>
</View>
);
};