一赠摇、環(huán)境搭建
1.1 React Native環(huán)境搭建
1.1.1 IOS環(huán)境搭建
環(huán)境:
MacOS
# 如果你已經(jīng)安裝了 Node妹窖,請檢查其版本是否在 v8.3 以上
brew install node
# Watchman則是由 Facebook 提供的監(jiān)視文件系統(tǒng)變更的工具缚柏。安裝此工具可以提高開發(fā)時的性能
brew install watchman
-
注意:不要使用
cnpm
砾肺!cnpm
安裝的模塊路徑比較奇怪凑术,packager
不能正常識別翩蘸!
npm install -g yarn react-native-cli
1. 創(chuàng)建新項目
init
命令默認會創(chuàng)建最新的版本,而目前最新的0.45
及以上版本需要下載boost
等幾個第三方庫編譯淮逊。這些庫在國內(nèi)即便翻墻也很難下載成功催首,導(dǎo)致很多人無法運行iOS
項目扶踊。可以暫時創(chuàng)建0.44.3
的版本
react-native init MyApp --version 0.44.3
2. 編譯并運行 React Native 應(yīng)用
1). 運行方式一 在你的項目目錄中運行react-native run-ios
cd MyApp
react-native run-ios
2). 運行方式二 在xCode
中運行
打開
xcode
選擇項目中myApp/ios/myApp.xcodeproj
郎任,然后點擊左上角運行即可
3. 遠程調(diào)試
-
ctrl + R
刷新 -
ctrl + D
選擇對應(yīng)的工具調(diào)試
Enable Live Reload
當(dāng)你的js代碼發(fā)生變化后秧耗,
React Native
會自動生成bundle然后傳輸?shù)侥M器或手機上
[圖片上傳失敗...(image-e2a80d-1565014986904)]
巧用Sources面板
[圖片上傳失敗...(image-8618e9-1565014986904)]
指定模擬的設(shè)備類型
- 你可以使用
--simulator
參數(shù),在其后加上要使用的設(shè)備名稱來指定要模擬的設(shè)備類型(目前默認為"iPhone X"
)舶治。如果你要模擬iPhone 4s
分井,那么這樣運行命令即可:react-native run-ios --simulator "iPhone 4s"
谒拴。 - 你可以在終端中運行
xcrun simctl list devices
來查看具體可用的設(shè)備名稱
1.1.2 安卓環(huán)境搭建
安裝依賴
必須安裝的依賴有:
Node
款票、Watchman
和React Native
命令行工具以及 JDK 和Android Studio
brew install node
brew install watchman
npm install -g yarn react-native-cli
Java Development Kit
React Native
需要Java Development Kit [JDK] 1.8
(暫不支持1.9
及更高版本)。你可以在命令行中輸入
-
javac -version
來查看你當(dāng)前安裝的JDK
版本生音。如果版本不合要求韩脏,則可以到 官網(wǎng)上下載
1. 安裝 Android Studio
首先下載和安裝
Android Studio
缩麸,國內(nèi)用戶可能無法打開官方鏈接,請自行使用搜索引擎搜索可用的下載鏈接赡矢。安裝界面中選擇"Custom"選項杭朱,確保選中了以下幾項
Android SDK
Android SDK Platform
Performance (Intel ? HAXM)
Android Virtual Device
然后點擊"
Next
"來安裝選中的組件。安裝完成后吹散,看到歡迎界面時弧械,就可以進行下面的操作了
2. 安裝 Android SDK
Android Studio
默認會安裝最新版本的Android SDK
。目前編譯React Native
應(yīng)用需要的是Android 8.1 (Oreo)
版本的SDK
空民。你可以在Android Studio
的SDK Manager
中選擇安裝各版本的SDK
你可以在 Android Studio
的歡迎界面中找到 SDK Manager
刃唐。點擊"Configure
",然后就能看到"SDK Manager
"界轩。
在
SDK Manager
中選擇"SDK Platforms
"選項卡画饥,然后在右下角勾選"Show Package Details
"。展開Android 8.1 (Oreo)
選項浊猾,確保勾選了下面這些組件(重申你必須使用穩(wěn)定的翻墻工具抖甘,否則可能都看不到這個界面):
Android SDK Platform 27
-
Intel x86 Atom_64 System Image
(官方模擬器鏡像文件,使用非官方模擬器不需要安裝此組件)
SDK Manager
還可以在Android Studio
的"Preferences"菜單中找到葫慎。具體路徑是Appearance & Behavior → System Settings → Android SDK
- 然后點擊"
SDK Tools
"選項卡衔彻,同樣勾中右下角的"Show Package Details
"。展開"Android SDK Build-Tools
"選項偷办,確保選中了React Native
所必須的27.0.3
版本艰额。你可以同時安裝多個其他版本
最后點擊"
Apply
"來下載和安裝這些組件。
3. 配置 ANDROID_HOME 環(huán)境變量
React Native
需要通過環(huán)境變量來了解你的Android SDK
裝在什么路徑椒涯,從而正常進行編譯
- 具體的做法是把下面的命令加入到
~/.bash_profile
文件中
# 如果你不是通過Android Studio安裝的sdk悴晰,則其路徑可能不同,請自行確定清楚逐工。
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/emulator
如果你的命令行不是
bash
铡溪,而是例如zsh
等其他,請使用對應(yīng)的配置文件
使用
source $HOME/.bash_profile
命令來使環(huán)境變量設(shè)置立即生效(否則重啟后才生效)泪喊∽亓颍可以使用echo $ANDROID_HOME
檢查此變量是否已正確設(shè)置
4. 編譯并運行 React Native 應(yīng)用
確保你先運行了模擬器或者連接了真機,然后在你的項目目錄中運行
react-native run-android
Android Studio自帶工具運行
使用genymotion模擬器
去官網(wǎng)需要注冊并下載https://www.genymotion.com/袒啼,需要注冊登錄再下載的哈扮。注意下載
with virtualBox
版本,然后安裝完成后需要登錄蚓再,就是剛才注冊的賬號滑肉。登錄后進入這個頁面做兩個操作
點擊
settings
,選擇adb
設(shè)置sdk
就是剛才一直用的sdk
安裝路徑,如下
啟動項目摘仅,點擊
genymotion
里的start
啟動我們剛才安裝好的的虛擬設(shè)備靶庙,是這個樣子的,此時我們剛才初始化的項目還沒連上虛擬設(shè)備
然后在我們的工程項目里執(zhí)行
adb devices
會列出當(dāng)前啟動的虛擬設(shè)備娃属,能檢測到說明沒問題六荒,如下圖里最后一行顯示的就是剛才我們開啟的genymotion
那臺虛擬設(shè)備
最后項目目錄里執(zhí)行
react-native run-android
打開
genymotion
,歡迎頁面出來了矾端,成功掏击,修改一下文字,重新加載一遍秩铆,成功
- 第一次默認不是熱加載形式砚亭,就是改變文件內(nèi)容需要手動刷新的,這里設(shè)置一下熱加載殴玛,以后內(nèi)容這里就會自動刷新捅膘,
mac
是執(zhí)行command+r
,選擇第四個hot reloading
運行
react-native run-andriod
會下載很多東西族阅,然后出現(xiàn)這個標(biāo)志說明編譯沒有問題篓跛,還缺少一個模擬設(shè)備
如果是安卓5.0以下需要配置一下IP
1.2 安卓設(shè)備真機調(diào)試
1. 開啟 USB 調(diào)試
在默認情況下
Android
設(shè)備只能從應(yīng)用市場來安裝應(yīng)用。你需要開啟USB
調(diào)試才能自由安裝開發(fā)版本的APP
2. 通過 USB 數(shù)據(jù)線連接設(shè)備
下面檢查你的設(shè)備是否能正確連接到
ADB(Android Debug Bridge)
坦刀,使用adb devices
命令:
3. 運行應(yīng)用
現(xiàn)在你可以運行
react-native run-android
來在設(shè)備上安裝并啟動應(yīng)用了
從設(shè)備上訪問開發(fā)服務(wù)器
- 運行
adb reverse tcp:8081 tcp:8081
- 在命令行執(zhí)行
adb shell input keyevent 82
彈出開發(fā)者工具愧沟。打開熱更新和遠程調(diào)試
1.3 移除vscode裝飾器報錯
點擊
Visual Studio Code
左下角的配置按鈕。在搜索框內(nèi)輸入“experimentalDecorators”鲤遥,發(fā)現(xiàn)竟然能夠找到選項沐寺,如下
"javascript.implicitProjectConfig.experimentalDecorators": false
試著將false
改為true
,重啟Visual Studio Code
二盖奈、矢量圖標(biāo)的運用
https://github.com/oblador/react-native-vector-icons
react-native-vector-icons
是可以直接使用圖片名就能加載圖片的第三方,類似于web的 iconfont
矢量圖混坞,使用很方便, 你不需要在工程文件夾里塞各種圖片, 節(jié)省很多空間,下面就來看看怎么使用吧
npm install react-native-vector-icons --save
npm install rnpm -g
2.1 android平臺
1. 自動配置
react-native link react-native-vector-icons
# 或者
npm install -g rnpm
rnpm link react-native-vector-icons
會為你配置好所有,但是這是成功的情況下,你不需要操心任何事究孕,但是往往不能如愿啥酱。如果你這步成功了,而且能夠正常運行厨诸,下面這些你就可以跳過
2. 手動配置
- 第一步:復(fù)制字體文件(這一步千萬不能忘記镶殷,不然就算運行成功你也看不到圖標(biāo))
找到項目
node_modules/react-native-vector-icons/Fonts
,里面有很多已經(jīng)內(nèi)置的圖標(biāo)庫字體文件微酬,依照自己的需求绘趋,復(fù)制你需要的字體文件到android/app/src/main/assets/fonts
,(如果沒有這個目錄就自行創(chuàng)建)
- 第二步:配置
android/settings.gradle
在現(xiàn)有的代碼基礎(chǔ)上添加如下代碼
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
- 第三步:配置
android/app/build.gradle
dependencies {
compile project(':react-native-vector-icons') //添加
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:+" // From node_modules
compile project(':react-native-navigation')
}
- 第四步:配置
android/app/src/main/java/com/xxxx/MainApplication.java
import com.oblador.vectoricons.VectorIconsPackage;
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
+ , new VectorIconsPackage()
);
}
到這里配置就全部完成颗管,接下來就可以在
rn
項目中使用iconfont
2.2 IOS平臺
打開你的
Xcode
項目工程陷遮,右鍵工程文件,選擇react
項目下的node_modules/react-native-vector-icons/Fonts
文件
在xcode的Info.plist文件中,加入: Fonts provided by application數(shù)組
打開終端垦江,輸入:
rnpm link
帽馋,回車后會看到Fonts provided by application
下加入如下字體
重新運行
react
項目,終端輸入:react-native run-ios
疫粥,可以看到效果了
三茬斧、react-native-router-flux的使用
3.1 簡介
特性
react-native-router-flux
是一個路由包.在一個中心區(qū)域定義可切換scene
模塊。在使用過程中梗逮,跟react-native
提供的navigator
的區(qū)別是你不需要有navigator
對象项秉。你可以在任意地方使用簡單的語法去控制scene
的切換,如:Actions.login({username, password})
orActions.profile({profile})
or 甚至Actions.profile(123)
,其中login
profile
等是路由的key
慷彤,通過調(diào)用key
來切換路由
- 所有的參數(shù)將被注入到
this.props
中給Sene
組件使用
功能和亮點
- 可定制的導(dǎo)航條:由
Scene
或者Scene
的state
去控制導(dǎo)航條的show
/hide
- 嵌套導(dǎo)航:每一個
tab
都可以有自己的導(dǎo)航娄蔼,該導(dǎo)航被嵌套在root
導(dǎo)航中 - 使用
Action sheet
來自定義場景渲染器 - 動態(tài)路由:動態(tài)路由將允許你通過應(yīng)用的
state
去選著哪個scene
將被渲染 -
Reset History stack
重置歷史棧:新的reset
類型將提供清除歷史棧河消除導(dǎo)航的返回按鈕的功能 - 更加強大的狀態(tài)控制:在多個
scene
中可以有不同的state
npm i react-native-router-flux --save
使用方式一
在你的
src/index.js
級別的文件中使用Scene
組件定義你的scenes
,并且Scene
組件作為Router
的子節(jié)點底哗。定義好的Scene
將由Router
來控制其行為
import {Scene, Router, Actions} from 'react-native-router-flux';
import {Router, Scene} from "react-native-router-flux";
import PageOne from "./Component/PageOne";
import PageTwo from "./Component/PageTwo";
const Root = () => {
return (
<Router>
{/* 這種寫法是將全部的跳轉(zhuǎn)頁面都放在Root下面 */}
<Scene key="root">
{/* key 就是給頁面的標(biāo)簽,供Actions使用 */}
{/* component 設(shè)置關(guān)聯(lián)的頁面 */}
{/* title 就是給頁面標(biāo)題 */}
{/* initial 就是設(shè)置默認頁面*/}
<Scene
key="one"
component={PageOne}
title="PageOne"
initial={true}
/>
<Scene key="two" component={PageTwo} title="PageTwo" />
</Scene>
</Router>
);
};
第二種使用方式
你可以在編譯期定義你所有的
scenes
岁诉,并在后面的Router
里面使用
import {Actions, Scene, Router} from 'react-native-router-flux';
const scenes = Actions.create(
<Scene key="root">
<Scene key="login" component={Login} title="Login"/>
<Scene key="register" component={Register} title="Register"/>
<Scene key="home" component={Home}/>
</Scene>
);
/* ... */
class App extends React.Component {
render() {
return <Router scenes={scenes}/>
}
}
{Actions, Scene, Router} from 'react-native-router-flux';
const scenes = Actions.create(
<Scene key="root">
<Scene key="login" component={Login} title="Login"/>
<Scene key="register" component={Register} title="Register"/>
<Scene key="home" component={Home}/>
</Scene>
);
/* ... */
class App extends React.Component {
render() {
return <Router scenes={scenes}/>
}
}
在任意地方通過導(dǎo)入
import {Actions} from 'react-native-router-flux'
獲得
Actions
對象,Actions
對象將是我們操作Scenes
的遙控器跋选。通過Actions
我們可以向Router
發(fā)出動作讓Router
控制Scene
變化涕癣。
- 調(diào)用
Actions.ACTION_NAME(PARAMS)
可以展示一個scene
,參數(shù)將被注入scene
中
(如Actions.login()
切換到登錄頁面) -
Actions.pop()
方法將會彈出當(dāng)前的scene
前标,他接受如下可選參數(shù)-
{popNum:[number]}
允許你去一次彈出多個scene
-
{refresh:{...propsToSetOnPreviousScene}}
允許你去刷新pop
后的scene
-
-
Actions.refresh(PARAMS)
會更新當(dāng)前scene
的屬性
3.2 簡單例子
import {Router, Scene} from "react-native-router-flux";
import PageOne from "./Component/PageOne";
import PageTwo from "./Component/PageTwo";
const Root = () => {
return (
<Router>
{/* 這種寫法是將全部的跳轉(zhuǎn)頁面都放在Root下面 */}
<Scene key="root">
{/* key 就是給頁面的標(biāo)簽,供Actions使用 */}
{/* component 設(shè)置關(guān)聯(lián)的頁面 */}
{/* title 就是給頁面標(biāo)題 */}
{/* initial 就是設(shè)置默認頁面*/}
<Scene
key="one"
component={PageOne}
title="PageOne"
initial={true}
/>
<Scene key="two" component={PageTwo} title="PageTwo" />
</Scene>
</Router>
);
};
// PageOne 的核心代碼坠韩,點擊 Text 跳轉(zhuǎn)到下一個頁面
//導(dǎo)入Action的包,處理頁面跳轉(zhuǎn)
import { Actions } from 'react-native-router-flux';
const PageOne = () => {
return (
<View style={styles.container}>
<Text style={styles.welcome}
onPress={()=>Actions.two()} >
我是Page One
</Text>
</View>
);
};
// PageTwo 的核心代碼
export default class PageTwo extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>我是Page Two </Text>
</View>)
}
}
運行就可以看到下面的效果:
簡單就完成了兩個頁面之間的切換
每一個Scene component
有如下屬性
-
key
:一個唯一的字符串,用來標(biāo)識一個Scene
炼列,可以理解為scene
的一個身份牌號碼 -
component
:當(dāng)切換到該scene
時只搁,component
屬性引用的組件將被渲染出來 -
title
:當(dāng)切換到對應(yīng)的scene
時,屏幕頂部的導(dǎo)航條中間將顯示該title
-
initial={true}
表示默認為初始化scene
在
pageOne
中有一個Text
組件俭尖,當(dāng)點擊onPress
方法氢惋,該方法將調(diào)用Actions.pageTwo
- 會調(diào)用
Actions.SCENE_KEY(PARAMS)
,SCENE_KEY
即為之前定義的key
值洞翩,參數(shù)為可選的 - 我們的
Actions
就會通知Router
,把key=pageTwo
的Scene
顯示出來焰望,如果傳有參數(shù)的話骚亿,參數(shù)也會傳入Scene
組件中
render() {
const goToPageTwo = () => Actions.pageTwo({text: 'Hello World!'});
return (
This is PageOne!
)
}
我們傳遞一個參數(shù)名為
text
。值為Hello World
柿估!如下所示循未,我們就可以在key=pageTwo
的scene
的component
屬性置頂?shù)慕M件中通過props
獲取該參數(shù)值
render() {
return (
This is PageTwo!
{this.props.text}
)
}
我們從
pageOne
跳轉(zhuǎn)到了pageTwo
,如果我們想跳回pageOne
怎么辦呢
- 官方提供的導(dǎo)航欄早已提供了一個
back icon
秫舌,我們也可以通過調(diào)用Actions.pop()
方法將當(dāng)前scene
彈出棧,我們的pageOne
就在棧頂了绣檬,此時顯示的就是pageOne
了足陨,如果跳回來后我們需要刷新當(dāng)前scene
,我們可以調(diào)用Actions.refresh(PARAMS)
數(shù)據(jù)傳遞與刷新
頁面之間的切換自然不會缺少數(shù)據(jù)的傳遞娇未,而且這個路由框架可以實時
refresh
當(dāng)前頁面
- 先看頁面之間傳遞數(shù)據(jù)吧墨缘,這里添加一個
PageThree
import {Actions} from "react-native-router-flux"
const PageThree = () => {
return (
<View style={styles.container}>
<Text style={styles.welcome}
//Actions.pop是退回到上一層
onPress={() => Actions.pop({
//refresh用于刷新數(shù)據(jù)
refresh: {
data: '從 three 回到 two'
}
})}>我是Page Three </Text>
</View>
);
};
PageTwo
也要修改一下代碼
import {Actions} from 'react-native-router-flux'; // New code
export default class PageTwo extends Component {
render() {
const data = this.props.data || "null";
return (
<View style={styles.container}>
<Text style={styles.welcome}
//添加點擊事件并傳遞數(shù)據(jù)到PageThree
onPress={() => Actions.three({data: "從 two 傳遞到 three"})}
>我是Page Two </Text>
<Text style={styles.refresh}
//展示從PageThree傳回來的數(shù)據(jù)
> refresh:{data}</Text>
</View>)
}
}
最后到
Root.js
添加新的Scence
const Root = () => {
return (
<Router>
//...........
<Scene key="three"
component={PageThree}
title="PageThree"/>
</Scene>
</Router>
);
};
此時運行就可以看到頁面數(shù)據(jù)傳遞的效果了
可以看到從
PageThree
回到PageTwo
數(shù)據(jù)傳遞并刷新頁面的效果,不過如果需要實時刷新當(dāng)前頁面呢零抬?這時就需要使用Actions.refresh
方法了
export default class PageTwo extends Component {
render() {
const data = this.props.data || "null";
return (
<View style={styles.container}>
<Text style={styles.welcome}
onPress={() => Actions.three({data: "從 two 傳遞到 three"})}
>我是Page Two </Text>
<Text style={styles.refresh}
onPress={() => Actions.refresh({
data: 'Changed data',
})}
> refresh:{data}</Text>
</View>)
}
}
Tab Scene
通過設(shè)置
Scene
屬性的Tabs
可以設(shè)置Tabs
镊讼。這個也開發(fā)中經(jīng)常用到的頁面效果
//設(shè)置tab選中時的字體顏色和標(biāo)題
const TabIcon = ({focused , title}) => {
return (
<Text style={{color: focused ? 'blue' : 'black'}}>{title}</Text>
);
};
const Root = () => {
return (<Router>
{/*tabBarPosition設(shè)置tab是在top還是bottom */}
<Scene hideNavBar tabBarPosition="bottom">
<Tabs
key="tabbar"
swipeEnabled
wrap={false}
// 是否顯示標(biāo)簽欄文字
showLabel={false}
tabBarStyle={{backgroundColor: "#eee"}}
//tab選中的顏色
activeBackgroundColor="white"
//tab沒選中的顏色
inactiveBackgroundColor="red"
>
<Scene
key="one"
icon={TabIcon}
component={PageOne}
title="PageOne"
/>
<Scene
key="two"
component={PageTwo}
title="PageTwo"
icon={TabIcon}
/>
<Scene
key="three"
component={PageThree}
title="PageThree"
icon={TabIcon}
/>
</Tabs>
</Scene>
</Router>)
};
3.3 react-native-router-flux之API
英文版:https://github.com/aksonov/react-native-router-flux/blob/master/docs/API.md
3.3.1 Router
Property | Type | Default | Description |
---|---|---|---|
children |
required |
頁面根組件 | |
wrapBy |
Function |
允許集成諸如Redux (connect )和Mobx (observer )之類的狀態(tài)管理方案 |
|
sceneStyle |
Style |
適用于所有場景的Style (可選) |
|
backAndroidHandler |
Function |
允許在Android 中自定義控制返回按鈕(可選) |
backAndroidHandler用法
const onBackPress = () => {
if (Actions.state.index !== 0) {
return false
}
Actions.pop()
return true
}
backAndroidHandler={onBackPress}
3.3.2 Scene
此路由器的最重要的組件, 所有
<Scene>
組件必須要有一個唯一的key
平夜。父節(jié)點<Scene>
不能將component
作為prop
蝶棋,因為它將作為其子節(jié)點的組件
Property | Type | Default | Description |
---|---|---|---|
key |
string |
required |
將用于標(biāo)識頁面,例如Actions.name(params) 忽妒。必須是獨一無二的 |
path |
string |
將被用來匹配傳入的深層鏈接和傳遞參數(shù)玩裙,例如:/user/:id/ 將從/user/1234/ 用params {id:1234} 調(diào)用場景的操作。接受uri 的模板標(biāo)準(zhǔn) |
|
component |
React.Component |
semi-required |
要顯示的組件段直,定義嵌套時不需要Scene 吃溅。 |
back |
boolean |
false |
如果是true ,則顯示后退按鈕鸯檬,而不是由上層容器定義的左側(cè)/drawer 按鈕 |
backButtonImage |
string |
設(shè)置返回按鈕的圖片 | |
backButtonTintColor |
string |
自定義后退按鈕色調(diào) | |
init |
boolean |
false |
如果是true 后退按鈕不會顯示 |
clone |
boolean |
false |
標(biāo)有clone 的場景將被視為模板决侈,并在被推送時克隆到當(dāng)前場景的父節(jié)點中 |
contentComponent |
React.Component |
用于呈現(xiàn)抽屜內(nèi)容的組件(例如導(dǎo)航) | |
drawer |
boolean |
false |
載入DrawerNavigator 內(nèi)的子頁面 |
failure |
Function |
如果on 返回一個“falsey” 值,那么failure 將被調(diào)用 |
|
backTitle |
string |
指定場景的后退按鈕標(biāo)題 | |
backButtonTextStyle |
Style |
用于返回按鈕文本的樣式 | |
rightTitle |
string |
為場景指定右側(cè)的按鈕標(biāo)題 | |
headerMode |
string |
float |
指定標(biāo)題應(yīng)該如何呈現(xiàn):(float 渲染單個標(biāo)題喧务,保持在頂部赖歌,動畫隨著屏幕的變化,這是iOS 上的常見樣式蹂楣。)screen (每個屏幕都有一個標(biāo)題俏站,并且標(biāo)題淡入,與屏幕一起出現(xiàn)痊土,這是Android 上的常見模式)如果為none (不會顯示標(biāo)題) |
hideNavBar |
boolean |
false |
隱藏導(dǎo)航欄 |
hideTabBar |
boolean |
false |
隱藏標(biāo)簽欄(僅適用于擁有tabs 指定的場景) |
hideBackImage |
boolean |
false |
隱藏返回圖片 |
initial |
boolean |
false |
設(shè)置為true 后肄扎,會默認顯示該頁面 |
leftButtonImage |
Image |
替換左側(cè)按鈕圖片 | |
leftButtonTextStyle |
Style |
左側(cè)按鈕的文字樣式 | |
leftButtonStyle |
Style |
左側(cè)按鈕的樣式 | |
leftButtonIconStyle |
Style |
左側(cè)按鈕的圖標(biāo)樣式 | |
modal |
boolean |
false |
將場景容器定義為modal ,即所有子場景都將從底部彈起到頂部。它僅適用于containers (與v3 版本的語法不同) |
navBar |
React.Component |
可以使用自定義的React 組件來定義導(dǎo)航欄 |
|
navBarButtonColor |
string |
設(shè)置導(dǎo)航欄返回按鈕的顏色 | |
navigationBarStyle |
Style |
導(dǎo)航欄的樣式 | |
navigationBarTitleImage |
Object |
導(dǎo)航欄中的圖像中覆蓋title 的Image
|
|
navigationBarTitleImageStyle |
object |
navigationBarTitleImage 的樣式 |
|
navTransparent |
boolean |
false |
導(dǎo)航欄是否透明 |
on |
Function |
又名 onEnter
|
|
onEnter |
Function |
當(dāng)Scene要被跳轉(zhuǎn)時調(diào)用犯祠。props將被作為參數(shù)提供旭等。只支持定義了component 的場景。 |
|
onExit |
Function |
當(dāng)Scene 要跳轉(zhuǎn)離開時調(diào)用衡载。只支持定義了component 的場景 |
|
onLeft |
Function |
當(dāng)導(dǎo)航欄左側(cè)按鈕被點擊時調(diào)用 | |
onRight |
Function |
當(dāng)導(dǎo)航欄右側(cè)按鈕被點擊時調(diào)用 | |
renderTitle |
React.Component |
使用React 組件顯示導(dǎo)航欄的title
|
|
renderLeftButton |
React.Component |
使用React 組件顯示導(dǎo)航欄的左側(cè)按鈕 |
|
renderRightButton |
React.Component |
使用React 組件顯示導(dǎo)航欄的右側(cè)按鈕 |
|
renderBackButton |
React.Component |
使用React 組件顯示導(dǎo)航欄的返回按鈕 |
|
rightButtonTextStyle |
Style |
右側(cè)按鈕文字的樣式 | |
success |
Function |
如on 返回一個"真實"的值搔耕,那么success 將被調(diào)用 |
|
tabs |
boolean |
false |
將子場景加載為TabNavigator 。其他標(biāo)簽導(dǎo)航器屬性也是適用 |
title |
string |
要顯示在導(dǎo)航欄中心的文本 | |
titleStyle |
Style |
title 的樣式 |
|
type |
string |
push |
可選的導(dǎo)航操作痰娱。你可以使用replace 來替換此場景中的當(dāng)前場景 |
3.3.3 Tabs (<Tabs> or <Scene tabs>)
標(biāo)簽欄組件
你可以使用
<Scene>
中的所有props
來作為<Tabs>
的屬性弃榨。 如果要使用該組件需要設(shè)置<Scene tabs={true}>
Property | Type | Default | Description |
---|---|---|---|
wrap |
boolean |
true |
自動使用自己的導(dǎo)航欄包裝每個場景(如果不是另一個容器)。 |
activeBackgroundColor |
string |
指定焦點的選項卡的選中背景顏色 | |
activeTintColor |
string |
指定標(biāo)簽欄圖標(biāo)的選中色調(diào)顏色 | |
inactiveBackgroundColor |
string |
指定非焦點的選項卡的未選中背景顏色 | |
inactiveTintColor |
string |
指定標(biāo)簽欄圖標(biāo)的未選中色調(diào)顏色 | |
labelStyle |
object |
設(shè)置tabbar 上文字的樣式 |
|
lazy |
boolean |
false |
在選項卡處于活動狀態(tài)之前梨睁,不會渲染選項卡場景(推薦設(shè)置成true ) |
tabBarComponent |
React.Component |
使用React 組件以自定義標(biāo)簽欄 |
|
tabBarPosition |
string |
指定標(biāo)簽欄位置鲸睛。iOS 上默認為bottom ,安卓上是top
|
|
tabBarStyle |
object |
標(biāo)簽欄樣式 | |
tabStyle |
object |
單個選項卡的樣式 | |
showLabel |
boolean |
true |
是否顯示標(biāo)簽欄文字 |
swipeEnabled |
boolean |
true` | 是否可以滑動選項卡 |
animationEnabled |
boolean |
true |
切換動畫 |
tabBarOnPress |
function |
自定義tabbar 點擊事件 |
|
backToInitial |
boolean |
false |
如果選項卡圖標(biāo)被點擊坡贺,返回到默認選項卡 |
3.3.4 Stack (<Stack>)
將場景組合在一起的組件官辈,用于自己的基于堆棧實現(xiàn)的導(dǎo)航。使用它將為此堆棧創(chuàng)建一個單獨的
navigator
遍坟,因此拳亿,除非您添加hideNavBar
,否則將會出現(xiàn)兩個導(dǎo)航條
3.3.5 Tab Scene (child <Scene> within Tabs)
用于實現(xiàn)
Tabs
的效果展示愿伴,可以自定義icon
和label
Property | Type | Default | Description |
---|---|---|---|
icon |
component |
undefined |
作為選項卡圖標(biāo)放置的RN 組件 |
tabBarLabel |
string |
tabbar 上的文字 |
3.3.6 Drawer (<Drawer> or <Scene drawer>)
用于實現(xiàn)抽屜的效果肺魁,如果要使用該組件需要設(shè)置
<drawer tabs={true}>
。
Property | Type | Default | Description |
---|---|---|---|
drawerImage |
Image |
替換抽屜hamburger 圖標(biāo)公般,你必須把它與drawer 一起設(shè)置 |
|
drawerIcon |
React.Component |
用于抽屜hamburger 圖標(biāo)的任意組件万搔,您必須將其與drawer 道具一起設(shè)置 |
|
hideDrawerButton |
boolean |
false |
是否顯示drawerImage 或者drawerIcon
|
drawerPosition |
string |
抽屜是在右邊還是左邊」倭保可選屬性right 或left
|
|
drawerWidth |
number |
抽屜的寬度(以像素為單位)(可選) |
3.3.7 Modals (<Modal> or <Scene modal>)
想要實現(xiàn)模態(tài)瞬雹,您必須將其
<Modal>
作為您Router
的根場景。在Modal
將正常呈現(xiàn)第一個場景(應(yīng)該是你真正的根場景)刽虹,它將渲染第一個元素作為正常場景酗捌,其他所有元素作為彈出窗口(當(dāng)它們 被push
)
示例:在下面的示例中,root
場景嵌套在<Modal>
中涌哲,因為它是第一個嵌套Scene
胖缤,所以它將正常呈現(xiàn)。如果要push
到statusModal
阀圾,errorModal
或者loginModal
哪廓,他們將呈現(xiàn)為Modal
,默認情況下會從屏幕底部向上彈出初烘。重要的是要注意涡真,目前Modal
不允許透明的背景分俯。
//... import components
<Router>
<Modal>
<Scene key="root">
<Scene key="screen1" initial={true} component={Screen1} />
<Scene key="screen2" component={Screen2} />
</Scene>
<Scene key="statusModal" component={StatusModal} />
<Scene key="errorModal" component={ErrorModal} />
<Scene key="loginModal" component={LoginModal} />
</Modal>
</Router>
3.3.8 Lightbox (<Lightbox>)
Lightbox
是用于將組件渲染在當(dāng)前組件上Scene
的組件 。與Modal
不同哆料,它將允許調(diào)整大小和背景的透明度
在下面的示例中缸剪,root
場景嵌套在中<Lightbox>
,因為它是第一個嵌套Scene
东亦,所以它將正常呈現(xiàn)杏节。如果要push
到loginLightbox
,他們將呈現(xiàn)為Lightbox
典阵,默認情況下將放置在當(dāng)前場景的頂部奋渔,允許透明的背景
//... import components
<Router>
<Lightbox>
<Scene key="root">
<Scene key="screen1" initial={true} component={Screen1} />
<Scene key="screen2" component={Screen2} />
</Scene>
{/* Lightbox components will lay over the screen, allowing transparency*/}
<Scene key="loginLightbox" component={loginLightbox} />
</Lightbox>
</Router>
3.3.9 Actions
- 該對象的主要工具是為您的應(yīng)用程序提供導(dǎo)航功能。 假設(shè)您的
Router
和Scenes
配置正確萄喳,請使用下列屬性在場景之間導(dǎo)航卒稳。 有些提供添加的功能,將React
道具傳遞到導(dǎo)航場景 - 這些可以直接使用他巨,例如,
Actions.pop()
將在源代碼中實現(xiàn)的操作减江,或者染突,您可以在場景類型中設(shè)置這些常量,當(dāng)您執(zhí)行Actions.main()
時辈灼,它將根據(jù)您的場景類型或默認值來執(zhí)行動作
Property | Type | Default | Description |
---|---|---|---|
[key] |
Function |
Object |
Actions 將'自動'使用路由器中的場景key 進行導(dǎo)航份企。如果需要跳轉(zhuǎn)頁面,可以直接使用Actions.key() 或Actions[key].call()
|
currentScene |
String |
返回當(dāng)前活動的場景 | |
jump |
Function |
(sceneKey: String, props: Object) |
用于切換到新選項卡. For Tabs only. |
popTo |
Function |
(sceneKey: String, props: Object) |
返回到指定的頁面 |
push |
Function |
(sceneKey: String, props: Object) |
跳轉(zhuǎn)到新頁面 |
refresh |
Function |
(props: Object) |
重新加載當(dāng)前頁面 |
replace |
Function |
(sceneKey: String, props: Object) |
從堆棧中彈出當(dāng)前場景巡莹,并將新場景推送到導(dǎo)航堆棧司志。沒有過度動畫 |
reset |
Function |
(sceneKey: String, props: Object) |
清除路由堆棧并將場景推入第一個索引. 沒有過渡動畫 |
drawerOpen |
Function |
如果可用,打開Drawer
|
|
drawerClose |
Function |
如果可用降宅,關(guān)閉Drawer
|
3.3.10 ActionConst
鍵入常量以確定
Scene
轉(zhuǎn)換骂远,這些是優(yōu)先于手動鍵入其值,因為項目更新時可能會發(fā)生更改
Property | Type | Default | Description |
---|---|---|---|
ActionConst.JUMP |
string |
'REACT_NATIVE_ROUTER_FLUX_JUMP' |
jump |
ActionConst.PUSH |
string |
'REACT_NATIVE_ROUTER_FLUX_PUSH' |
`push |
ActionConst.PUSH_OR_POP |
string |
'REACT_NATIVE_ROUTER_FLUX_PUSH_OR_POP' |
push |
ActionConst.REPLACE |
string |
'REACT_NATIVE_ROUTER_FLUX_REPLACE' |
replace |
ActionConst.BACK |
string |
'REACT_NATIVE_ROUTER_FLUX_BACK' |
pop |
ActionConst.BACK_ACTION |
string |
'REACT_NATIVE_ROUTER_FLUX_BACK_ACTION' |
pop |
ActionConst.POP_TO |
string |
'REACT_NATIVE_ROUTER_FLUX_POP_TO' |
popTo |
ActionConst.REFRESH |
string |
'REACT_NATIVE_ROUTER_FLUX_REFRESH' |
refresh |
ActionConst.RESET |
string |
'REACT_NATIVE_ROUTER_FLUX_RESET' |
reset |
ActionConst.FOCUS |
string |
'REACT_NATIVE_ROUTER_FLUX_FOCUS' |
N/A |
ActionConst.BLUR |
string |
'REACT_NATIVE_ROUTER_FLUX_BLUR' |
N/A |
ActionConst.ANDROID_BACK |
string |
'REACT_NATIVE_ROUTER_FLUX_ANDROID_BACK' |
N/A |
3.3.11 Universal and Deep Linking
- 考慮這樣一個
web
應(yīng)用程序和app
配對,這可能有一個urlhttps://thesocialnetwork.com/profile/1234/
- 如果我們同時構(gòu)建一個
web
應(yīng)用程序和一個移動應(yīng)用程序腰根,我們希望能夠通過path /profile/:id/
- 在web上激才,我們可能想要用一個路由器來打開我們的
<Profile />
和參數(shù){ id: 1234 }
- 在移動設(shè)備上,如果我們正確地設(shè)置了
Android / iOS
環(huán)境來啟動我們的應(yīng)用程序并打開RNRF<Router />
,额嘿,那么我們還需要導(dǎo)航到我們的移動<Profile />
場景和參數(shù){ id: 1234 }
<Router uriPrefix={'thesocialnetwork.com'}>
<Scene key="root">
<Scene key={'home'} component={Home} />
<Scene key={'profile'} path={"/profile/:id/"} component={Profile} />
<Scene key={'profileForm'} path={"/edit/profile/:id/"} component={ProfileForm} />
</Scene>
</Router>
如果用戶點擊
http://thesocialnetwork.com/profile/1234/
在他們的設(shè)備,他們會打開<Router/ >
,然后調(diào)用操作Actions.profile({ id:1234 })
四瘸恼、React Native基礎(chǔ)知識
4.1 常見組件
-
Image
圖片 -
Text
文本 -
View
包裹最外層
4.2 樣式
實際開發(fā)中組件的樣式會越來越復(fù)雜,我們建議使用
StyleSheet.create
來集中定義組件的樣式
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
export default class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigblue}>just bigblue</Text>
<Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
<Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
</View>
);
}
}
const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
AppRegistry.registerComponent('LotsOfStyles', () => LotsOfStyles);
常見的做法是按順序聲明和使用
style
屬性册养,以借鑒CSS
中的“層疊”做法(即后聲明的屬性會覆蓋先聲明的同名屬性)
4.3 高度與寬度
最簡單的給組件設(shè)定尺寸的方式就是在樣式中指定固定的
widt
h和height
东帅。React Native
中的尺寸都是無單位的,表示的是與設(shè)備像素密度無關(guān)的邏輯像素點
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
class FixedDimensionsBasics extends Component {
render() {
return (
<View>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
<View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
</View>
);
}
};
// 注冊應(yīng)用(registerComponent)后才能正確渲染
// 注意:只把應(yīng)用作為一個整體注冊一次球拦,而不是每個組件/模塊都注冊
AppRegistry.registerComponent('AwesomeProject', () => FixedDimensionsBasics);
- 在組件樣式中使用
flex
可以使其在可利用的空間中動態(tài)地擴張或收縮靠闭。一般而言我們會使用flex:1
來指定某個組件擴張以撐滿所有剩余的空間帐我。如果有多個并列的子組件使用了flex:1
,則這些子組件會平分父容器中剩余的空間阎毅。如果這些并列的子組件的flex
值不一樣焚刚,則誰的值更大,誰占據(jù)剩余空間的比例就更大(即占據(jù)剩余空間的比等于并列組件間flex
值的比) - 組件能夠撐滿剩余空間的前提是其父容器的尺寸不為零扇调。如果父容器既沒有固定的
width
和height
矿咕,也沒有設(shè)定flex
,則父容器的尺寸為零狼钮。其子組件如果使用了flex
碳柱,也是無法顯示的。
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
class FlexDimensionsBasics extends Component {
render() {
return (
// 試試去掉父View中的`flex: 1`熬芜。
// 則父View不再具有尺寸莲镣,因此子組件也無法再撐開。
// 然后再用`height: 300`來代替父View的`flex: 1`試試看涎拉?
<View style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}} />
<View style={{flex: 2, backgroundColor: 'skyblue'}} />
<View style={{flex: 3, backgroundColor: 'steelblue'}} />
</View>
);
}
};
AppRegistry.registerComponent('AwesomeProject', () => FlexDimensionsBasics);
4.4 處理文本輸入
TextInput
是一個允許用戶輸入文本的基礎(chǔ)組件季俩。它有一個名為onChangeText
的屬性,此屬性接受一個函數(shù),而此函數(shù)會在文本變化時被調(diào)用毡代。另外還有一個名為onSubmitEditing
的屬性递鹉,會在文本被提交后(用戶按下軟鍵盤上的提交鍵)調(diào)用
import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, View } from 'react-native';
export default class PizzaTranslator extends Component {
constructor(props) {
super(props);
this.state = {text: ''};
}
render() {
return (
<View style={{padding: 10}}>
<TextInput
style={{height: 40}}
placeholder="Type here to translate!"
onChangeText={(text) => this.setState({text})}
/>
<Text style={{padding: 10, fontSize: 42}}>
{this.state.text.split(' ').map((word) => word && '??').join(' ')}
</Text>
</View>
);
}
}
4.5 如何使用滾動視圖
ScrollView
是一個通用的可滾動的容器,你可以在其中放入多個組件和視圖,而且這些組件并不需要是同類型的。ScrollView
不僅可以垂直滾動,還能水平滾動(通過horizontal
屬性來設(shè)置)
-
ScrollView
適合用來顯示數(shù)量不多的滾動元素嘁酿。放置在ScollView
中的所有組件都會被渲染,哪怕有些組件因為內(nèi)容太長被擠出了屏幕外铐刘。如果你需要顯示較長的滾動列表陪每,那么應(yīng)該使用功能差不多但性能更好的ListView
組件
import React, { Component } from 'react';
import{ ScrollView, Image, Text, View } from 'react-native'
export default class IScrolledDownAndWhatHappenedNextShockedMe extends Component {
render() {
return(
<ScrollView>
<Text style={{fontSize:96}}>Scroll me plz</Text>
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
<Image source={require('./img/favicon.png')} />
</ScrollView>
);
}
}
4.6 如何使用長列表
-
FlatList
組件用于顯示一個垂直的滾動列表,其中的元素之間結(jié)構(gòu)近似而僅數(shù)據(jù)不同 -
FlatList
更適于長列表數(shù)據(jù)镰吵,且元素個數(shù)可以增刪檩禾。和ScrollView
不同的是,FlatList
并不立即渲染所有元素疤祭,而是優(yōu)先渲染屏幕上可見的元素 -
FlatList
組件必須的兩個屬性是data
和renderItem
盼产。data
是列表的數(shù)據(jù)源,而renderItem
則從數(shù)據(jù)源中逐個解析數(shù)據(jù)勺馆,然后返回一個設(shè)定好格式的組件來渲染
import React, { Component } from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';
export default class FlatListBasics extends Component {
render() {
return (
<View style={styles.container}>
<FlatList
data={[
{key: 'Devin'},
{key: 'Jackson'},
{key: 'James'},
{key: 'Joel'},
{key: 'John'},
{key: 'Jillian'},
{key: 'Jimmy'},
{key: 'Julie'},
]}
renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 22
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
})
4.7 網(wǎng)絡(luò)
默認情況下戏售,
iOS
會阻止所有非https
的請求。如果你請求的接口是http
協(xié)議草穆,那么首先需要添加一個App Transport Security
的例外
五灌灾、React Native布局
5.1 寬和高
- 一個組件的高度和寬度決定了它在屏幕上的尺寸,也就是大小
- 在
React Native
中尺寸是沒有單位的续挟,它代表了設(shè)備獨立像素
<View style={ {width:100,height:100,margin:40,backgroundColor:'gray'}}>
<Text style={ {fontSize:16,margin:20}}>尺寸</Text>
</View>
5.2 和web中的差異
React Native
中的FlexBox
和Web CSSS
上FlexBox
的不同之處
-
flexDirection
:React Native
中默認為flexDirection:'column'
紧卒,在Web CSS
中默認為flex-direction:'row'
-
alignItems
:React Native
中默認為alignItems:'stretch'
,在Web CSS
中默認align-items:'flex-start'
-
flex
: 相比Web CSS
的flex
接受多參數(shù)诗祸,如:flex: 2 2 10%
;跑芳,但在React Native
中flex
只接受一個參數(shù) - 不支持屬性:
align-content
轴总,flex-basis
,order
博个,flex-basis
怀樟,flex-flow
,flex-grow
盆佣,flex-shrink
5.3 Layout
以下屬性是
React Native
所支持的Flex
屬性
5.3.1 容器屬性
-
flexDirection
:row
column
row-reverse
column-reverse
-
flexWrap
:wrap
nowrap
-
justifyContent
:flex-start
flex-end
center
space-between
space-around
-
alignItems
:flex-start
flex-end
center
stretch
5.3.2 橫軸和豎軸
主軸即水平方向的軸線往堡,可以理解成橫軸,側(cè)軸垂直于主軸共耍,可以理解為豎軸
5.3.3 flexDirection
flexDirection
:row
column
row-reverse
column-reverse
flexDirection
屬性定義了父視圖中的子元素沿橫軸或側(cè)軸方片的排列方式
-
row
: 從左向右依次排列 -
row-reverse
: 從右向左依次排列 -
column(default)
: 默認的排列方式虑灰,從上向下排列 -
column-reverse
: 從下向上排列
<View style={ {flexDirection:'row-reverse',backgroundColor:"darkgray",marginTop:20}}>
<View style={ {width:40,height:40,backgroundColor:"darkcyan",margin:5}}>
<Text style={ {fontSize:16}}>1</Text>
</View>
<View style={ {width:40,height:40,backgroundColor:"darkcyan",margin:5}}>
<Text style={ {fontSize:16}}>2</Text>
</View>
<View style={ {width:40,height:40,backgroundColor:"darkcyan",margin:5}}>
<Text style={ {fontSize:16}}>3</Text>
</View>
<View style={ {width:40,height:40,backgroundColor:"darkcyan",margin:5}}>
<Text style={ {fontSize:16}}>4</Text>
</View>
</View>
5.3.4 flexWrap
flexWrap
屬性定義了子元素在父視圖內(nèi)是否允許多行排列,默認為nowrap
-
nowrap flex
的元素只排列在一行上痹兜,可能導(dǎo)致溢出 -
wrap flex
的元素在一行排列不下時穆咐,就進行多行排列
<View style={ {flexWrap:'wrap',flexDirection:'row',backgroundColor:"darkgray",marginTop:20}}>
</View>
5.3.5 justifyContent
justifyContent
屬性定義了瀏覽器如何分配順著父容器主軸的彈性(flex
)元素之間及其周圍的空間,默認為flex-start
justifyContent
:flex-start
flex-end
center
space-between
space-around
-
flex-start(default)
從行首開始排列字旭。每行第一個彈性元素與行首對齊对湃,同時所有后續(xù)的彈性元素與前一個對齊 -
flex-end
從行尾開始排列。每行最后一個彈性元素與行尾對齊遗淳,其他元素將與后一個對齊拍柒。 -
center
伸縮元素向每行中點排列。每行第一個元素到行首的距離將與每行最后一個元素到行尾的距離相同屈暗。 -
space-between
在每行上均勻分配彈性元素拆讯。相鄰元素間距離相同。每行第一個元素與行首對齊养叛,每行最后一個元素與行尾對齊往果。 -
space-around
在每行上均勻分配彈性元素。相鄰元素間距離相同一铅。每行第一個元素到行首的距離和每行最后一個元素到行尾的距離將會是相鄰元素之間距離的一半。
<View style={ {justifyContent:'center',flexDirection:'row',backgroundColor:"darkgray",marginTop:20}}>
</View>
[圖片上傳失敗...(image-3f1462-1565014986905)]
5.3.6 alignItems
alignItems
屬性以與justify-content
相同的方式在側(cè)軸方向上將當(dāng)前行上的彈性元素對齊堕油,默認為stretch
潘飘。
-
flex-start
元素向側(cè)軸起點對齊。 -
flex-end
元素向側(cè)軸終點對齊掉缺。 -
center
元素在側(cè)軸居中卜录。如果元素在側(cè)軸上的高度高于其容器,那么在兩個方向上溢出距離相同眶明。 -
stretch
彈性元素被在側(cè)軸方向被拉伸到與容器相同的高度或?qū)挾?/li>
<View style={ {justifyContent:'center',flexDirection:'row',backgroundColor:"darkgray",marginTop:20}}>
</View>
5.3.7 alignSelf
alignSelf
屬性以屬性定義了flex
容器內(nèi)被選中項目的對齊方式艰毒。注意:alignSelf
屬性可重寫靈活容器的alignItems
屬性
-
stretch
元素被拉伸以適應(yīng)容器。 -
center
元素位于容器的中心搜囱。 -
flex-start
元素位于容器的開頭丑瞧。 -
flex-end
元素位于容器的結(jié)尾
<View style={ {alignSelf:'baseline',width:60,height: 20,backgroundColor:"darkcyan",margin:5}}>
<Text style={ {fontSize:16}}>1</Text>
</View>
5.3.8 flex
flex
屬性定義了一個可伸縮元素的能力柑土,默認為0
<View style={ {flexDirection:'row',height:40, backgroundColor:"darkgray",marginTop:20}}>
<View style={ {flex:1,backgroundColor:"darkcyan",margin:5}}>
<Text style={ {fontSize:16}}>flex:1</Text>
</View>
<View style={ {flex:2,backgroundColor:"darkcyan",margin:5}}>
<Text style={ {fontSize:16}}>flex:2</Text>
</View>
<View style={ {flex:3,backgroundColor:"darkcyan",margin:5}}>
<Text style={ {fontSize:16}}>flex:3</Text>
</View>
</View>
[圖片上傳失敗...(image-459c64-1565014986905)]
5.4 視圖邊框
-
borderBottomWidth number
底部邊框?qū)挾?/li> -
borderLeftWidth number
左邊框?qū)挾?/li> -
borderRightWidth number
右邊框?qū)挾?/li> -
borderTopWidth number
頂部邊框?qū)挾?/li> -
borderWidth number
邊框?qū)挾?/li> -
border<Bottom|Left|Right|Top>Color
個方向邊框的顏色 -
borderColor
邊框顏色
5.5 尺寸
width number
height number
5.6 外邊距
-
margin number
外邊距 -
marginBottom number
下外邊距 -
marginHorizontal number
左右外邊距 -
marginLeft number
左外邊距 -
marginRight number
右外邊距 -
marginTop number
上外邊距 -
marginVertical number
上下外邊距
5.7 內(nèi)邊距
-
padding number
內(nèi)邊距 -
paddingBottom number
下內(nèi)邊距 -
paddingHorizontal number
左右內(nèi)邊距 -
paddingLeft number
做內(nèi)邊距 -
paddingRight number
右內(nèi)邊距 -
paddingTop number
上內(nèi)邊距 -
paddingVertical number
上下內(nèi)邊距
5.8 邊緣
-
left number
屬性規(guī)定元素的左邊緣。該屬性定義了定位元素左外邊距邊界與其包含塊左邊界之間的偏移绊汹。 -
right number
屬性規(guī)定元素的右邊緣稽屏。該屬性定義了定位元素右外邊距邊界與其包含塊右邊界之間的偏移 -
top number
屬性規(guī)定元素的頂部邊緣。該屬性定義了一個定位元素的上外邊距邊界與其包含塊上邊界之間的偏移西乖。 -
bottom number
屬性規(guī)定元素的底部邊緣狐榔。該屬性定義了一個定位元素的下外邊距邊界與其包含塊下邊界之間的偏移。
5.9 定位(position)
position:absolute|relative
屬性設(shè)置元素的定位方式获雕,為將要定位的元素定義定位規(guī)則薄腻。
-
absolute
:生成絕對定位的元素,元素的位置通過 "left
", "top
", "right
" 以及 "bottom
" 屬性進行規(guī)定届案。 -
relative
:生成相對定位的元素庵楷,相對于其正常位置進行定位。因此萝玷,"left:20
" 會向元素的LEFT
位置添加20
像素嫁乘。
六、React Native適配
6.1 Platform.OS
為了提高代碼的兼容性球碉,我們有時需要判斷當(dāng)前系統(tǒng)的平臺蜓斧,然后做一些適配。比如睁冬,我們在使用
StatusBar
做導(dǎo)航欄的時候挎春,在iOS
平臺下根視圖的位置默認情況下是占據(jù)狀態(tài)欄的位置的,我們通常希望狀態(tài)欄下面能顯示一個導(dǎo)航欄豆拨,所以我們需要為StatusBar
的外部容器設(shè)置一個高度
<View style={{height: Platform.OS === 'ios' ? 20:0}}>
<StatusBar {...this.props.statusBar} />
</View>;
6.2 留意api doc的android或ios標(biāo)識
并不是所有
React Native
的一些api
或組件的一些屬性和方法都兼容Android
和iOS
直奋,在React Native
的api doc
中通常會在一些屬性或方法的前面加上android
或ios
的字樣來標(biāo)識該屬性或方法所支持的平臺,如
android renderToHardwareTextureAndroid bool
ios shouldRasterizeIOS bool
在上述代碼中施禾,
renderToHardwareTextureAndroid bool
只支持Android
平臺脚线,ios shouldRasterizeIOS bool
只支持iOS
平臺,所有我們在使用這些帶有標(biāo)記的屬性或方法的時候就需要考慮對于它們不兼容的平臺我們是否需要做相應(yīng)的適配了
6.3 組件選擇
比如弥搞,我們要開發(fā)一款應(yīng)用需要用到導(dǎo)航組件邮绿,
在React Native
組件中有NavigatorIOS
與Navigator
兩個導(dǎo)航組件來供我們選擇,從api doc
中我們可以看出NavigatorIOS
只支持iOS
平臺攀例,Navigator
則兩個平臺都支持船逮。
所以如果我們要開發(fā)的應(yīng)用需要適配Android
和iOS
,那么Navigator
才是最佳的選擇粤铭。
為了提高代碼的復(fù)用性與兼容性建議大家在選擇React Native
組件的時候要多留意該組件是不是兼容Android
和iOS
挖胃,盡量選擇Android
和iOS
平臺都兼容的組件。
6.4 圖片適配
開發(fā)一款應(yīng)用少不了的需要用到圖標(biāo)。無論是
Android
還是iOS
酱鸭,現(xiàn)在不同分辨率的設(shè)備越來越多吗垮,我們希望這些圖標(biāo)能夠適配不同分辨率的設(shè)備。為此我們需要為每個圖標(biāo)提供1x
凛辣、2x
抱既、3x
三種大小的尺寸,React Native
會根據(jù)屏幕的分辨率來動態(tài)的選擇顯示不同尺寸的圖片扁誓。比如:在img
目錄下有如下三種尺寸的check.png
└── img
├── check.png
├── check@2x.png
└── check@3x.png
那么我們就可以通過下面的方式來使用check.png
<Image source={require('./img/check.png')} />
提示:我們在使用具有不同分辨率的圖標(biāo)時防泵,一定要引用標(biāo)準(zhǔn)分辨率的圖片如
require('./img/check.png')
,如果我們這樣寫require('./img/check@2x.png')
蝗敢,那么應(yīng)用在不同分辨率的設(shè)備上都只會顯示check@2x.png
圖片捷泞,也就無法達到圖片自適配的效果。
七寿谴、react-navigation
文檔 https://reactnavigation.org/docs/zh-Hans/getting-started.html
7.1 頁面切換
- 跳轉(zhuǎn)到新的頁面(將新路由推送到堆棧導(dǎo)航器锁右,如果它尚未在堆棧中,則跳轉(zhuǎn)到該頁面)
this.props.navigation.navigate('Details',{})
- 不考慮現(xiàn)有導(dǎo)航歷史的情況下添加其他路由
this.props.navigation.push
- 返回
this.props.navigation.goBack()
- 返回到堆棧中的第一個頁面
navigation.popToTop()
7.2 傳遞參數(shù)給路由
-
navigate
接受可選的第二個參數(shù)讶泰,以便將參數(shù)傳遞給要導(dǎo)航到的路由咏瑟。 例如:this.props.navigation.navigate('RouteName', {paramName: 'value'})
。 - 我們可以使用
this.props.navigation.getParam
讀取參數(shù) - 你也可以使用
this.props.navigation.state.params
作為getParam
的替代方案痪署, 如果未指定參數(shù)码泞,它的值是null
/* 1. Navigate to the Details route with params */
this.props.navigation.navigate('Details', {
itemId: 86,
otherParam: 'anything you want here',
});
/* 2. Get the param, provide a fallback value if not available */
const { navigation } = this.props;
const itemId = navigation.getParam('itemId', 'NO-ID');
const otherParam = navigation.getParam('otherParam', 'some default value');
7.3 配置標(biāo)題欄
每個頁面組件可以有一個名為
navigationOptions
的靜態(tài)屬性,它是一個對象或一個返回包含各種配置選項的對象的函數(shù)狼犯。我們用于設(shè)置標(biāo)題欄的標(biāo)題的是title
這個屬性余寥,如以下示例所示
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
};
/* render function, etc */
}
class DetailsScreen extends React.Component {
static navigationOptions = {
title: 'Details',
};
/* render function, etc */
}
createStackNavigator
默認情況下按照平臺慣例設(shè)置,所以在iOS
上標(biāo)題居中悯森,在Android
上左對齊
7.3.1 動態(tài)設(shè)置標(biāo)題
class DetailsScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('otherParam', 'A Nested Details Screen'),
};
};
/* render function, etc */
}
7.3.2 使用setParams更新navigationOptions
通常有必要從已加載的頁面組件本身更新當(dāng)前頁面的
navigationOptions
配置宋舷。 我們可以使用this.props.navigation.setParams
來做到這一點
/* Inside of render() */
<Button
title="Update the title"
onPress={() => this.props.navigation.setParams({otherParam: 'Updated!'})}
/>
7.3.3 調(diào)整標(biāo)題樣式
定制標(biāo)題樣式時有三個關(guān)鍵屬性:headerStyle、headerTintColor和headerTitleStyle
-
headerStyle
:一個應(yīng)用于header
的最外層View
的 樣式對象瓢姻, 如果你設(shè)置backgroundColor
祝蝠,他就是header
的顏色 -
headerTintColor
:返回按鈕和標(biāo)題都使用這個屬性作為它們的顏色。 在下面的例子中幻碱,我們將tint color
設(shè)置為白色(#fff)续膳,所以返回按鈕和標(biāo)題欄標(biāo)題將變?yōu)榘咨?/li> -
headerTitleStyle
:如果我們想為標(biāo)題定制fontFamily
,fontWeight
和其他Text
樣式屬性收班,我們可以用它來完成。
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
/* render function, etc */
}
7.3.4 統(tǒng)一配置所有頁面頭部defaultNavigationOptions
在初始化時谒兄,還可以在
stack navigator
的配置中指定共享的navigationOptions
靜態(tài)屬性優(yōu)先于該配置
const Home = createStackNavigator(
{
Feed: ExampleScreen,
Profile: ExampleScreen,
}, {
defaultNavigationOptions: {
headerTintColor: '#fff',
headerStyle: {
backgroundColor: '#000',
},
},
navigationOptions: {
tabBarLabel: 'Home!',
},
}
);
7.3.5 覆蓋共享的navigationOptions
class DetailsScreen extends React.Component {
static navigationOptions = ({ navigation, navigationOptions }) => {
const { params } = navigation.state;
return {
title: params ? params.otherParam : 'A Nested Details Screen',
/* These values are used instead of the shared configuration! */
headerStyle: {
backgroundColor: navigationOptions.headerTintColor,
},
headerTintColor: navigationOptions.headerStyle.backgroundColor,
};
};
/* render function, etc */
}
7.4 標(biāo)題欄和其所屬的頁面之間的交互
class HomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerTitle: <LogoTitle />,
headerRight: (
<Button
onPress={navigation.getParam('increaseCount')} //執(zhí)行事件
title="+1"
color="#fff"
/>
),
};
};
componentDidMount() {
// 設(shè)置事件
this.props.navigation.setParams({ increaseCount: this._increaseCount });
}
state = {
count: 0,
};
_increaseCount = () => {
this.setState({ count: this.state.count + 1 });
};
/* later in the render function we display the count */
}
八摔桦、打包
8.1 修改app名稱、logo、啟動圖
修改圖標(biāo)和名稱
找到根目錄
/android/app/src/main/res
啟動頁
- 在
react-native
的android
中的啟動圖和IOS
不相同點在于邻耕,android
沒有默認的啟動圖鸥咖,在IOS
里面有- 使用插件
import SplashScreen from 'react-native-splash-screen';
- https://github.com/crazycodeboy/react-native-splash-screen
react-native ios端icon和啟動圖的設(shè)置
8.2 Android打包APK
1. 在Android/app目錄下執(zhí)行這條命令
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD=123456
MYAPP_RELEASE_KEY_PASSWORD=123456
2. 在app/build.gradle中配置
signingConfigs {
release {
if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
storeFile file(MYAPP_RELEASE_STORE_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
}
buildTypes {
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
signingConfig signingConfigs.release
}
}
3. 減少打包apk大小
4. 輸出目錄
android/app/build/outputs/apk/
8.3 IOS打包
九、更多參考
- 常用的react-native組件整理
- React Native 研究與實踐
- 從navigator到react-navigation進階教程
- React Native0.50+開發(fā)指導(dǎo)
- React Native 集成分享第三方登錄功能分享第三方登錄模塊開發(fā)(iOS)
- React Native 集成分享第三方登錄功能分享第三方登錄模塊開發(fā)(Android)
- 教你輕松在React Native中集成統(tǒng)計的功能
- 教你輕松修改React Native端口
- React Native Android iOS 教程快速創(chuàng)建React Native App
- Mac(OSX)平臺搭建React Native開發(fā)環(huán)境