折叠输入框(组)
需求描述:
希望在输入框收起时能够直接按照username@host:port的格式输入,在展开时能够自动将输入拆分为username、host、port显示在子输入框,且能够在顶部的输入框同步子输入框组输入数据的拼合值;此外还需要处理输入为空或不符合格式的特殊情况。
实现如下:
const [combine, onChangeCombine] = React.useState("");
const [username, onChangeUsername] = React.useState("");
const [host, onChangeHost] = React.useState("");
const [port, onChangePort] = React.useState("");
const [isMenuVisible_Setting, setIsMenuVisible_Setting] = useState(false);
const handleSet_Setting = () => {
if (!isMenuVisible_Setting) { //如果要展开:拆分输入值,在子输入框中展示
const parts = combine.split(/[@:]/);
onChangeUsername(parts[0] || "");
onChangeHost(parts[1] || "");
onChangePort(parts[2] || "");
} else if(username||host||port) //如果要收起,且子输入框不全为空:拼合输入值
onChangeCombine(username + "@" + host + ":" + port);
else onChangeCombine(""); //如果要收起,且子输入框为空:设为空
setIsMenuVisible_Setting(!isMenuVisible_Setting);
};
<View style={styles.item}>
<View style={{ display: "flex", flexDirection: "column", width: "100%" }}>
<View style={styles.accordionContainer}>
<View style={styles.accordionHeader}>
<TextInput
style={styles.input}
onChangeText={text => {onChangeCombine(text)}}
value={isMenuVisible_Setting ? (username || host || port ? username + "@" + host + ":" + port : "") : combine}
placeholder={"用户名@主机:端口"}
editable={!isMenuVisible_Setting} /*展开时顶部输入框不可编辑,显示临时拼合值*/
/>
<TouchableOpacity activeOpacity={0.5} onPress={handleSet_Setting} style={styles.arrow}>
<Text style={{ fontSize: 20 }}>{isMenuVisible_Setting ? "▲" : "▼"}</Text>
</TouchableOpacity>
</View>
{isMenuVisible_Setting && <View style={styles.accordionContent}>
{<><TextInput
style={styles.input}
onChangeText={text => onChangeUsername(text)}
value={username || ""}
placeholder={"用户名"}
/><TextInput
style={styles.input}
onChangeText={text => onChangeHost(text)}
value={host || ""}
placeholder={"主机"}
/><TextInput
style={styles.input}
onChangeText={text => onChangePort(text)}
value={port || ""}
placeholder={"端口"}
/></>}
</View>}
</View>
</View>
</View>
const screenWidth = Dimensions.get("window").width;
const styles = StyleSheet.create({
item: {
minHeight: 80,
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
borderBottomWidth: 1,
borderBottomColor: "black",
},
input: {
height: 50,
width: screenWidth - 60,
margin: 5,
lineHeight: 25,
borderColor: "gray",
borderWidth: 1,
},
accordionContainer: {
overflow: "hidden"
},
accordionHeader: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
padding: 10
},
accordionContent: {
padding: 10,
backgroundColor: "#ffffff"
},
arrowContainer: {
width: "auto",
position: "absolute",
right: 0,
display: "flex",
fontSize: 20,
},
arrow: {
position: "absolute",
fontSize: 20,
marginTop: -10,
right: 15,
},
});
效果示例:(样式经过美化)