前言
這篇文章來瞭解一下輸入框組件TextInput和按鈕Button的使用,並結合之前的Flexbox布局來搭建一個簡單的登入介面。
廢話不多說,先上效果圖。
輸入框組件TextInput
TextInput是一個允許使用者輸入文本的基礎組件。在Android中對應的就是EditText控制項。 屬性 autoCapitalize 控制TextInput是否要自動將特定字元切換為大寫。它的取值有以下4個enum:
'characters': 所有的字元。 'words': 每個單詞的第一個字元。 'sentences': 每句話的第一個字元(預設)。 'none': 不自動切換任何字元為大寫。 autoCorrect 如果為false,會關閉拼字自動修正。預設值是true。 autoFocus如果為true,在componentDidMount後會獲得焦點。預設值為false。 caretHidden如果為true,則隱藏游標。預設值為false defaultValue提供一個文字框中的初始值。當使用者開始輸入的時候,值就可以改變。 editable如果為false,文字框是不可編輯的。預設值為true。 maxLength 限制文字框中最多的字元數。使用這個屬性而不用JS邏輯去實現,可以避免閃爍的現象。 multiline如果為true,文字框中可以輸入多行文字。預設值為false。
當multiline=false時,為元素的某一個邊添加邊框樣式(例如:borderBottomColor,borderLeftWidth等)將不會生效。為了能夠實現效果你可以使用一個View來包裹TextInput。 placeholder 如果沒有任何文字輸入,會顯示此字串。(同Android中的hint) placeholderTextColor佔位字串顯示的文字顏色。 secureTextEntry 如果為true,文字框會遮住之前輸入的文字,這樣類似密碼之類的敏感文字可以更加安全。預設值為false。
下邊兩個屬性呢,在Android環境下使用,為了統一,可以與iOS端一致。 numberOfLines 設定輸入框的行數。當multiline設定為true時使用它,可以佔據對應的行數。 underlineColorAndroid 文字框的底線顏色(譯註:如果要去掉文字框的邊框,請將此屬性設為透明transparent)。
使用:underlineColorAndroid={'transparent'}
還有需要注意的地方就是:
①TextInput在安卓上預設有一個底邊框,同時會有一些padding。如果要想使其看起來和iOS上盡量一致,則需要設定padding: 0
②在安卓上如果設定multiline = {true},文本預設會垂直置中,可設定textAlignVertical: 'top'樣式來使其居頂顯示。
下邊是屬性值為function()的幾個屬性。
先說兩個最常用的onChangeText和onSubmitEditing。
onChangeText:屬性接受一個函數,而此函數會在文本變化時被調用,改變後的文字內容會作為參數傳遞。
這個屬性,在我們要讀取使用者輸入,得到輸入框內容的時候,會用到。(注意,從TextInput裡取值這就是目前唯一的做法。),具體的做法就是使用onChangeText寫入state,然後從this.state中取出值。,下邊的登入介面樣本中也會有,具體可以看下邊樣本。
onSubmitEditing:會在文本被提交後(使用者按下軟鍵盤上的提交鍵)調用。需要注意的是,如果multiline={true},此屬性不可用。
其他的屬性,這裡就不一一列舉了,用到的時候可以查看官方文檔。 按鈕Button
在RN v0.46版本,添加了<Button>組件,在此之前是沒有的。
我試了一下<Button>組件的使用,非常簡單:
<Button onPress={onPressed} title="Login" color="green" accessibilityLabel="Learn more about this button"/>
主要就是以上4個屬性:
- onPress:接收一個點擊事件function。
- title:按鈕要顯示的文字。
- color:按鈕的背景顏色(Android),文本的顏色(iOS)。
- accessibilityLabel:用於給殘障人士顯示的文本(比如讀屏器軟體可能會讀取這一內容)
就長這樣:
這裡有一個問題很奇葩,就是它不能自己設定寬高,更確切的說這個按鈕的高度是固定的,而寬度呢跟它的父容器的寬度一致。。。。寬高都不能自己設定,更別說我們設定它的樣式了。WTF。
不知道是不是我自己理解有誤。求指教。
所以,更多的時候,是需要我們自己定製需要的按鈕的。而不是用它這個<Button>組件。 定製Button按鈕
我們可以使用三個組件來製作自己所需要的按鈕。或者也可以在github.com網站上搜尋'react native button'來看看社區其他人的作品。 TouchableOpacity TouchableHighlight TouchableNativeFeedback
還有一個TouchableWithoutFeedback,官方不推薦使用。
這裡以TouchableOpacity為例說一下如何定製Button。
<TouchableOpacity activeOpacity={0.5} style={LoginStyles.login} onPress={this.onButtonPress.bind(this)}> <Text style={{fontSize:15,color:'white',fontWeight:'bold'}}> 登入 </Text></TouchableOpacity>
簡單的使用呢,就是使用<TouchableOpacity>組件來嵌套一個<Text>文本,文本是按鈕顯示的文字。
activeOpacity屬性指定封裝的視圖在被觸摸操作啟用時以多少不透明度顯示(通常在0到1之間)。
style屬性來指定按鈕的樣式。(我們想要的按鈕樣式,就要在這裡設定,比如圓角,寬高等)
onPress屬性,接收點擊事件function。跟<Button>組件一樣。
至於其他兩個組件的定製,就不再提了,可以查閱文檔瞭解一下。 簡單登入介面的搭建
下面就輸入框TextInput和定製的按鈕,來搭建一個簡單的登入介面。效果圖呢,在文章開頭已經有了,下面直接看代碼:
import React, { Component } from 'react';import { AppRegistry, Image, StyleSheet, Text, TextInput, Alert,//簡單的JS彈出框 TouchableOpacity, Dimensions,//擷取螢幕寬高 View} from 'react-native';var width = Dimensions.get('window').width;//得到螢幕寬度class LoginComponent extends Component { //建構函式 constructor(props) { super(props); //兩個狀態使用者輸入框文本,密碼框文本 this.state = {user_text: '',pass_text: ''}; } //點擊事件函數 onButtonPress () { Alert.alert('使用者輸入資訊','您輸入的手機號/魅族帳號為:'+this.state.user_text+',輸入的密碼為:'+this.state.pass_text); }; render() { return ( <View style={LoginStyles.container}> <Image source={require('./img/flyme5_logo.png')}//項目中的圖片 style={LoginStyles.logoImg}/> <TextInput placeholder="手機號/魅族帳號" underlineColorAndroid={'transparent'}//去掉底線 style={LoginStyles.username} //將文本寫入state onChangeText={(user_text) => this.setState({user_text})}/> <TextInput placeholder="密碼" secureTextEntry={true}//隱藏輸入內容 underlineColorAndroid={'transparent'} style={LoginStyles.username} onChangeText={(pass_text) => this.setState({pass_text})}/> <TouchableOpacity activeOpacity={0.5}//點擊時的透明度 style={LoginStyles.login} //點擊事件,要記得綁定 onPress={this.onButtonPress.bind(this)}> <Text style={{fontSize:15,color:'white',fontWeight:'bold'}}> 登入 </Text> </TouchableOpacity> </View> ); }};const LoginStyles = StyleSheet.create({ container:{ flex: 1, flexDirection: 'column', justifyContent: 'center' }, logoImg: { width:100, height:108, alignSelf:'center',//設定子控制項的位置置中 marginBottom:60 }, username: { width:width-32,//置中,寬度為螢幕寬度-32,這樣左右都有16的邊距 borderRadius: 20,//輸入框邊界圓角度數 borderColor: 'skyblue',//輸入框邊界顏色 marginBottom:16, paddingLeft:10,//這裡是為了在圓角之後輸入 padding:0,//去掉Android預設的padding borderWidth: 1, alignSelf:'center'//自身置中 }, login :{ width:width-32, height:35, borderRadius: 20,//按鈕圓角 alignSelf:'center', backgroundColor:'skyblue', marginTop:20, justifyContent:'center', alignItems:'center'//顯示Text組件置中 },});AppRegistry.registerComponent('AwesomeProject', () => ButtonTest);
好了,具體的內容呢,上邊代碼中注釋已經很清楚了。
有幾塊這裡再強調一下:
①var {height, width} = Dimensions.get('window');可以得到螢幕的寬高。
如果要得打螢幕的像素,可以用:var pi=PixelRatio.get();
②onChangeText={(text) => this.setState({text})是唯一的得到輸入框內容的方法。
③按鈕點擊事件要想得到state中的值,需要調用bind()方法進行綁定。
onPress={this.onButtonPress.bind(this)}
或者我們在構造器中bind:
this.onButtonPress=this.onButtonPress.bind(this);
然後在使用:onPress={this.onButtonPress}是一樣的。
2018/3/1更新:
首先在JavaScript中,this對象是運行時基於函數的執行環境(也就是上下文)綁定的。如果我們用ES5的文法去寫的話,就不存在綁定this的說法,因為在ES5中會預設自動綁定,但是在ES6中就取消了auto binding,就需要我們手動bind。如果不綁定this,this.onButtonPress方法的this就會指向全域,綁定了this之後將this綁定到組件執行個體之上。
需要注意的問題就是:bind方法每運行一次就返回一個新的函數,在react中也就是每次render都會建立一個新的函數,影響效能。
上邊提到的在構造器中進行bind,這樣就不會建立新的函數。但是這樣還是很繁瑣,那麼有沒有更好的寫法呢。有,那就是使用箭頭函數。
onButtonPress = () => { xxxxxx};onPress={this.onButtonPress}
箭頭函數不會建立自身的this上下文,this就指向組件執行個體。建議就用箭頭函數,代碼也會精簡很多。
關於bind(this)更多的理解,請參考下面一篇文章,講解的比較清晰。
理解React中es6方法建立組件的this
另外提一下:
使用ES6文法來建立組件是不支援React mixins的,如果一定要使用React mixins就只能使用React.createClass方法(ES5的寫法)來建立組件了。
④<Text>組件設定fontWeight:'bold'為粗體。這些屬性都是基本的,需要的話查閱文檔就可以。
⑤Alert彈出框,alert()方法在Android平台有4個參數(iOS平台多了一個AlertType),第一個參數為標題,第二個參數為內容,第三個參數為一個下邊的按鈕數組,第四個參數為彈出框的選項。
具體的使用:
Alert.alert( 'Alert Title', 'My Alert Msg', [ {text: 'Ask me later', onPress: () => console.log('Ask me later pressed')}, {text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'}, {text: 'OK', onPress: () => console.log('OK Pressed')}, ], { cancelable: false })
好了,我們再來看下,輸入內容,點擊按鈕之後的效果:
結語
本篇瞭解了輸入框和按鈕的定製,並搭建了一個簡單的登入介面。涉及到的內容還是蠻多的。需要我們慢慢去理解消化。
好了,先這樣了,我們下一篇再見。