为什么在每次击键后关闭我的键盘?
Why closes my keyboard after every keystroke?
我正在为某些算法开发应用程序。类似“问题”的内容,如果是,则为 x,如果否,则为 y。有些我创建了一个组件,用于单个算法步骤。
有些答案不仅是是或否,所以我在我的组件中添加了一个可选的文本输入。如果尽可能在算法“TextInput”中给出答案,则应该有一个 TextInput 元素和一个 Button 就可以了。单击“确定”后,TextInput 应变为固定文本。但是每次击键后键盘都会关闭。
我发现,在向 TextInput 添加值和 onTextChanged 之后,这个行为开始了。但在其他项目中,我的工作方式完全相同。为什么?有人可以帮忙吗?
这是我的组件代码:
import { AutoSizeText, ResizeTextMode } from 'react-native-auto-size-text';
import { Dimensions, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { useState } from 'react';
export default function SingleAlgorithmStep(props) {
const step = props.step; //Inhalt des akutell auszuführenden Schritts
const stepsDone = props.stepsDone; //Array mit bereits erledigten Schritten
const clickedButtons = props.clickedButtons; //Array mit den bereits ausgewählten Buttons
const currentAlgorithmJson = props.algorithmJson; //Aktuellen Algorithmus von den Props auslesen
const [textInputValue, changeTextInput] = useState('');
let buttons = []; //Array, was die Texte und die Anzahl der Buttons für diesen Step beinhaltet
var buttonWidth = (Dimensions.get('window').width - 20); //Breite eines Buttons entspricht der Bildschirmbreite abzüglich Rand
if (Object.keys(step["Action"]).length > 1) {
buttonWidth = (buttonWidth - (Object.keys(step["Action"]).length - 1) * 10) / Object.keys(step["Action"]).length;
} //Falls mehrere Buttons vorhanden sind, soll zwischen den Buttons etwas Platz sein und trotzdem sollen alle gleich groß sein
for (const buttonText in step["Action"]) {
const id = step["Question"] + " : " + buttonText; //Einmalige ID erzeugen
buttons = buttons.concat(
<TouchableOpacity key={id} style={[styles.button, { width: buttonWidth, backgroundColor: clickedButtons.includes(id) ? "limegreen" : "dodgerblue" }]} onPress={() => {
if (clickedButtons.filter(oldId => oldId.includes(step["Question"])).length > 0) {
//Falls auf einen bereits erledigten Schritt zurückgegangen wird...
props.actualizeButtons(clickedButtons.splice(0, stepsDone.indexOf(step)).concat(id)); //Gewählte Buttons werden bis zum Index des Schrittes beibehalten und der neue Button wird ergänzt
props.actualizeSteps(stepsDone.splice(0, stepsDone.indexOf(step) + 1).concat(currentAlgorithmJson[step["Action"][buttonText]])); //Schritte werden bis zum Index des aktuellen Steps beibehalten und der nächste Schritt ergänzt
}
else {
props.actualizeButtons(clickedButtons.concat(id)); //ID zum Array hinzufüge, um angeklickte Buttons zu markieren
props.actualizeSteps(stepsDone.concat(currentAlgorithmJson[step["Action"][buttonText]])); //Nächsten Schritt einfügen
}
}}>
<AutoSizeText style={[styles.buttonText, { width: buttonWidth }]} fontSize={18} minFontSize={18} numberOfLines={3} mode={ResizeTextMode.min_font_size}>{buttonText === "TextInput" ? "Ok" : buttonText}</AutoSizeText>
</TouchableOpacity>
);
} //Jeden Button aus dem JSON als Element zur Liste hinzufügen, um so dynamisch die Anzahl der Button und den Button Text zu regulieren
return (
<View style={{ marginBottom: 15 }}>
<AutoSizeText style={styles.Question} fontSize={24} minFontSize={21} numberOfLines={5} mode={ResizeTextMode.min_font_size}>{step["Question"]}</AutoSizeText>
{Object.keys(step["Action"]).includes("TextInput") ? !clickedButtons.includes(step["Question"] + " : " + "TextInput") ? <TextInput key={Math.random()} style={styles.input} value={textInputValue} onChangeText={(textInputValue) => changeTextInput(textInputValue)} placeholder={step["Question"]}></TextInput> : <Text>{textInputValue}</Text> : null}
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
{buttons}
</View>
</View>
)
}
const styles = StyleSheet.create({
Question: {
width: Dimensions.get('window').width - 20,
minHeight: 40,
borderColor: 'black',
borderWidth: 2,
textAlign: 'center',
},
input: {
borderWidth: 1,
borderColor: 'black',
width: '100%',
fontSize: 18,
padding: 5,
marginTop: 5,
},
button: {
marginTop: 10,
minHeight: 30,
justifyContent: 'space-around'
},
buttonText: {
textAlign: 'center',
color: 'white',
minHeight: 30,
textAlignVertical: 'center'
}
});
当 TextInput 是可滚动组件的子组件时,这是默认行为,ScrollView
、FlatList
或 SectionList
.
使键盘始终保持点击如下:
<FlatList
keyboardShouldPersistTaps="always"
//...otherProps
/>
然后删除设置为Math.random()
的key
属性。随机数值对于每次重新渲染都是动态的,不会提供任何性能优势。
<TextInput
//key={Math.random()} - Key should not be random number
style={styles.input}
value={textInputValue}
onChangeText={(textInputValue) => changeTextInput(textInputValue)}
placeholder={step["Question"]}
/>;
我正在为某些算法开发应用程序。类似“问题”的内容,如果是,则为 x,如果否,则为 y。有些我创建了一个组件,用于单个算法步骤。
有些答案不仅是是或否,所以我在我的组件中添加了一个可选的文本输入。如果尽可能在算法“TextInput”中给出答案,则应该有一个 TextInput 元素和一个 Button 就可以了。单击“确定”后,TextInput 应变为固定文本。但是每次击键后键盘都会关闭。
我发现,在向 TextInput 添加值和 onTextChanged 之后,这个行为开始了。但在其他项目中,我的工作方式完全相同。为什么?有人可以帮忙吗?
这是我的组件代码:
import { AutoSizeText, ResizeTextMode } from 'react-native-auto-size-text';
import { Dimensions, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { useState } from 'react';
export default function SingleAlgorithmStep(props) {
const step = props.step; //Inhalt des akutell auszuführenden Schritts
const stepsDone = props.stepsDone; //Array mit bereits erledigten Schritten
const clickedButtons = props.clickedButtons; //Array mit den bereits ausgewählten Buttons
const currentAlgorithmJson = props.algorithmJson; //Aktuellen Algorithmus von den Props auslesen
const [textInputValue, changeTextInput] = useState('');
let buttons = []; //Array, was die Texte und die Anzahl der Buttons für diesen Step beinhaltet
var buttonWidth = (Dimensions.get('window').width - 20); //Breite eines Buttons entspricht der Bildschirmbreite abzüglich Rand
if (Object.keys(step["Action"]).length > 1) {
buttonWidth = (buttonWidth - (Object.keys(step["Action"]).length - 1) * 10) / Object.keys(step["Action"]).length;
} //Falls mehrere Buttons vorhanden sind, soll zwischen den Buttons etwas Platz sein und trotzdem sollen alle gleich groß sein
for (const buttonText in step["Action"]) {
const id = step["Question"] + " : " + buttonText; //Einmalige ID erzeugen
buttons = buttons.concat(
<TouchableOpacity key={id} style={[styles.button, { width: buttonWidth, backgroundColor: clickedButtons.includes(id) ? "limegreen" : "dodgerblue" }]} onPress={() => {
if (clickedButtons.filter(oldId => oldId.includes(step["Question"])).length > 0) {
//Falls auf einen bereits erledigten Schritt zurückgegangen wird...
props.actualizeButtons(clickedButtons.splice(0, stepsDone.indexOf(step)).concat(id)); //Gewählte Buttons werden bis zum Index des Schrittes beibehalten und der neue Button wird ergänzt
props.actualizeSteps(stepsDone.splice(0, stepsDone.indexOf(step) + 1).concat(currentAlgorithmJson[step["Action"][buttonText]])); //Schritte werden bis zum Index des aktuellen Steps beibehalten und der nächste Schritt ergänzt
}
else {
props.actualizeButtons(clickedButtons.concat(id)); //ID zum Array hinzufüge, um angeklickte Buttons zu markieren
props.actualizeSteps(stepsDone.concat(currentAlgorithmJson[step["Action"][buttonText]])); //Nächsten Schritt einfügen
}
}}>
<AutoSizeText style={[styles.buttonText, { width: buttonWidth }]} fontSize={18} minFontSize={18} numberOfLines={3} mode={ResizeTextMode.min_font_size}>{buttonText === "TextInput" ? "Ok" : buttonText}</AutoSizeText>
</TouchableOpacity>
);
} //Jeden Button aus dem JSON als Element zur Liste hinzufügen, um so dynamisch die Anzahl der Button und den Button Text zu regulieren
return (
<View style={{ marginBottom: 15 }}>
<AutoSizeText style={styles.Question} fontSize={24} minFontSize={21} numberOfLines={5} mode={ResizeTextMode.min_font_size}>{step["Question"]}</AutoSizeText>
{Object.keys(step["Action"]).includes("TextInput") ? !clickedButtons.includes(step["Question"] + " : " + "TextInput") ? <TextInput key={Math.random()} style={styles.input} value={textInputValue} onChangeText={(textInputValue) => changeTextInput(textInputValue)} placeholder={step["Question"]}></TextInput> : <Text>{textInputValue}</Text> : null}
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
{buttons}
</View>
</View>
)
}
const styles = StyleSheet.create({
Question: {
width: Dimensions.get('window').width - 20,
minHeight: 40,
borderColor: 'black',
borderWidth: 2,
textAlign: 'center',
},
input: {
borderWidth: 1,
borderColor: 'black',
width: '100%',
fontSize: 18,
padding: 5,
marginTop: 5,
},
button: {
marginTop: 10,
minHeight: 30,
justifyContent: 'space-around'
},
buttonText: {
textAlign: 'center',
color: 'white',
minHeight: 30,
textAlignVertical: 'center'
}
});
当 TextInput 是可滚动组件的子组件时,这是默认行为,ScrollView
、FlatList
或 SectionList
.
使键盘始终保持点击如下:
<FlatList
keyboardShouldPersistTaps="always"
//...otherProps
/>
然后删除设置为Math.random()
的key
属性。随机数值对于每次重新渲染都是动态的,不会提供任何性能优势。
<TextInput
//key={Math.random()} - Key should not be random number
style={styles.input}
value={textInputValue}
onChangeText={(textInputValue) => changeTextInput(textInputValue)}
placeholder={step["Question"]}
/>;