TextInput_文本处理

傅茂实
2023-12-01

 React Native 学习随笔,有不同意见尽情发表!

1简单的例

import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, View } from 'react-native';

class PizzaTranslator extends Component {
   constructor(props) {
super(props);
    this.state = {text: ''};
  }

  endEditing(param) {
     alert(param)
  }

  submiteContext(param) {
     alert(param)
  }

  render() {
    return (
      <View style={{padding: 10}}>
        <TextInput
          style={styles.textIPStyle}
          placeholder="Type here to translate!"
          onChangeText={(text) => this.setState({text})}
          keyboardType = "numeric"
          multiline = {true}
          numberOfLines = {2}
          //设置键类型
          returnKeyType={'done'}
          clearButtonMode={'while-editing'} // 输入框右边 x 按钮
          underlineColorAndroid ={"transparent"} 
          onEndEditing={(event) => this.endEditing( // 退出键盘
                    'onEndEditing text: ' + event.nativeEvent.text)}
          onSubmitEditing={(event) => this.submiteContext( // 数据提交
                    'onSubmitEditing text: ' + event.nativeEvent.text)}
        />
        <Text style={{padding: 10, fontSize: 42}}>
          {this.state.text.split(' ').map((word) => word && '��').join(' ')}
        </Text>
         <Text></Text>
      </View>
    );
  }
}// 注册应用(registerComponent)后才能正确渲染// 注意:只把应用作为一个整体注册一次,而不是每个组件/模块都注册AppRegistry.registerComponent('PizzaTranslator', () => PizzaTranslator);
  上面代码, (text) => this .setState({text}) 是箭头函数,参数是text,代码块设置TextInput变化后的值, 再来看这行代码{ this .state.text.split( ' ' ).map((word) => word && '��' ).join( ' ' )}, split()方法把字符串text以 ' ' 分割为数组,map是迭代器遍历这个数组,
(word) => word &&  '��'的作用是把数组的每个元素替代为'��'。
假如我们要实现当用户输入时,实时将其以单词为单位翻译为另一种文字。我们假设这另一种文字来自某个吃货星球,只有一个单词: ��。所以"Hello there Bob"将会被翻译为"������"。

2 TextInput几个重要属性

keyboardType enum("default", 'numeric', 'email-address', "ascii-capable", 'numbers-and-punctuation', 'url', 'number-pad', 'phone-pad', 'name-phone-pad', 'decimal-pad', 'twitter', 'web-search') 

决定弹出的何种软键盘的,譬如numeric(纯数字键盘)。

这些值在所有平台都可用:

  • default
  • numeric
  • email-address
使用:
keyboardType = "numeric"

maxLength number 

限制文本框中最多的字符数。使用这个属性而不用JS逻辑去实现,可以避免闪烁的现象。

maxLength = {10}

multiline bool (直接使用无效果)参考例2

如果为true,文本框中可以输入多行文字。默认值为false。

numberOfLines number (直接使用无效果)参考例2

设置输入框的行数。当multiline设置为true时使用它,可以占据对应的行数

secureTextEntry bool 

如果为true,文本框会遮住之前输入的文字,这样类似密码之类的敏感文字可以更加安全。默认值为false

placeholder:占位符,在输入前显示的文本内容


value:文本输入框的默认值


autoCapitalize :首字母自动大写。可选值有: none sentences words characters

underlineColorAndroid string 

文本框的下划线颜色(译注:如果要去掉文本框的边框,请将此属性设为透明transparent)



3 常见的几个方法

onChangeText function 

当文本框内容变化时调用此回调函数。改变后的文字内容会作为参数传递

constructor(props) {
    super(props);
    this.state = {text: ''};
  }
onChangeText={(text) => this.setState({text})}

onEndEditing function 

当文本输入结束后调用此回调函数

endEditing(param) {
        alert(param)
    }
 onEndEditing={(event) => this.endEditing( // 退出键盘
                    'onEndEditing text: ' + event.nativeEvent.text
                )}

onSubmitEditing function 

此回调函数当软键盘的确定/提交按钮被按下的时候调用此函数。如果multiline={true},此属性不可用

submiteContext(param) {
        alert(param)
    }
onSubmitEditing={(event) => this.submiteContext( // 数据提交
                    'onSubmitEditing text: ' + event.nativeEvent.text
                )}


3实例

例1 状态变化

var TextEventsExample = React.createClass({

  //这个是Es5中的方法 初始化状态  
  // getInitialState 方法用于定义初始状态,也就是一个对象,
  //这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件                                         
  getInitialState: function() {
    return {
      //记录当前状态
      curText: '<No Event>',
      //记录前一个状态
      prevText: '<No Event>',
      //记录前前一个状态
      prev2Text: '<No Event>',
    };
  },

  updateText: function(text) {
    this.setState((state) => {
      return {
        curText: text,
        prevText: state.curText,
        prev2Text: state.prevText,
      };
    });
  },

  render: function() {
    return (
      <View>
        <TextInput
          //不自动切换任何字符为大写
          autoCapitalize="none"
          //占位符
          placeholder="Enter text to see events"
          //关闭拼写自动修正
          autoCorrect={false}
          //当文本框获得焦点的时候调用此回调函数
          onFocus={() => this.updateText('onFocus')}
          //当文本框失去焦点的时候调用此回调函数
          onBlur={() => this.updateText('onBlur')}
          //当文本框内容变化时调用此回调函数
          onChange={(event) => this.updateText(
            'onChange text: ' + event.nativeEvent.text
          )}
          //当文本输入结束后调用此回调函数
          onEndEditing={(event) => this.updateText(
            'onEndEditing text: ' + event.nativeEvent.text
          )}
          //此回调函数当软键盘的确定/提交按钮被按下的时候调用此函数。如果multiline={true},此属性不可用
          onSubmitEditing={(event) => this.updateText(
            'onSubmitEditing text: ' + event.nativeEvent.text
          )}
          style={styles.singleLine}
        />
        <Text style={styles.eventLabel}>
          {this.state.curText}{'\n'}
          (prev: {this.state.prevText}){'\n'}
          (prev2: {this.state.prev2Text})
        </Text>
        <Text></Text>
      </View>
    );
  }
});

这里牵涉到getInitialState 

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。

React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。

以下实例中创建了 LikeButton 组件,getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。

上面的updateText也可以改成如下:

updateText: function(text) {
    this.setState({
        curText: text,
        prevText: this.state.curText,
        prev2Text: this.state.prevText,
    });
  },
例2 换行
class AutoExpandingTextInput extends React.Component {
  constructor(props) {
    super(props);
    //初始化状态 
    this.state = {text: '', height: 0};
  }

  render() {
    return (
      <TextInput
        {...this.props}
        multiline={true}
        onChange={(event) => {
          //修改文本 和高度 每次修改状态时,React都重新渲染UI,使用户的状态和数据保持一致
          this.setState({
            text: event.nativeEvent.text,
            height: event.nativeEvent.contentSize.height,
          });
        }}
        style={[styles.default, {height: Math.max(35, this.state.height)}]}
        value={this.state.text}
      />
    );
  }
}
上面的代码, event.nativeEvent.text 是获取TextInPut文本, event.nativeEvent.contentSize.height 获取TextInPut 的高度。
例3 限制输入
class RewriteExample extends React.Component {
  constructor(props) {
    super(props);
    //初始化状态
    this.state = {text: ''};
  }
  render() {
    //字符限制数量
    var limit = 20;
    //剩余的可输入的字符
    var remainder = limit - this.state.text.length;
    //如果剩余可输入的字符数少于5 显示红色否则显示蓝色
    var remainderColor = remainder > 5 ? 'blue' : 'red';
    return (
      <View style={styles.rewriteContainer}>
        <TextInput
          multiline={false}
          maxLength={limit}
          onChangeText={(text) => {
           //如果输入的是空格 则使用 '_' 替换
            text = text.replace(/ /g, '_');
            this.setState({text});
          }}
          style={styles.default}
          value={this.state.text}
        />
        <Text
         style={[styles.remainder, {color: remainderColor}]}>
          {remainder}
        </Text>
        <Text></Text>
      </View>
    );
  }
}

例4 输入空格+#字符变为蓝色
hashtag: {
    color: 'blue',
    fontWeight: 'bold',
  },
class TokenizedTextExample extends React.Component {
  constructor(props) {
    super(props);
    this.state = {text: 'Hello #World'};
  }
  render() {

    //define delimiter 正则表达式  查找空白字符
    let delimiter = /\s+/;

    //split string
    let _text = this.state.text;
    let token, index, parts = [];
    while (_text) {
      // lastIndex 一个整数,标示开始下一次匹配的字符位置               
      delimiter.lastIndex = 0;
      //检索字符串中指定的值。返回找到的值,并确定其位置 [" ", index: 5, input: "Hello #World"] 
      // " " 是返回找到的值 index 是字符" " 所在的位置   属性input 被查找的字符串
      token = delimiter.exec(_text);
      //如果没有查找到就中断查找
      if (token === null) {
        break;
      }
      //字符" " 所在的位置
      index = token.index;
      if (token[0].length === 0) {
          index = 1;
      }
      //向数组的末尾添加一个或更多元素,并返回新的长度
      parts.push(_text.substr(0, index));
      parts.push(token[0]);
      console.log(parts);//["Hello", " "]
      index = index + token[0].length;
      //提取字符串的某个部分,并以新的字符串返回被提取的部分 语法 str.slice(start,end)  
     // 返回一个新的字符串,包含从 start 到 end (不包括该元素)的 str 中的元素
      _text = _text.slice(index);
    }
    
    parts.push(_text);
    console.log(parts);//["Hello", " ", "#World"]
    //highlight hashtags
    parts = parts.map((text) => {
      if (/^#/.test(text)) {//检索字符串中指定的值。返回 true 或 false
        return <Text key={text} style={styles.hashtag}>{text}</Text>;
      } else {
        return text;
      }
    });

    return (
      <View>
        <TextInput
          multiline={true}
          style={styles.multiline}
          onChangeText={(text) => {
            this.setState({text});
          }}>
          <Text>{parts}</Text>
        </TextInput>
      </View>
    );
  }
}
Input:
Hello #Eirc next to meet you !
output:
Hello  #Eirc next to meet you !
上面的代码中有几个方法需要注意下:
/\s+/  正则表达式查找空格字符  
/^#/ 正则表达式查找 #
re.exec(str)  根据正则表达式查找字符串 返回找到的值 和其位置 re是正则表达式对象 str是被查找的对象 例: [" ", index: 5, input: "Hello #World"]
re.test (str) 检索字符串中是否包含默个字符,返回 true 或 false 了解 更多
str.slice(start,end) 从旧的字符串中提取一个新的字符串,start 开始的位置 end 结束的位置

自学资料:


















 类似资料: