React Native學(xué)習(xí)總結(jié)篇

一赠摇、環(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郎任,然后點擊左上角運行即可

更多詳情 https://reactnative.cn/docs/getting-started.html

3. 遠程調(diào)試

  • ctrl + R刷新
  • ctrl + D 選擇對應(yīng)的工具調(diào)試
image.png

Enable Live Reload

當(dāng)你的js代碼發(fā)生變化后秧耗,React Native會自動生成bundle然后傳輸?shù)侥M器或手機上

[圖片上傳失敗...(image-e2a80d-1565014986904)]

在瀏覽器中打開 http://localhost:8081/debugger-ui

image.png

巧用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è)備名稱
image.png

1.1.2 安卓環(huán)境搭建

安裝依賴

必須安裝的依賴有:Node款票、WatchmanReact 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 StudioSDK Manager 中選擇安裝各版本的 SDK

你可以在 Android Studio 的歡迎界面中找到 SDK Manager刃唐。點擊"Configure",然后就能看到"SDK Manager"界轩。

image

SDK Manager中選擇"SDK Platforms"選項卡画饥,然后在右下角勾選"Show Package Details"。展開Android 8.1 (Oreo)選項浊猾,確保勾選了下面這些組件(重申你必須使用穩(wěn)定的翻墻工具抖甘,否則可能都看不到這個界面):

  • Android SDK Platform 27
  • Intel x86 Atom_64 System Image(官方模擬器鏡像文件,使用非官方模擬器不需要安裝此組件)
image.png

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版本艰额。你可以同時安裝多個其他版本
image.png

最后點擊"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自帶工具運行

image.png

使用genymotion模擬器

去官網(wǎng)需要注冊并下載https://www.genymotion.com/袒啼,需要注冊登錄再下載的哈扮。注意下載with virtualBox版本,然后安裝完成后需要登錄蚓再,就是剛才注冊的賬號滑肉。登錄后進入這個頁面做兩個操作

image.png

點擊settings,選擇adb設(shè)置sdk就是剛才一直用的sdk安裝路徑,如下

image.png

啟動項目摘仅,點擊genymotion里的start啟動我們剛才安裝好的的虛擬設(shè)備靶庙,是這個樣子的,此時我們剛才初始化的項目還沒連上虛擬設(shè)備

image.png

然后在我們的工程項目里執(zhí)行adb devices會列出當(dāng)前啟動的虛擬設(shè)備娃属,能檢測到說明沒問題六荒,如下圖里最后一行顯示的就是剛才我們開啟的genymotion那臺虛擬設(shè)備

image.png

最后項目目錄里執(zhí)行

react-native run-android

打開genymotion,歡迎頁面出來了矾端,成功掏击,修改一下文字,重新加載一遍秩铆,成功

  • 第一次默認不是熱加載形式砚亭,就是改變文件內(nèi)容需要手動刷新的,這里設(shè)置一下熱加載殴玛,以后內(nèi)容這里就會自動刷新捅膘,mac是執(zhí)行command+r,選擇第四個hot reloading
image.png

運行react-native run-andriod 會下載很多東西族阅,然后出現(xiàn)這個標(biāo)志說明編譯沒有問題篓跛,還缺少一個模擬設(shè)備

image.png
image.png
image.png

如果是安卓5.0以下需要配置一下IP

image.png

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命令:

image.png

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

https://blog.csdn.net/yiifaa/article/details/78862507

二盖奈、矢量圖標(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文件

image.png

在xcode的Info.plist文件中,加入: Fonts provided by application數(shù)組

image.png

打開終端垦江,輸入:rnpm link帽馋,回車后會看到Fonts provided by application下加入如下字體

image.png

重新運行react項目,終端輸入:react-native run-ios疫粥,可以看到效果了

三茬斧、react-native-router-flux的使用

https://github.com/aksonov/react-native-router-flux

3.1 簡介

特性

react-native-router-flux 是一個路由包.在一個中心區(qū)域定義可切換scene模塊。在使用過程中梗逮,跟react-native提供的navigator的區(qū)別是你不需要有navigator對象项秉。你可以在任意地方使用簡單的語法去控制scene的切換,如:Actions.login({username, password}) or Actions.profile({profile}) or 甚至Actions.profile(123) ,其中login profile等是路由的key慷彤,通過調(diào)用key來切換路由

  • 所有的參數(shù)將被注入到this.props中給Sene組件使用

功能和亮點

  • 可定制的導(dǎo)航條:由Scene或者Scenestate去控制導(dǎo)航條的showhide
  • 嵌套導(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>)
    }
}

運行就可以看到下面的效果:

image.png

簡單就完成了兩個頁面之間的切換

每一個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=pageTwoScene顯示出來焰望,如果傳有參數(shù)的話骚亿,參數(shù)也會傳入Scene組件中
render() {
  const goToPageTwo = () => Actions.pageTwo({text: 'Hello World!'}); 
  return (
    
      This is PageOne!
    
  )
}

我們傳遞一個參數(shù)名為text 。值為Hello World柿估!如下所示循未,我們就可以在key=pageTwoscenecomponent屬性置頂?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ù)傳遞的效果了

image.png

可以看到從 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>)
};
image.png

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 允許集成諸如Reduxconnect)和Mobxobserver)之類的狀態(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)航欄中的圖像中覆蓋titleImage
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的效果展示愿伴,可以自定義iconlabel

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 抽屜是在右邊還是左邊」倭保可選屬性rightleft
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)。如果要pushstatusModal阀圾,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)杏节。如果要pushloginLightbox,他們將呈現(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è)您的RouterScenes配置正確萄喳,請使用下列屬性在場景之間導(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è)定尺寸的方式就是在樣式中指定固定的width和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值的比)
  • 組件能夠撐滿剩余空間的前提是其父容器的尺寸不為零扇调。如果父容器既沒有固定的widthheight矿咕,也沒有設(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組件必須的兩個屬性是datarenderItem盼产。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中的FlexBoxWeb CSSSFlexBox的不同之處

  • flexDirection: React Native中默認為flexDirection:'column'紧卒,在Web CSS中默認為flex-direction:'row'
  • alignItems: React Native中默認為alignItems:'stretch',在Web CSS中默認align-items:'flex-start'
  • flex: 相比Web CSSflex接受多參數(shù)诗祸,如:flex: 2 2 10%;跑芳,但在 React Nativeflex只接受一個參數(shù)
  • 不支持屬性:align-content轴总,flex-basisorder博个,flex-basis怀樟,flex-flowflex-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è)軸垂直于主軸共耍,可以理解為豎軸

image

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>
image

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>
image

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>
image

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>
image

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或組件的一些屬性和方法都兼容AndroidiOS直奋,在React Nativeapi doc中通常會在一些屬性或方法的前面加上androidios的字樣來標(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組件中有NavigatorIOSNavigator兩個導(dǎo)航組件來供我們選擇,從api doc中我們可以看出NavigatorIOS只支持iOS平臺攀例,Navigator則兩個平臺都支持船逮。
所以如果我們要開發(fā)的應(yīng)用需要適配AndroidiOS,那么Navigator才是最佳的選擇粤铭。

為了提高代碼的復(fù)用性與兼容性建議大家在選擇React Native組件的時候要多留意該組件是不是兼容AndroidiOS挖胃,盡量選擇AndroidiOS平臺都兼容的組件。

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)題定制fontFamilyfontWeight和其他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

image.png

啟動頁

image.png

react-native ios端icon和啟動圖的設(shè)置

http://www.reibang.com/p/b49629529a95

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
image.png
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
      }
  }
image.png

3. 減少打包apk大小

image.png

4. 輸出目錄

android/app/build/outputs/apk/

8.3 IOS打包

九、更多參考

原文 http://blog.poetries.top/2019/06/08/rn-summary/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末兄世,一起剝皮案震驚了整個濱河市啼辣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌御滩,老刑警劉巖鸥拧,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異削解,居然都是意外死亡富弦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門氛驮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腕柜,“玉大人,你說我怎么就攤上這事矫废≌电停” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵蓖扑,是天一觀的道長唉铜。 經(jīng)常有香客問我,道長赵誓,這世上最難降的妖魔是什么打毛? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮俩功,結(jié)果婚禮上幻枉,老公的妹妹穿的比我還像新娘。我一直安慰自己诡蜓,他們只是感情好熬甫,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蔓罚,像睡著了一般椿肩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上豺谈,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天郑象,我揣著相機與錄音,去河邊找鬼茬末。 笑死厂榛,一個胖子當(dāng)著我的面吹牛盖矫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播击奶,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼辈双,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了柜砾?” 一聲冷哼從身側(cè)響起湃望,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎痰驱,沒想到半個月后证芭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡萄唇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年檩帐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片另萤。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡湃密,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出四敞,到底是詐尸還是另有隱情泛源,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布忿危,位于F島的核電站达箍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏铺厨。R本人自食惡果不足惜缎玫,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望解滓。 院中可真熱鬧赃磨,春花似錦、人聲如沸洼裤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腮鞍。三九已至值骇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間移国,已是汗流浹背吱瘩。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留迹缀,地道東北人使碾。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓皱卓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親部逮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容