React Native学习组件之TextInput

Demo展示

RNTextInput.gif

搜索框自动提示。此demo分为两部分,第一是我们自定义输入框,RN默认的输入框不是很美观;第二个是自动列表提示。demo比较简单,我们快速的来实现它吧。

自定义输入框

在根目录上新建一个search.js文件

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

var onePT = 1 / PixelRatio.get();

class SearchComponent extends Component {

    render() {
        return (
            <View style={styles.flex}>
                <View style={[styles.inputHeight, styles.flexDirection]}>
                    <View style={[styles.flex, styles.input]}>
                        <TextInput
                            //这里表示输入自带的下划线颜色透明
                            underlineColorAndroid={'transparent'}
                        />
                    </View>
                    <View style={styles.btn }>

                        <Text >搜索</Text>
                    </View>
                </View>

            </View>
        );
    }

}

const styles = StyleSheet.create({

    flex: {
        flex: 1
    },

    flexDirection: {
        flexDirection: 'row'
    },
    input: {
        borderWidth: 1,
        marginLeft: 5,
        paddingLeft: 5,
        borderColor: '#ccc',
        justifyContent: 'center',
        borderRadius: 4
    },
    inputHeight: {
        height: 45
    },
    btn: {
        width: 55,
        marginLeft: -5,
        marginRight: 5,
        backgroundColor: '#23beff',
        justifyContent: 'center',
        alignItems: 'center',
        borderBottomRightRadius: 4,
        borderTopRightRadius: 4
    },
    result: {

        marginLeft: 5,
        marginRight: 5,
        height: 200,
        borderColor: '#ccc',
        borderBottomWidth: 1,
        borderRightWidth: 1,
        borderLeftWidth: 1
    },
    resultItem: {
        fontSize: 16,
        paddingLeft: 10,
        paddingTop: 10,
        paddingBottom: 10,
        borderWidth: onePT,
        borderColor: '#ddd'

    },

    resultItemBottomLine: {
        borderBottomWidth: onePT,
        borderColor: '#ddd',
    }
});
module.exports = SearchComponent;

我们在index.android.js文件里面使用它

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

var SearchComponent = require('./search');

class RNTextInput extends Component {
    render() {
        return (
            <View style={[styles.flex, styles.topStatus]}>

                <SearchComponent/>

            </View>
        );
    }
}

const styles = StyleSheet.create({
    flex: {
        flex: 1
    },
    topStatus: {
        marginTop: 25
    }
});

AppRegistry.registerComponent('RNTextInput', () => RNTextInput);

效果如下:

serach_1.png

自动提示列表

  • TextInput常用属性

    • returnKeyType

      因为这里的使用场景是搜索,所我们虚拟键盘的返回键是search

    • placeholder

      显示在输入前的占位符,如“请输入关键字”。有点像Android中EditText中的hint提示

    • value

      通过this.state.value修改TextInput的value的变化

    • onEndEditing

      用户结束编辑时触发该事件,会将this.state.value写入。这样,就能在搜索框中显示该值

    • onChangeText

      监听输入框值的变化,onChangeText获取的值作为字符串传入

  • 代码实现

在serach.js文件添加一些代码

...

var onePT = 1 / PixelRatio.get();

class SearchComponent extends Component {

    //我们可以在构造方法中进行初始化
    constructor(props) {
        super(props);
        this.state = {
            show: false,
        };
    }

    /**
     * 显示搜索结果
     * @param result
     */
    showResult(result) {
        var result = result;
        this.setState({
            show: true,
            value: result
        });
    }

    /**
     * 隐藏搜索结果
     * @param result
     */
    hideResult(result) {
        this.setState({
            show: false,
            value: result
        });
    }   
    render() {
        return (
            <View style={styles.flex}>
                <View style={[styles.inputHeight, styles.flexDirection]}>
                    <View style={[styles.flex, styles.input]}>
                        <TextInput
                            underlineColorAndroid={'transparent'}
                            returnKeyType="search"
                            placeholder="请输入关键字"
                            onChangeText={(text)=>this.showResult(text)}
                            value={this.state.value}
                            onEndEditing={(text)=>this.hideResult({text})}
                        />
                    </View>
                    <View style={styles.btn }>

                        <Text onPress={()=>this.hideResult(this.state.value)}>搜索</Text>
                    </View>
                </View>

                { this.state.show ?
                    <View style={styles.result}>
                        <View style={[styles.resultItemBottomLine, styles.flex]}>
                            <Text style={[styles.resultItem]}
                                  numberOfLines={1}
                                  onPress={this.hideResult.bind(this, this.state.value + '超市')}>
                                {this.state.value}超市
                            </Text>
                        </View>

                        <View style={[styles.resultItemBottomLine, styles.flex]}>
                            <Text style={styles.resultItem}
                                  numberOfLines={1}
                                  onPress={this.hideResult.bind(this, this.state.value + '道路')}>
                                {this.state.value}道路
                            </Text>
                        </View>

                        <View style={[styles.resultItemBottomLine, styles.flex]}>
                            <Text style={[styles.resultItem]}
                                  numberOfLines={1}
                                  onPress={this.hideResult.bind(this, this.state.value + '综合商店')}>
                                {this.state.value}综合商店
                            </Text>
                        </View>

                        <View style={[styles.resultItemBottomLine, styles.flex]}>
                            <Text style={[styles.resultItem]}
                                  numberOfLines={1}
                                  onPress={this.hideResult.bind(this, this.state.value + '医院')}>
                                {this.state.value}医院
                            </Text>
                        </View>

                        <View style={[styles.flex]}>
                            <Text style={[styles.resultItem]}
                                  numberOfLines={1}
                                  onPress={this.hideResult.bind(this, this.state.value + '美容院')}>
                                {this.state.value}美容院
                            </Text>
                        </View>
                    </View>
                    : null
                }
            </View>
        );
    }

}

... 

运行效果如下:

search_2.png

总结

我们通过判断this.state.show来确定是否显示结果列表。如果this.state.show是true,则显示。如果是false,则隐藏(null对象不显示)。

结果列表的规则是:输入关键字+预设关键字。这是我们模拟服务端传过来的数据。同时,点击结果列表中的某一项,应该隐藏列表并且将结果显示在输入框中。onPress={this.hideResult.bind(this, this.state.value + '超市')}就是当用户点击时,将字符传结果输入的到hide方法中。在js中,调用有参数的方法,我们可以使用bind方法来传参。

hide方法很简单,就是将this.state.show设置为false,这样会将结果列表隐藏起来了。因为状态的改变引起了视图的重新渲染,遇到this.state.show为false,就不渲染结果列表了。

好了,我们的TextInput组件就学习完了,若有不对之处,还请告知。谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容