我在平面列表中有一个联系人列表,我制作了一个随机颜色生成器函数,它将为带有用户名字缩写的联系人个人资料图像占位符生成随机背景颜色。我在列表中添加了一个删除按钮,以便用户可以删除特定的联系人。如果用户按下删除按钮,我已经制作了一个自定义弹出对话框来要求确认。我正在从本地领域数据库中获取列表。
现在的问题是,当我单击删除按钮时,它会重新呈现整个列表,每次单击删除按钮时,用户图像占位符的背景颜色都会发生变化。但是预期的行为应该是当我单击删除按钮时,我的自定义弹出窗口将出现,如果用户确认删除,则列表可以重新呈现,但只需单击删除按钮即可重新呈现。我不熟悉反应备忘录。我尝试在 generateRandomColor 函数甚至自定义弹出窗口上应用它,但没有任何效果。下面是我的原始代码。有人,请帮助,我在过去的两天里被困住了。
联系人列表代码如下:-
import React from 'react';
import {useState, useEffect, useCallback} from 'react';
import {
View,
Text,
FlatList,
StatusBar,
SafeAreaView,
TouchableOpacity,
StyleSheet,
Linking,
Animated,
Modal,
} from 'react-native';
import {CustomDialog} from '@components/CustomDialog';
import {Header} from '@components/Header';
import Fonts from '@utils/Fonts';
import {Colors} from '@theme';
import WhatsappIcon from '@images/svgs/whatsapp.svg';
import DeleteIcon from '@images/svgs/delete.svg';
import {
realm,
insertNewContactList,
updateContactList,
deleteContactList,
queryAllContactLists,
} from '@database/realmDB';
const RecentSaved = ({navigation}) => {
const [recentSavedContacts, setRecentSavedContacts] = useState([]);
const [visible, setVisible] = useState(false);
useEffect(() => {
const tasks = realm.objects('Contact');
// set state to the initial value of your realm objects
setRecentSavedContacts([...tasks]);
tasks.addListener(() => {
// update state of tasks to the updated value
setRecentSavedContacts([...tasks]);
});
return () => {
// Remember to remove the listener when you're done!
tasks.removeAllListeners();
// Call the close() method when done with a realm instance to avoid memory leaks.
realm.close();
};
}, []);
const InitialIcon = ({initials}) => {
return (
<View
style={[
Styles.initialsIconContainer,
{backgroundColor: generateColor()},
]}>
<Text style={Styles.initialsIconText}>{initials}</Text>
</View>
);
};
const generateColor = () => {
const randomColor = Math.floor(Math.random() * 16777215)
.toString(16)
.padStart(6, '0');
return `#${randomColor}`;
};
const onDelete = id => {
// deleteContactList(id)
// .then()
// .catch(error => {
// alert(`Failed to delete todoList with id = ${id}, error=${error}`);
// });
setVisible(true);
};
const recentContactCards = ({item, index}) => {
return (
<View style={Styles.flatListCard}>
<View style={Styles.flatListSubView}>
<View style={{flexDirection: 'row', marginLeft: 10}}>
<InitialIcon
initials={
item.name
? item.name.slice(0, 2).toUpperCase()
: `+${item.number.slice(0, 2)}`
}
/>
<View style={{justifyContent: 'center'}}>
{item.name ? (
<Text style={Styles.nameTitle}>{item.name}</Text>
) : null}
<Text style={item.name ? Styles.numberTitle : Styles.nameTitle}>
+{item.number}
</Text>
</View>
</View>
<View style={{flexDirection: 'row'}}>
<TouchableOpacity
style={{marginRight: 15}}>
<WhatsappIcon width={25} height={25} />
</TouchableOpacity>
<TouchableOpacity
onPress={() => onDelete(item.id)}
style={{marginRight: 10}}>
<DeleteIcon width={25} height={25} />
</TouchableOpacity>
</View>
</View>
<View style={Styles.separatorLine} />
</View>
);
};
return (
<SafeAreaView style={Styles.safeAreaContainer}>
<StatusBar barStyle="light-content" backgroundColor={Colors.AppTheme} />
<Header title="Recent" />
<FlatList
data={recentSavedContacts}
contentContainerStyle={Styles.flatListContainer}
keyExtractor={(item, index) => Math.random().toString()}
renderItem={recentContactCards}
ListEmptyComponent={() => {
return (
<View style={Styles.emptyListView}>
<Text>There are no saved Contacts</Text>
</View>
);
}}
/>
<CustomDialog visible={visible}>
<View style={{alignItems: 'center'}}></View>
<View style={{alignItems: 'center'}}>
<DeleteIcon width={45} height={45} />
</View>
<Text style={Styles.nameTitle}>
Are you sure you want to delete this contact?
</Text>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
width: '90%',
alignSelf: 'center',
}}>
<TouchableOpacity
style={{
borderWidth: 1,
borderRadius: 10,
padding: 10,
backgroundColor: 'red',
width: '40%',
}}
onPress={() => setVisible(false)}>
<Text style={[Styles.nameTitle, {marginLeft: 15, color: 'white'}]}>
Cancel
</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
borderWidth: 1,
borderRadius: 10,
padding: 10,
backgroundColor: 'red',
width: '40%',
}}
onPress={() => setVisible(false)}>
<Text style={[Styles.nameTitle, {marginLeft: 15, color: 'white'}]}>
Confirm
</Text>
</TouchableOpacity>
</View>
</CustomDialog>
</SafeAreaView>
);
};
const Styles = StyleSheet.create({
safeAreaContainer: {flex: 1, backgroundColor: 'white'},
initialsIconContainer: {
alignItems: 'center',
justifyContent: 'center',
borderRadius: 25,
width: 50,
height: 50,
},
initialsIconText: {color: 'white', fontSize: 20},
flatListContainer: {
backgroundColor: Colors.white,
flexGrow: 1,
},
flatListCard: {
height: 70,
backgroundColor: Colors.white,
margin: 10,
alignItems: 'center',
borderRadius: 35,
},
flatListSubView: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
width: '100%',
},
emptyListView: {
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
},
nameTitle: {
...Fonts.openSansSemiBold,
fontSize: 15,
color: 'black',
marginLeft: 20,
},
numberTitle: {
...Fonts.openSansRegular,
fontSize: 15,
color: 'gray',
marginLeft: 20,
},
separatorLine: {
height: 2,
backgroundColor: '#F2F2F2',
width: '100%',
position: 'absolute',
bottom: 2,
},
modalBackGround: {
flex: 1,
backgroundColor: 'rgba(0,0,0,0.5)',
justifyContent: 'center',
alignItems: 'center',
},
modalContainer: {
width: '80%',
backgroundColor: 'white',
paddingHorizontal: 20,
paddingVertical: 30,
borderRadius: 20,
elevation: 20,
},
header: {
width: '100%',
height: 40,
alignItems: 'flex-end',
justifyContent: 'center',
},
});
export default RecentSaved;
自定义对话框组件代码如下:-
import React, {useState, useEffect, useCallback} from 'react';
import {View, StyleSheet, Animated, Modal} from 'react-native';
const CustomDialog = ({visible, children}) => {
const [showModal, setShowModal] = useState(visible);
const scaleValue = React.useRef(new Animated.Value(0)).current;
useEffect(() => {
toggleModal();
}, [visible]);
const toggleModal = () => {
if (visible) {
setShowModal(true);
Animated.spring(scaleValue, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}).start();
} else {
setTimeout(() => setShowModal(false), 200);
Animated.timing(scaleValue, {
toValue: 0,
duration: 300,
useNativeDriver: true,
}).start();
}
};
return (
<Modal transparent visible={showModal}>
<View style={Styles.modalBackGround}>
<Animated.View
style={[Styles.modalContainer, {transform: [{scale: scaleValue}]}]}>
{children}
</Animated.View>
</View>
</Modal>
);
};
const Styles = StyleSheet.create({
modalBackGround: {
flex: 1,
backgroundColor: 'rgba(0,0,0,0.5)',
justifyContent: 'center',
alignItems: 'center',
},
modalContainer: {
width: '80%',
backgroundColor: 'white',
paddingHorizontal: 20,
paddingVertical: 30,
borderRadius: 20,
elevation: 20,
},
header: {
width: '100%',
height: 40,
alignItems: 'flex-end',
justifyContent: 'center',
},
});
export default CustomDialog;