我在做什么
管理学生SAT和GRE成绩列表的web应用程序。一个学生有三个textput,分别代表学生的姓名、SAT和GRE成绩。
我想要实现的
- 通过按屏幕上的自定义numpad输入分数到TextInput。
- 移动到下一个文本输入按下一个按钮。当用户到达底部时,它不做任何事情。
- 我需要为每个TextInput使用
onFocus()
。如果有一个全局变量存储当前聚焦的对象,那就太好了。 - 当我按下一个按钮时,焦点不会移动到下一个TextInput。
我写的代码
如果它不工作,尝试:https://snack.expo.dev/@dixhom/sat_gre_score_test
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div data-snack-id="@dixhom/sat_gre_score_test" data-snack-platform="web" data-snack-preview="true" data-snack-theme="light" style="overflow:hidden;background:#F9F9F9;border:1px solid var(--color-border);border-radius:4px;height:505px;width:100%"></div>
<script async src="https://snack.expo.dev/embed.js"></script>
<标题>研究我问ChatGPT和谷歌搜索这个问题。他们帮了我很大的忙,我写了上面的代码,但不能完全解决这个问题。
任何帮助或评论将不胜感激。谢谢你。
标题>我自己修复了代码。
import React, { useRef, useState } from 'react';
import { Text, View, StyleSheet, TextInput, Button } from 'react-native';
import Constants from 'expo-constants';
export default function App() {
const inputs = useRef([]);
let currentFocus = null;
// initializing inputs
for (let i = 0; i < 3; i++) {
inputs.current[i] = []; // initialize inputs.current[i] as an empty array
for (let j = 0; j < 3; j++) {
inputs.current[i][j] = null;
}
}
const NUM_ROWS = 3; // replace N with the number of View tags
const NUM_COLS = 3; // replace M with the number of TextInputs in each View
// When you press the next button, move the focus
const handlePress = () => {
for (let i = 0; i < NUM_ROWS; i++) {
for (let j = 0; j < NUM_COLS; j++) {
if (inputs.current[i][j] === currentFocus) {
if (j < NUM_COLS - 1) {
inputs.current[i][j + 1].focus();
} else if (i < NUM_ROWS - 1) {
inputs.current[i + 1][0].focus();
}
else
inputs.current[i][j].focus();
return
}
}
}
};
// when you press the number button, insert a number to the TextInput
const handleInsertNumber = (number) => {
console.log("insert num!");
for (let i = 0; i < NUM_ROWS; i++) {
for (let j = 0; j < NUM_COLS; j++) {
if (inputs.current[i][j] === currentFocus) {
inputs.current[i][j].value += number.toString();
return;
}
}
}
};
// values for each TextInput
recordInfos = [
{"placeholder": "name", "editable": false},
{"placeholder": "Input SAT score", "editable": true},
{"placeholder": "Input GRE score", "editable": true},
];
// each group of TextInputs
const records = [...Array(NUM_ROWS)].map((_, i) => (
<View key={i} style={styles.score}>
{[...Array(NUM_COLS)].map((_, j) => (
<TextInput
key={j}
placeholder={recordInfos[j]["placeholder"]}
style={styles.scoreInput}
ref={ref => (inputs.current[i][j] = ref)}
onSubmitEditing={handlePress}
onFocus={() => currentFocus = inputs.current[i][j]}
editable={recordInfos[j]["editable"]}
/>
))}
</View>
));
// number buttons
const numbers = Array.from(Array(10).keys());
const numberButtons = numbers.map((number) => (
<View style={styles.numberButton}>
<Button title={number} key={number} onPress={() => handleInsertNumber(number)}/>
</View>
));
return (
<View style={styles.container}>
{records}
<View style={{ flexDirection: "row", }}>
{numberButtons}
</View>
<Button title="Next" onPress={() => handlePress()}/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
score: {
margin: 10,
padding: 10,
fontSize: 18,
borderColor: 'gray',
borderWidth: 5,
backgroundColor: 'orange',
},
scoreInput: {
borderColor: "gray",
borderWidth: 1,
padding: 3,
margin: 3,
backgroundColor: "white",
},
numberButton: {
margin: 3,
},
});