在React Native中使用自定义数字键盘并移动到下一个TextInput

cnh2zyt3  于 2023-04-22  发布在  React
关注(0)|答案(1)|浏览(135)

我在做什么

一个管理学生SAT和GRE成绩列表的Web应用程序。一个学生有三个TextInputs,分别代表学生的姓名,他们的SAT和GRE成绩。

我想要实现的

1.通过按屏幕上的自定义数字键盘将分数输入到TextInput。
1.通过按下下一个按钮移动到下一个TextInput。当用户到达底部时,它什么也不做。

问题

1.我需要为每个TextInput使用onFocus()。如果有一个全局变量来存储当前焦点对象,那就太好了。
1.当我按下“下一步”按钮时,焦点不会移动到下一个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并搜索了谷歌这个问题。他们帮了我很多,我写了上面的代码,但不能完全解决这个问题。
任何帮助或意见将不胜感激。谢谢。

8fsztsew

8fsztsew1#

我自己修复了代码。

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,
  },
});

相关问题