1,首先,要顯示控件,需要一個視圖畫板(View)。React Native繪製視圖的組件是 Component。那麼,我們就要重載Component對象,制定畫板視圖,並重載 render() 函數,重新繪製頁面時就會調用該方法(詳情查看React 組件生命週期),並將UI實現代碼放到return中
export default class ThirthDayStudy extends Component {
render() {
return (
// 視圖的樣式放到styles.container中定義,
<View style={styles.container}>
// 將你的控件代碼放到這裏…
</View>
);
}
}
// 想了解更多關於屬性設置的可以到JavaScript,CSS教程中觀摩觀摩
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center', // flex-start 容器的開頭; flex-end容器的結尾; center容器的中心; space-between; space-around
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center', // start end center left right
margin: 10,
},
});
2,按照常例,我們要在剛生成的視圖裏顯示 Hello World!文本
<View style={styles.container}>
// view中的佈局,回默認由上到下添加 所以,text就是最上面的組件(View中)詳情可瞭解React 的頁面佈局
<Text style={styles.welcome}> // styles.welcome 如上面的定義
Hello World!// React 初始化默認顯示 Welcome to React Native!
</Text>
</View>
3,顯示圖片的控件 Image
<View style={styles.container}>
…
<Image
style={styles.icon}
source={require('./image/banner.png')} // 本地圖片 根目錄/image文件夾/圖片名稱
/>
<Image
style={styles.logo}
source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}} // 網絡圖片
/>
…
</View>
4, button 按鈕及事件 。 在RN中使用按鈕有3種:TouchableHighlight,TouchableOpacity,TouchableWithoutFeedback。
TouchableHighlight 點擊後產生高亮顏色變化狀態;
TouchableOpacity 點擊產生透明度變化狀態 點擊無變化;
TouchableWithoutFeedback 官方不推薦使用;
<TouchableHighlight
style={styles.button}
onPress={this.onSearchPressed.bind(this)} // 響應方法
underlayColor='#99d9f4'> // 高亮顏色
<Text style={styles.buttonText}>Go</Text> // 可以在按鈕區域顯示文本和圖片
</TouchableHighlight>
// 在 ThirthDayStudy 中添加對應函數
onSearchPressed() {
var query = urlForQueryAndPage('place_name', this.state.searchString, 1);
this._executeQuery(query);
}
var styles = StyleSheet.create({
…
button: {
width: 100,
height: 50,
alignItems: 'center',
justifyContent: 'center',
alignSelf: 'center',
backgroundColor:'#ff0000',
borderRadius:10 // 圓角
},
…
}
// TouchableOpacity 和 TouchableOpacity 一樣 只要設置activeOpacity ,值(如 0.2)即可
// 觸發事件
onPressIn--用戶剛點擊
onPressOut--用戶手指離開按鈕
onPress--用戶完成一次點擊事件
onLongPress--長按事件
一般來說用戶完成一次點擊:onPressIn->onPressOut->onPress
但是如果用戶按下按鈕後移動到按鈕外:onPressIn->onPressOut
5,文本輸入框
<TextInput
style={styles.searchInput}
value={this.state.searchString}
onChange={this.onSearchTextChanged.bind(this)} // 輸入框文本變化是 調用的處理函數
placeholder='Search via name or postcode' />
…
searchInput: {
height: 36,
padding: 4,
marginRight: 5,
flex: 4,
fontSize: 18,
borderWidth: 1,
borderColor: '#48BBEC',
borderRadius: 8,
color: '#48BBEC'
},
…
重要屬性
keyboardType 屬性 enum('default', "ascii-capable", 'numbers-and-punctuation', 'url', 'number-pad', 'phone-pad', 'name-phone-pad', 'email-address', 'decimal-pad', 'twitter', 'web-search', "numeric") 決定打開哪種鍵盤,例如,數字鍵盤。
multiline 布爾型
如果值爲真,文本輸入可以輸入多行。默認值爲假。
returnKeyType enum('default', 'go', 'google', 'join', 'next', 'route', 'search', 'send', 'yahoo', 'done', 'emergency-call')
決定返回鍵的樣式
clearButtonMode enum('never', 'while-editing', 'unless-editing', 'always')
清除按鈕出現在文本視圖右側的時機
6, 列表 ListView (UITableView)
<ListView
showsVerticalScrollIndicator={false} // 是否顯示滾動條
dataSource={this.state.dataSource.cloneWithRows(this.state.data)} // 指定數據源
renderRow={(rowData,rowId) => <Text>{rowData}</Text>} // 每一行的顯示 (Cell)
/>
// 在構造函數裏,初始化數據源
constructor(props) {
super(props)
// row更新的策略
var dataSource = new ListView.DataSource({
rowHasChanged:(r1,r2) => r1 != r2,
})
// row更新的策略
this.state = {
dataSource : dataSource ,
data : ["A" ,"B" ,"C" ,"D" ,"E" ,"F" ,"G" ,"H"]
}
}
7, 滾動視圖 ScrollView
<ScrollView
onScroll={() => { console.log('onScroll!'); }}
scrollEventThrottle={200}
contentInset={{top: -50}}
style={styles.scrollView}>
</ScrollView>
…
contentContainer: {
backgroundColor: '#6A85B1',
height: 300,
scrollView: 20
},
…
8, Swiper 用第三方控件 react-native-swiper 。下載該文件放到項目的 ‘node_modules’ 文件夾下面
import Swiper from 'react-native-swiper';
<Swiper height={150} showButtons={true} autoplay={true}
// 滾動指示點
activeDot={<View style={{backgroundColor: 'rgba(255,255,255,0.8)', width: 8, height: 8, borderRadius: 4, margin: 3}} />} >
<Text style={{flex:1 ,height:150}} >Swiper One</Text>
<Text style={{flex:1 ,height:150}} >Swiper tow</Text>
<Text style={{flex:1 ,height:150}} >Swiper Three</Text>
</Swiper>
9, 計時器
let intervel = setInterval( // 開始計時器
()=> {
let currentTime = (new Date()).getTime()
let count = currentTime - this.state.intialTime
let second = Math.floor(count/1000)
this.setState({
time: (second<10 ? "0"+second : second),
})
if (this.state.buttonTitle == 'Start') { // 在外部改變狀態,停止計時器
clearInterval(intervel) // 結束計時器
}
}, 1000) // 計時器間隔 按 毫秒記
10, tabBarIos
import { TabBarIOS}from 'react-native';
constructor(props) {
super(props)
this.state = {
selectIndex: 0,
barItems: [{
title: 'home',
icon: '',
} ,{
title: 'msg',
icon: '',
} ,{
title: 'discover',
icon: '',
} ,{
title: 'member',
icon: '',
}]
}
}
// 生成 BarItem
baritem(index) {
return (
<TabBarIOS.Item
title={this.state.barItems[index].title} // item 標題
icon={this.state.barItems[index].icon} // item 圖片
selected={this.state.selectIndex == index} // item 是否被選中
onPress={ ()=> { // item 點擊事件
this.setState({
selectIndex: index
})
}}
>
// item 對應的Viewcontroller 繼承 Component
<TabBarViewController nviTitle={this.state.barItems[index].title} />
</TabBarIOS.Item>
)
}
render() {
// 根據數組 生成對應的 BarItem
var onThis = this
var items = this.state.barItems.map(function(elem ,index) {
return (
onThis.baritem(index)
)
})
return (
<TabBarIOS barTintColor='#fff' tintColor='#1b95e0' style={{backgroundColor:'#ABC'}} >
{items}
</TabBarIOS>
)
}
11, RefreshControl 刷新
import {RefreshControl}from 'react-native';
<ScrollView
refreshControl={<RefreshControl
refreshing={this.state.isRefreshing} // 是否在刷新 ,刷新狀態
onRefresh={()=> this.refreshAction()} // 刷新觸發的事件
tintColor='#ff0' />}
>
<Text>{this.props.nviTitle + this.state.refreshTime}</Text>
</ScrollView>
12, PanResponder 手勢
import {PanResponder}from 'react-native';
export default class extends Component {
constructor(props) {
super(props)
this.state = {
cicleTop: 64,
cicleLeft: 0,
}
}
lastLocation = {
x: 0,
y: 64,
}
stopPan(evt ,gestrueState) {
this.lastLocation.x = this.state.cicleLeft
this.lastLocation.y = this.state.cicleTop
}
componentWillMount() {
this._panResponder = PanResponder.create({
//用戶開始觸摸屏幕的時候,是否願意成爲響應者;
onStartShouldSetPanResponder: (evt ,gestrueState) => true,
onStartShouldSetPanResponderCapture: (evt ,gestrueState) => true,
//在每一個觸摸點開始移動的時候,再詢問一次是否響應觸摸交互;
onMoveShouldSetPanResponder: (evt ,gestrueState) => true,
// 開始手勢操作。給用戶一些視覺反饋,讓他們知道發生了什麼事情!
onPanResponderGrant: (evt ,gestrueState) => {
},
// 最近一次的移動距離 gestureState.move{X,Y}
onPanResponderMove: (evt ,gestrueState) => {
var left = this.lastLocation.x + gestrueState.dx;
var top = this.lastLocation.y + gestrueState.dy;
if (left < 0) {
left = 0
}
if (top < 64) {
top = 64
}
this.setState({
cicleTop: top,
cicleLeft: left
})
},
// 用戶放開了所有的觸摸點,且此時視圖已經成爲了響應者。
// 一般來說這意味着一個手勢操作已經成功完成。
onPanResponderEnd: this.stopPan.bind(this),
// 用戶放開了所有的觸摸點,且此時視圖已經成爲了響應者。
onPanResponderRelease: this.stopPan.bind(this),
// 另一個組件已經成爲了新的響應者,所以當前手勢將被取消。
onPanResponderTerminate: this.stopPan.bind(this),
})
}
render() {
return (
<View style={{flex:1}} >
<View style={{width:100, height:100, marginTop: this.state.cicleTop ,marginLeft: this.state.cicleLeft , backgroundColor:'#feb'}} {...this._panResponder.panHandlers} >
</View>
</View>
)
}
}
相關資料
1 http://wiki.jikexueyuan.com/project/react-native/text-input.html react native 教程
2 https://segmentfault.com/a/1190000004031633 樣式使用
3 http://www.jianshu.com/p/1293bb8ac969 React-Native組件用法詳解之ListView
4 http://www.jianshu.com/p/7944648bb16a ReactNative的ScrollView簡述