React Native替换已弃用ListItem及布局与功能优化问题
Hey there! I see you've migrated to Native Base after React Native's ListItem got deprecated, and you're dealing with two small issues—let's fix them up together.
Fixing the Right-Aligned Arrow in CardItem
The arrow isn't sticking to the far right because the default CardItem layout isn't leveraging flexbox correctly. We'll adjust the CardItem's style to split content into left/right sections, ensuring the arrow stays aligned to the right edge.
Creating Editable Label-Value List Items with Modal
We'll add state to track tenant info, modal visibility, and the current field being edited. Each list item will show a label and its corresponding value, and tapping it will open a modal to edit that value.
Here's your updated code with both fixes implemented:
import React, { Component } from 'react'; import { StyleSheet, View } from 'react-native'; import { Container, Header, Content, Card, CardItem, Text, Icon, Right, Left, Body, Title, Button, Modal, Input } from 'native-base'; import { Avatar } from 'react-native-elements'; class TenantDetails extends Component { state = { modalVisible: false, currentEditingField: '', tenantInfo: { firstName: 'John', lastName: 'Test', email: 'joinh@gmail.com', phone: 'xxx-xxx-xxxx' } }; openEditModal = (field) => { this.setState({ modalVisible: true, currentEditingField: field }); }; closeEditModal = () => { this.setState({ modalVisible: false }); }; saveEditedValue = () => { // Add your save logic here (e.g., API call, state persistence) this.closeEditModal(); }; render() { const { navigation } = this.props; const { tenantInfo, modalVisible, currentEditingField } = this.state; // Format field name for modal title (e.g., "firstName" → "First Name") const formattedFieldName = currentEditingField .replace(/([A-Z])/g, ' $1') .replace(/^./, str => str.toUpperCase()); return ( <Container> <Header> <Left> <Button transparent onPress={() => navigation.goBack()}> <Icon name='arrow-back' /> </Button> </Left> <Body> <Title>My Profile</Title> </Body> <Right /> </Header> <Content> <View style={styles.userRow}> <View style={styles.userImage}> <Avatar rounded size="large" source={{ uri: 'https://myirent.com/rent/appImg/person-icon.png', }} /> </View> <View> <Text style={{ fontSize: 16 }}>{`${tenantInfo.firstName} ${tenantInfo.lastName}`}</Text> <Text style={{ color: 'gray', fontSize: 16, }} > {tenantInfo.email}{'\n'}{tenantInfo.phone} </Text> </View> </View> <Card> <View style={styles.containerTextHeader}> <Text style={styles.infoTextHeader}>Tenant Details</Text> </View> {/* First Name Item */} <CardItem style={styles.listItem} onPress={() => this.openEditModal('firstName')} > <View style={styles.labelSection}> <Icon active name="person" style={styles.itemIcon} /> <Text style={styles.labelText}>First Name</Text> </View> <View style={styles.valueSection}> <Text style={styles.valueText}>{tenantInfo.firstName}</Text> <Icon name="arrow-forward" style={styles.rightArrow} /> </View> </CardItem> {/* Last Name Item */} <CardItem style={styles.listItem} onPress={() => this.openEditModal('lastName')} > <View style={styles.labelSection}> <Icon active name="person" style={styles.itemIcon} /> <Text style={styles.labelText}>Last Name</Text> </View> <View style={styles.valueSection}> <Text style={styles.valueText}>{tenantInfo.lastName}</Text> <Icon name="arrow-forward" style={styles.rightArrow} /> </View> </CardItem> {/* Email Item */} <CardItem style={styles.listItem} onPress={() => this.openEditModal('email')} > <View style={styles.labelSection}> <Icon active name="mail" style={styles.itemIcon} /> <Text style={styles.labelText}>Email</Text> </View> <View style={styles.valueSection}> <Text style={styles.valueText}>{tenantInfo.email}</Text> <Icon name="arrow-forward" style={styles.rightArrow} /> </View> </CardItem> {/* Phone Item */} <CardItem style={styles.listItem} onPress={() => this.openEditModal('phone')} > <View style={styles.labelSection}> <Icon active name="call" style={styles.itemIcon} /> <Text style={styles.labelText}>Phone</Text> </View> <View style={styles.valueSection}> <Text style={styles.valueText}>{tenantInfo.phone}</Text> <Icon name="arrow-forward" style={styles.rightArrow} /> </View> </CardItem> </Card> {/* Edit Modal */} <Modal isVisible={modalVisible} onBackdropPress={this.closeEditModal} style={styles.modal} > <View style={styles.modalContent}> <Text style={styles.modalTitle}>Edit {formattedFieldName}</Text> <Input value={tenantInfo[currentEditingField]} onChangeText={(text) => this.setState(prevState => ({ tenantInfo: { ...prevState.tenantInfo, [currentEditingField]: text } }))} style={styles.modalInput} autoFocus /> <View style={styles.modalButtonRow}> <Button light style={styles.modalButton} onPress={this.closeEditModal} > <Text>Cancel</Text> </Button> <Button primary style={styles.modalButton} onPress={this.saveEditedValue} > <Text>Save</Text> </Button> </View> </View> </Modal> </Content> </Container> ); } } const styles = StyleSheet.create({ userRow: { alignItems: 'center', flexDirection: 'row', paddingVertical: 6, paddingHorizontal: 15, }, userImage: { marginRight: 12, }, containerTextHeader: { paddingVertical: 12, backgroundColor: '#F4F5F4', }, infoTextHeader: { fontSize: 16, marginLeft: 20, color: 'gray', fontWeight: '500', }, // List Item Styles listItem: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: 8 }, labelSection: { flexDirection: 'row', alignItems: 'center', }, itemIcon: { marginRight: 10, color: '#666' }, labelText: { fontSize: 15, color: '#333' }, valueSection: { flexDirection: 'row', alignItems: 'center', }, valueText: { fontSize: 15, color: '#666', marginRight: 8 }, rightArrow: { color: '#999' }, // Modal Styles modal: { justifyContent: 'center', alignItems: 'center' }, modalContent: { width: '90%', backgroundColor: 'white', borderRadius: 8, padding: 20 }, modalTitle: { fontSize: 18, fontWeight: '500', marginBottom: 15 }, modalInput: { marginBottom: 20 }, modalButtonRow: { flexDirection: 'row', justifyContent: 'flex-end', gap: 10 }, modalButton: { borderRadius: 4 } }); export default TenantDetails;
Key Changes Explained:
Arrow Alignment:
- Added
justifyContent: 'space-between'tolistItemstyle, which pushes the label section left and value/arrow section right. - Wrapped icon+label and value+arrow in separate views for clean layout.
- Added
Editable Label-Value Items:
- Added state to track tenant info, modal visibility, and the current field being edited.
- Added
onPresshandlers to eachCardItemto trigger the modal. - Implemented a Native Base
Modalwith an input field to edit the selected value, plus save/cancel buttons. - Dynamic modal title that formats the field name for readability.
内容的提问来源于stack exchange,提问作者myTest532 myTest532

