国产成人精品999视频&日本一区二区亚洲人妻精品&久久久精品国产99久久精&99热这里只有成人精品国产&精品国产剧情av一区二区&成人亚洲精品久久久久app&国产精品美女高潮抽搐A片

React Native 備忘清單

NPM version Downloads Repo Dependents Github repo

適合初學(xué)者的綜合 React Native 備忘清單,在開(kāi)始 React Native 之前需要先掌握 react 庫(kù)

入門(mén)

macOS 安裝 iOS 環(huán)境

您將需要 Node、Watchman、React Native 命令行界面、Ruby 版本管理器、Xcode 和 CocoaPods

$ brew install node # Node 14 或更新版本
$ brew install watchman

使用 .ruby-version 文件來(lái)確保您的 Ruby 版本與所需的一致

$ ruby --version
# ruby 2.7.5

注意: macOS 12.5.1 附帶了 Ruby 2.6.8,這不是 React Native 所要求的,React Native 70+ 需要 Ruby 2.7.5,可以使用下面工具切換版本:

創(chuàng)建一個(gè)新的應(yīng)用程序

$ npx react-native init MyApp
# 指定 React Native 版本創(chuàng)建
$ npx react-native init MyApp \
  --version X.XX.X
# 創(chuàng)建 typescript 版本項(xiàng)目
$ npx react-native init MyTSApp \
--template react-native-template-typescript

安裝依賴(lài)

$ yarn install # 根目錄運(yùn)行
$ cd ios # 進(jìn)入 ios 目錄
$ bundle install # 安裝 Bundler
$ bundle exec pod install # 以安裝 iOS 依賴(lài)項(xiàng)

運(yùn)行你的 React Native 應(yīng)用程序

# 啟動(dòng)監(jiān)聽(tīng)打包 JS 服務(wù),默認(rèn)端口 8081
$ npx react-native start
# 指定 8088 端口
$ npx react-native start --port=8088
# 啟動(dòng) iOS 模擬器運(yùn)行你的應(yīng)用
$ npx react-native run-ios

:---
? + ? + 2設(shè)備窗格
? + R構(gòu)建并運(yùn)行
搖動(dòng)您的設(shè)備打開(kāi)開(kāi)發(fā)者菜單

macOS 安裝 Android 環(huán)境

您將需要 Node、Watchman、React Native 命令行界面、JDK 和 Android Studio

$ brew install node # Node 14 或更新版本
$ brew install watchman

我們建議使用 Homebrew 安裝名為 Azul Zulu 的 OpenJDK 發(fā)行版,發(fā)行版為 IntelM1 Mac 提供 JDK

$ brew tap homebrew/cask-versions
$ brew install --cask zulu11

下載安裝 Android Studio

  • Android SDK
  • Android SDK Platform
  • Android Virtual Device

安裝安卓SDK,React Native 應(yīng)用需要 Android 12 (S) SDK,通過(guò) Android Studio 中的 SDK 管理器安裝其他 Android SDK

SDK 管理器也可以在 Android Studio “Preferences” 對(duì)話框中找到,位于 Appearance & BehaviorSystem SettingsAndroid SDK

  • Android SDK Platform 31
  • Intel x86 Atom_64 System ImageGoogle APIs Intel x86 Atom System Image 或 (for Apple M1 Silicon) Google APIs ARM 64 v8a System Image

接下來(lái),選擇 SDK Tools 選項(xiàng)卡并選中 Show Package Details 旁邊的復(fù)選框。 查找并展開(kāi) Android SDK Build-Tools 條目,然后確保選擇了 31.0.0。最后點(diǎn)擊 Apply 下載并安裝 Android SDK 及相關(guān)構(gòu)建工具

配置 ANDROID_SDK_ROOT 環(huán)境變量

將以下行添加到您的 $HOME/.bash_profile$HOME/.bashrc(如果您使用的是 zsh,則為 ~/.zprofile~/.zshrc)配置文件:

export ANDROID_SDK_ROOT=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_SDK_ROOT/emulator
export PATH=$PATH:$ANDROID_SDK_ROOT/platform-tools

創(chuàng)建一個(gè)新的應(yīng)用程序

$ npx react-native init MyApp
# 指定 React Native 版本創(chuàng)建
$ npx react-native init MyApp --version X.XX.X
# 創(chuàng)建 typescript 版本項(xiàng)目
$ npx react-native init MyTSApp --template react-native-template-typescript

安裝依賴(lài)

$ yarn install # 根目錄運(yùn)行

使用虛擬設(shè)備

  • 使用 Android Studio 打開(kāi) ./AwesomeProject/android
  • 從 Android Studio 中打開(kāi) AVD 管理器 來(lái)查看可用的 Android 虛擬設(shè)備 (AVD) 列表
  • 第一次,您可能需要?jiǎng)?chuàng)建一個(gè)新的 AVD。選擇 Create Virtual Device...,然后從列表中選擇任何電話并單擊“下一步”,然后選擇 S API Level 31 image。

運(yùn)行你的 React Native 應(yīng)用程序

# 啟動(dòng)監(jiān)聽(tīng)打包 JS 服務(wù)
$ npx react-native start
# 啟動(dòng) iOS 模擬器運(yùn)行你的應(yīng)用
$ npx react-native run-ios

打開(kāi) React Native Debug 菜單

:---
? + M(Android)打開(kāi)開(kāi)發(fā)者菜單
? + D(iOS)打開(kāi)開(kāi)發(fā)者菜單
Ctrl + D(Linux)打開(kāi)開(kāi)發(fā)者菜單
搖動(dòng)您的設(shè)備打開(kāi)開(kāi)發(fā)者菜單
按兩次 R構(gòu)建并運(yùn)行

基本組件

View

import React from "react";
import { View, Text } from "react-native";

export default function ViewExample() {
  return (
    <View
      style={{
        backgroundColor: "red",
        flex: 0.5
      }}
    />
  );
};

構(gòu)建 UI 的最基本組件

Text

import React from 'react';
import { Text } from 'react-native';
import { StyleSheet } from 'react-native';

export default function BoldBeautiful() {
  return (
    <Text style={styles.baseText}>
      我是粗體
      <Text style={styles.innerText}>
        和紅色
      </Text>
    </Text>
  );
};
const styles = StyleSheet.create({
  baseText: { fontWeight: 'bold' },
  innerText: { color: 'red' }
});

用于顯示文本的組件

TextInput

import React from "react";
import { SafeAreaView, StyleSheet, TextInput } from "react-native";

export default function UseTextInput() {
  const [
    text, onChangeText
  ] = React.useState("Useless Text");
  return (
    <SafeAreaView>
      <TextInput
        onChangeText={onChangeText}
        value={text}
      />
    </SafeAreaView>
  );
};

用于通過(guò)鍵盤(pán)將文本輸入應(yīng)用程序的組件

Image

import React from 'react';
import { View, Image, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  container: { paddingTop: 50, },
  tinyLogo: { width: 50, height: 50, },
  logo: { width: 66, height: 58, },
});

const DisplayAnImage = () => {
  return (
    <View style={styles.container}>
      <Image
        style={styles.tinyLogo}
        source={require('@expo/snack-static/react-native-logo.png')}
      />
      <Image
        style={styles.tinyLogo}
        source={{
          uri: 'https://reactnative.dev/img/tiny_logo.png',
        }}
      />
      <Image
        style={styles.logo}
        source={{
          uri: 'data:image/png;base64,iVBORw0K.....',
        }}
      />
    </View>
  );
}

export default DisplayAnImage;

用于顯示圖像的組件

ScrollView

import React from 'react';
import { StyleSheet, Text, SafeAreaView, ScrollView, StatusBar } from 'react-native';

export const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <ScrollView style={styles.scrollView}>
        <Text style={styles.text}>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit,
          sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
          Ut enim ad minim veniam, quis nostrud exercitation
          ullamco laboris nisi ut aliquip ex ea commodo consequat.
          Duis aute irure dolor in reprehenderit in voluptate velit
          esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
          occaecat cupidatat non proident, sunt in culpa qui officia
          deserunt mollit anim id est laborum.
        </Text>
      </ScrollView>
    </SafeAreaView>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: StatusBar.currentHeight,
  },
  scrollView: {
    backgroundColor: 'pink',
    marginHorizontal: 20,
  },
  text: {
    fontSize: 42,
  },
});

提供一個(gè)可以承載多個(gè)組件和視圖的滾動(dòng)容器

StyleSheet

import React from "react";
import { StyleSheet, Text, View } from "react-native";

export const App = () => (
  <View style={styles.container}>
    <Text style={styles.title}>
      React Native
    </Text>
  </View>
);

const styles = StyleSheet.create({
  container: {
    padding: 24,
    backgroundColor: "#eaeaea"
  },
  title: {
    backgroundColor: "#61dafb",
    color: "#20232a",
    textAlign: "center",
  }
});

提供類(lèi)似于 CSS 樣式表的抽象層

用戶(hù)界面

Button

import { Button } from "react-native";

<Button
  onPress={onPressLearnMore}
  title="Learn More"
  color="#841584"
  accessibilityLabel="了解紫色按鈕的更多信息"
/>

一個(gè)基本的按鈕組件,用于處理應(yīng)該在任何平臺(tái)上都能很好地呈現(xiàn)的觸摸

Switch

import { Switch } from "react-native";

<Switch
  trackColor={{ false: "#767577", true: "#81b0ff" }}
  thumbColor={isEnabled ? "#f5dd4b" : "#f4f3f4"}
  ios_backgroundColor="#3e3e3e"
  onValueChange={toggleSwitch}
  value={isEnabled}
/>

呈現(xiàn)布爾輸入

列表視圖

SectionList

import React from "react";
import {
  StyleSheet, Text, View, SafeAreaView, SectionList, StatusBar
} from "react-native";

const DATA = [
  {
    title: "Main dishes",
    data: ["Pizza", "Burger", "Risotto"]
  },
  {
    title: "Sides",
    data: ["French Fries", "Onion Rings", "Fried Shrimps"]
  },
  {
    title: "Drinks",
    data: ["Water", "Coke", "Beer"]
  },
  {
    title: "Desserts",
    data: ["Cheese Cake", "Ice Cream"]
  }
];

const Item = ({ title }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{title}</Text>
  </View>
);

const App = () => (
  <SafeAreaView style={styles.container}>
    <SectionList
      sections={DATA}
      keyExtractor={(item, index) => item + index}
      renderItem={({ item }) => <Item title={item} />}
      renderSectionHeader={({ section: { title } }) => (
        <Text style={styles.header}>{title}</Text>
      )}
    />
  </SafeAreaView>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: StatusBar.currentHeight,
    marginHorizontal: 16
  },
  item: {
    backgroundColor: "#f9c2ff",
    padding: 20,
    marginVertical: 8
  },
  header: { fontSize: 32, backgroundColor: "#fff" },
  title: { fontSize: 24 }
});

export default App;

FlatList

import React from 'react';
import {
  SafeAreaView, View, FlatList, StyleSheet, Text, StatusBar
} from 'react-native';

const DATA = [
  {
    id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
    title: 'First Item',
  },
  {
    id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
    title: 'Second Item',
  },
  {
    id: '58694a0f-3da1-471f-bd96-145571e29d72',
    title: 'Third Item',
  },
];

const Item = ({ title }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{title}</Text>
  </View>
);

const App = () => {
  const renderItem = ({ item }) => (
    <Item title={item.title} />
  );

  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        data={DATA}
        renderItem={renderItem}
        keyExtractor={item => item.id}
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: StatusBar.currentHeight || 0,
  },
  item: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 32,
  },
});

export default App;

Android 組件和 API

BackHandler

import React, { useEffect } from "react";
import {
  Text, View, StyleSheet, BackHandler, Alert
} from "react-native";

const App = () => {
  useEffect(() => {
    const backAction = () => {
      Alert.alert("Hold on!", "你確定要回去嗎?", [
        {
          text: "Cancel",
          onPress: () => null,
          style: "cancel"
        },
        { text: "YES", onPress: () => BackHandler.exitApp() }
      ]);
      return true;
    };

    const backHandler = BackHandler.addEventListener(
      "hardwareBackPress",
      backAction
    );

    return () => backHandler.remove();
  }, []);

  return (
    <View style={styles.container}>
      <Text style={styles.text}>點(diǎn)擊后退按鈕!</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  text: {
    fontSize: 18,
    fontWeight: "bold"
  }
});

export default App;

檢測(cè)硬件按鈕按下以進(jìn)行后退導(dǎo)航

DrawerLayoutAndroid

import React, { useRef, useState } from "react";
import {
  Button, DrawerLayoutAndroid, Text, StyleSheet, View
} from "react-native";

const App = () => {
  const drawer = useRef(null);
  const [drawerPosition, setDrawerPosition] = useState("left");
  const changeDrawerPosition = () => {
    if (drawerPosition === "left") {
      setDrawerPosition("right");
    } else {
      setDrawerPosition("left");
    }
  };

  const navigationView = () => (
    <View style={[styles.container, styles.navigationContainer]}>
      <Text style={styles.paragraph}>I'm in the Drawer!</Text>
      <Button
        title="Close drawer"
        onPress={() => drawer.current.closeDrawer()}
      />
    </View>
  );

  return (
    <DrawerLayoutAndroid
      ref={drawer}
      drawerWidth={300}
      drawerPosition={drawerPosition}
      renderNavigationView={navigationView}
    >
      <View style={styles.container}>
        <Text style={styles.paragraph}>
          Drawer on the {drawerPosition}!
        </Text>
        <Button
          title="Change Drawer Position"
          onPress={() => changeDrawerPosition()}
        />
        <Text style={styles.paragraph}>
          Swipe from the side or press button below to see it!
        </Text>
        <Button
          title="Open drawer"
          onPress={() => drawer.current.openDrawer()}
        />
      </View>
    </DrawerLayoutAndroid>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
    padding: 16
  },
  navigationContainer: {
    backgroundColor: "#ecf0f1"
  },
  paragraph: {
    padding: 16,
    fontSize: 15,
    textAlign: "center"
  }
});

export default App;

在 Android 上呈現(xiàn) DrawerLayout

PermissionsAndroid

import React from "react";
import {
  Button, PermissionsAndroid,
  SafeAreaView, StatusBar, StyleSheet, Text, View
} from "react-native";

const requestCameraPermission = async () => {
  try {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.CAMERA,
      {
        title: "Cool Photo App Camera Permission",
        message:
          "Cool Photo App needs access to your camera " +
          "so you can take awesome pictures.",
        buttonNeutral: "Ask Me Later",
        buttonNegative: "Cancel",
        buttonPositive: "OK"
      }
    );
    if (granted === PermissionsAndroid.RESULTS.GRANTED) {
      console.log("You can use the camera");
    } else {
      console.log("Camera permission denied");
    }
  } catch (err) {
    console.warn(err);
  }
};

const App = () => (
  <View style={styles.container}>
    <Text style={styles.item}>Try permissions</Text>
    <Button
      title="request permissions"
      onPress={requestCameraPermission}
    />
  </View>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    paddingTop: StatusBar.currentHeight,
    backgroundColor: "#ecf0f1",
    padding: 8
  },
  item: {
    margin: 24,
    fontSize: 18,
    fontWeight: "bold",
    textAlign: "center"
  }
});

export default App;

提供對(duì) Android M 中引入的權(quán)限模型的訪問(wèn)

ToastAndroid

import React from "react";
import {
  View, StyleSheet, ToastAndroid, Button, StatusBar
} from "react-native";

const App = () => {
  const showToast = () => {
    ToastAndroid.show("一只皮卡丘出現(xiàn)在附近!", ToastAndroid.SHORT);
  };

  const showToastWithGravity = () => {
    ToastAndroid.showWithGravity(
      "All Your Base Are Belong To Us",
      ToastAndroid.SHORT,
      ToastAndroid.CENTER
    );
  };

  const showToastWithGravityAndOffset = () => {
    ToastAndroid.showWithGravityAndOffset(
      "A wild toast appeared!",
      ToastAndroid.LONG,
      ToastAndroid.BOTTOM,
      25,
      50
    );
  };

  return (
    <View style={styles.container}>
      <Button title="Toggle Toast" onPress={() => showToast()} />
      <Button
        title="Toggle Toast With Gravity"
        onPress={() => showToastWithGravity()}
      />
      <Button
        title="Toggle Toast With Gravity & Offset"
        onPress={() => showToastWithGravityAndOffset()}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    paddingTop: StatusBar.currentHeight,
    backgroundColor: "#888888",
    padding: 8
  }
});

export default App;

創(chuàng)建 Android Toast 警報(bào)

iOS 組件和 API

ActionSheetIOS

import React, { useState } from "react";
import { ActionSheetIOS, Button, StyleSheet, Text, View } from "react-native";

const App = () => {
  const [result, setResult] = useState("??");

  const onPress = () =>
    ActionSheetIOS.showActionSheetWithOptions(
      {
        options: ["Cancel", "Generate number", "Reset"],
        destructiveButtonIndex: 2,
        cancelButtonIndex: 0,
        userInterfaceStyle: 'dark'
      },
      buttonIndex => {
        if (buttonIndex === 0) {
          // cancel action
        } else if (buttonIndex === 1) {
          setResult(Math.floor(Math.random() * 100) + 1);
        } else if (buttonIndex === 2) {
          setResult("??");
        }
      }
    );

  return (
    <View style={styles.container}>
      <Text style={styles.result}>{result}</Text>
      <Button onPress={onPress} title="Show Action Sheet" />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center"
  },
  result: {
    fontSize: 64,
    textAlign: "center"
  }
});

export default App;

其它

ActivityIndicator

import React from "react";
import {
  ActivityIndicator, StyleSheet, Text, View
} from "react-native";

const App = () => (
  <View style={[styles.container, styles.horizontal]}>
    <ActivityIndicator />
    <ActivityIndicator size="large" />
    <ActivityIndicator size="small" color="#0000ff" />
    <ActivityIndicator size="large" color="#00ff00" />
  </View>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center"
  },
  horizontal: {
    flexDirection: "row",
    justifyContent: "space-around",
    padding: 10
  }
});

export default App;

顯示圓形加載指示器

Alert

import React, { useState } from "react";
import { View, StyleSheet, Button, Alert } from "react-native";

const App = () => {
  const createTwoButtonAlert = () =>
    Alert.alert( "Alert Title", "My Alert Msg",
      [
        {
          text: "Cancel",
          onPress: () => console.log("Cancel Pressed"),
          style: "cancel"
        },
        { text: "OK", onPress: () => console.log("OK Pressed") }
      ]
    );

  return (
    <View style={styles.container}>
      <Button title={"2-Button Alert"}
        onPress={createTwoButtonAlert} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "space-around",
    alignItems: "center"
  }
});

export default App;

啟動(dòng)具有指定標(biāo)題和消息的警報(bào)對(duì)話框

Animated

import React, { useRef } from "react";
import {
  Animated, Text, View, StyleSheet, Button, SafeAreaView
} from "react-native";

const App = () => {
  // fadeAnim 將用作不透明度的值。 初始值:0
  const fadeAnim = useRef(new Animated.Value(0)).current;
  const fadeIn = () => {
    // 將在 5 秒內(nèi)將 fadeAnim 值更改為 1
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 5000
    }).start();
  };
  const fadeOut = () => {
    // 將在 3 秒內(nèi)將 fadeAnim 值更改為 0
    Animated.timing(fadeAnim, {
      toValue: 0,
      duration: 3000
    }).start();
  };
  return (
    <SafeAreaView style={styles.container}>
      <Animated.View
        style={[
          styles.fadingContainer,
          {
            // 將不透明度綁定到動(dòng)畫(huà)值
            opacity: fadeAnim
          }
        ]}
      >
        <Text style={styles.fadingText}>Fading View!</Text>
      </Animated.View>
      <View style={styles.buttonRow}>
        <Button title="淡入淡出" onPress={fadeIn} />
        <Button title="淡出視圖" onPress={fadeOut} />
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  fadingContainer: {
    padding: 20,
    backgroundColor: "powderblue"
  },
  fadingText: { fontSize: 28 },
  buttonRow: {
    flexBasis: 100,
    justifyContent: "space-evenly",
    marginVertical: 16
  }
});

export default App;

一個(gè)用于創(chuàng)建易于構(gòu)建和維護(hù)的流暢、強(qiáng)大的動(dòng)畫(huà)的庫(kù)

Dimensions

import { Dimensions } from 'react-native';

const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;

提供獲取設(shè)備尺寸的接口

KeyboardAvoidingView

import React from 'react';
import {
  View, KeyboardAvoidingView, TextInput,
  StyleSheet, Text, Platform,
  TouchableWithoutFeedback, Button, Keyboard
} from 'react-native';

const KeyboardAvoidingComponent = () => {
  return (
    <KeyboardAvoidingView
      behavior={Platform.OS === "ios" ? "padding" : "height"}
      style={styles.container}
    >
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View style={styles.inner}>
          <Text style={styles.header}>Header</Text>
          <TextInput placeholder="用戶(hù)名" style={styles.textInput} />
          <View style={styles.btnContainer}>
            <Button title="Submit" onPress={() => null} />
          </View>
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1 },
  inner: {
    padding: 24,
    flex: 1,
    justifyContent: "space-around"
  },
  header: { fontSize: 36, marginBottom: 48 },
  textInput: {
    height: 40,
    borderColor: "#000000",
    borderBottomWidth: 1,
    marginBottom: 36
  },
  btnContainer: {
    backgroundColor: "white",
    marginTop: 12
  }
});

export default KeyboardAvoidingComponent;

提供一個(gè)自動(dòng)移出虛擬鍵盤(pán)的視圖

Linking

import React, { useCallback } from "react";
import {
  Alert, Button, Linking, StyleSheet, View
} from "react-native";

const supportedURL = "https://google.com";
const unsupportedURL = "slack://open?team=123456";
const OpenURLButton = ({ url, children }) => {
  const handlePress = useCallback(async () => {
    // 檢查具有自定義 URL 方案的鏈接是否支持該鏈接。
    const supported = await Linking.canOpenURL(url);
    if (supported) {
      // 打開(kāi)某些應(yīng)用程序的鏈接,如果 URL 方案是“http”,則應(yīng)打開(kāi) Web 鏈接
      // 通過(guò)手機(jī)中的某些瀏覽器
      await Linking.openURL(url);
    } else {
      Alert.alert(`不知道如何打開(kāi)這個(gè)網(wǎng)址: ${url}`);
    }
  }, [url]);
  return <Button title={children} onPress={handlePress} />;
};

export default function App() {
  return (
    <View style={styles.container}>
      <OpenURLButton url={supportedURL}>
        打開(kāi)支持的 URL
      </OpenURLButton>
      <OpenURLButton url={unsupportedURL}>
        打開(kāi)不支持的 URL
      </OpenURLButton>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  },
});

提供一個(gè)通用接口來(lái)與傳入和傳出應(yīng)用程序鏈接進(jìn)行交互

import React, { useState } from "react";
import {
  Alert, Modal, StyleSheet, Text, Pressable, View
} from "react-native";

const App = () => {
  const [modalVisible, setModalVisible] = useState(false);
  return (
    <View style={styles.centeredView}>
      <Modal
        animationType="slide"
        transparent={true}
        visible={modalVisible}
        onRequestClose={() => {
          Alert.alert("模態(tài)已關(guān)閉");
          setModalVisible(!modalVisible);
        }}
      >
        <View style={styles.centeredView}>
          <View style={styles.modalView}>
            <Text style={styles.modalText}>Hello World!</Text>
            <Pressable
              style={[styles.button, styles.buttonClose]}
              onPress={() => setModalVisible(!modalVisible)}
            >
              <Text style={styles.textStyle}>Hide Modal</Text>
            </Pressable>
          </View>
        </View>
      </Modal>
      <Pressable
        style={[styles.button, styles.buttonOpen]}
        onPress={() => setModalVisible(true)}
      >
        <Text style={styles.textStyle}>Show Modal</Text>
      </Pressable>
    </View>
  );
};

const styles = StyleSheet.create({
  centeredView: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    marginTop: 22
  },
  modalView: {
    margin: 20,
    backgroundColor: "white",
    borderRadius: 20,
    padding: 35,
    alignItems: "center",
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 2
    },
    shadowOpacity: 0.25,
    shadowRadius: 4,
    elevation: 5
  },
  button: {
    borderRadius: 20,
    padding: 10,
    elevation: 2
  },
  buttonOpen: {
    backgroundColor: "#F194FF",
  },
  buttonClose: {
    backgroundColor: "#2196F3",
  },
  textStyle: {
    color: "white",
    fontWeight: "bold",
    textAlign: "center"
  },
  modalText: {
    marginBottom: 15,
    textAlign: "center"
  }
});

export default App;

提供一種在封閉視圖上方呈現(xiàn)內(nèi)容的簡(jiǎn)單方法

PixelRatio

var image = getImage({
  width: PixelRatio.getPixelSizeForLayoutSize(200),
  height: PixelRatio.getPixelSizeForLayoutSize(100)
});
<Image source={image} style={{ width: 200, height: 100 }} />;

提供對(duì)設(shè)備像素密度的訪問(wèn)

RefreshControl

import React from 'react';
import {
  RefreshControl, SafeAreaView, ScrollView, StyleSheet, Text
} from 'react-native';
const wait = (timeout) => {
  return new Promise(resolve => setTimeout(resolve, timeout));
}
export default function App() {
  const [refreshing, setRefreshing] = React.useState(false);
  const onRefresh = React.useCallback(() => {
    setRefreshing(true);
    wait(2000).then(() => setRefreshing(false));
  }, []);
  return (
    <SafeAreaView style={styles.container}>
      <ScrollView
        contentContainerStyle={styles.scrollView}
        refreshControl={
          <RefreshControl
            refreshing={refreshing}
            onRefresh={onRefresh}
          />
        }
      >
        <Text>下拉看 RefreshControl 指標(biāo)</Text>
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  scrollView: {
    flex: 1,
    backgroundColor: 'pink',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

該組件在 ScrollView 內(nèi)部使用,以添加下拉刷新功能

StatusBar

import React, { useState } from 'react';
import { Button, Platform, SafeAreaView, StatusBar, StyleSheet, Text, View } from 'react-native';

const STYLES = ['default', 'dark-content', 'light-content'];
const TRANSITIONS = ['fade', 'slide', 'none'];

const App = () => {
  const [hidden, setHidden] = useState(false);
  const [statusBarStyle, setStatusBarStyle] = useState(STYLES[0]);
  const [statusBarTransition, setStatusBarTransition] = useState(TRANSITIONS[0]);

  const changeStatusBarVisibility = () => setHidden(!hidden);

  const changeStatusBarStyle = () => {
    const styleId = STYLES.indexOf(statusBarStyle) + 1;
    if (styleId === STYLES.length) {
      setStatusBarStyle(STYLES[0]);
    } else {
      setStatusBarStyle(STYLES[styleId]);
    }
  };

  const changeStatusBarTransition = () => {
    const transition = TRANSITIONS.indexOf(statusBarTransition) + 1;
    if (transition === TRANSITIONS.length) {
      setStatusBarTransition(TRANSITIONS[0]);
    } else {
      setStatusBarTransition(TRANSITIONS[transition]);
    }
  };

  return (
    <SafeAreaView style={styles.container}>
      <StatusBar
        animated={true}
        backgroundColor="#61dafb"
        barStyle={statusBarStyle}
        showHideTransition={statusBarTransition}
        hidden={hidden} />
      <Text style={styles.textStyle}>
        StatusBar Visibility:{'\n'}
        {hidden ? 'Hidden' : 'Visible'}
      </Text>
      <Text style={styles.textStyle}>
        StatusBar Style:{'\n'}
        {statusBarStyle}
      </Text>
      {Platform.OS === 'ios' ? (
        <Text style={styles.textStyle}>
          StatusBar Transition:{'\n'}
          {statusBarTransition}
        </Text>
      ) : null}
      <View style={styles.buttonsContainer}>
        <Button
          title="Toggle StatusBar"
          onPress={changeStatusBarVisibility} />
        <Button
          title="Change StatusBar Style"
          onPress={changeStatusBarStyle} />
        {Platform.OS === 'ios' ? (
          <Button
            title="Change StatusBar Transition"
            onPress={changeStatusBarTransition} />
        ) : null}
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#ECF0F1'
  },
  buttonsContainer: {
    padding: 10
  },
  textStyle: {
    textAlign: 'center',
    marginBottom: 8
  }
});

export default App;

控制應(yīng)用程序狀態(tài)欄的組件

StyleSheet

StyleSheet

import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  paragraph: {
    fontSize: 16,
  },
  label: {
    fontSize: 11,   
    textTransform: 'uppercase'
  }
});

<Text style={styles.paragraph}>段落</Text>
<Text style={styles.label}>標(biāo)簽</Text>

StyleSheet 是一種抽象,它通過(guò)使用二維 JavaScript 對(duì)象接受 CSS 樣式規(guī)則來(lái)替代 CSS

style 屬性

<Text style={styles.paragraph} />
<Text style={{ fontSize: 16 }} />
<Text
  style={[
    styles.paragraph, { color: 'red' }
  ]}
/>

可以使用 style={} 屬性設(shè)置組件的樣式,該屬性接受對(duì)象作為內(nèi)聯(lián)樣式、樣式表創(chuàng)建的樣式定義或一組對(duì)象/定義來(lái)組成樣式

使用樣式表定義

// 使用內(nèi)聯(lián)樣式
const AwesomeBox = () => (
  <View style={{
    width: 100, height: 100,
    backgroundColor: 'red' }} />
);
// 使用樣式表 API
const AwesomeBox = () => (
  <View style={styles.box} />
);
 
const styles = StyleSheet.create({
  box: {
    width: 100,
    height: 100,
    backgroundColor: 'red'
  },
});

動(dòng)態(tài)樣式

// 如果 props.isActive 為真 則在 `paragraph`
// 樣式之上應(yīng)用 `selected` 樣式
function Item(props) {
  return (
    <Text style={[
      styles.paragraph,
      props.isActive && styles.selected
    ]} />
  );
}

React Native 中的 Flex

<View style={{ flexDirection: 'row' }}>
  <View style={{ flex: 1 }} />
  <View style={{ flex: 1 }} />
  <View style={{ flex: 1 }} />
</View>

布局是用類(lèi)似 Flex 的規(guī)則定義的,以適應(yīng)各種屏幕尺寸。Web 上的 Flex 和 React Native 中的 Flex 之間的主要區(qū)別在于不需要帶有 display: flex 的父元素

flexDirection

<View style={{ flexDirection: 'row' }}>
  <View style={{ flex: 1 }} />
  <View style={{ flex: 1 }} />
  <View style={{ flex: 1 }} />
</View>

flexDirection 樣式屬性確定子元素的布局方向和順序,可以是rowrow-reverse、columncolumn-reverse

justifyContent

<View style={{
  flexDirection: 'row',
  justifyContent: 'flex-start'
}}>
  <View style={{ flex: 1 }} />
  <View style={{ flex: 1 }} />
  <View style={{ flex: 1 }} />
</View>

樣式屬性決定了子元素在父容器中的定位方式,可以是 center、flex-start、flex-end、space-aroundspace-betweenspace-evenly。

React Native 中的尺寸

<View
  style={{
    width: 50,
    height: 50,
    backgroundColor: 'powderblue'
  }}
/>

默認(rèn)所有尺寸都是無(wú)單位的,并且表示與密度無(wú)關(guān)的像素

Props

View Style Props

import React from "react";
import { View, StyleSheet } from "react-native";

export default function ViewStyle() {
  return (
    <View style={styles.container}>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "space-between",
    backgroundColor: "#fff",
  },
});

:---
backfaceVisibility#
backgroundColor#
borderBottomColor#
borderBottomEndRadius#
borderBottomLeftRadius#
borderBottomRightRadius#
borderBottomStartRadius#
borderBottomWidth#
borderColor#
borderEndColor#
borderLeftColor#
borderLeftWidth#
borderRadius#
borderRightColor#
borderRightWidth#
borderStartColor#
borderStyle#
borderTopColor#
borderTopEndRadius#
borderTopLeftRadius#
borderTopRightRadius#
borderTopStartRadius#
borderTopWidth#
borderWidth#
elevation Android#
opacity#

Text Style Props

:---
color#
fontFamily#
fontSize#
fontStyle#
fontWeight#
includeFontPadding Android#
fontVariant#
letterSpacing#
lineHeight#
textAlign#
textAlignVertical Android#
textDecorationColor iOS#
textDecorationLine#
textDecorationStyle iOS#
textShadowColor#
textShadowOffset#
textShadowRadius#
textTransform#
writingDirection iOS#

Shadow Props

:---
shadowColor#
shadowOffset iOS#
shadowOpacity iOS#
shadowRadius iOS#

Layout Props

:---
alignContent#
alignItems#
alignSelf#
aspectRatio#
borderBottomWidth#
borderEndWidth#
borderLeftWidth#
borderRightWidth#
borderStartWidth#
borderTopWidth#
borderWidth#
bottom#
direction#
display#
end#
flex#
flexBasis#
flexDirection#
flexGrow#
flexShrink#
flexWrap#
height#
justifyContent#
left#
margin#
marginBottom#
marginEnd#
marginHorizontal#
marginLeft#
marginRight#
marginStart#
marginTop#
marginVertical#
maxHeight#
maxWidth#
minHeight#
minWidth#
overflow#
padding#
paddingBottom#
paddingEnd#
paddingHorizontal#
paddingLeft#
paddingRight#
paddingStart#
paddingTop#
paddingVertical#
position#
right#
start#
top#
width#
zIndex#

Image Style Props

<Image
  style={{
    resizeMode: "contain",
    height: 100,
    width: 200
  }}
  source={require("@expo/snack-static/react-native-logo.png")}
/>

:---
backfaceVisibility#
backgroundColor#
borderBottomLeftRadius#
borderBottomRightRadius#
borderColor#
borderRadius#
borderTopLeftRadius#
borderTopRightRadius#
borderWidth#
opacity#
overflow#
overlayColor#
resizeMode#
tintColor#