Trong một vài năm trở lại đây, React Native đã trở thành một chủ đề “nóng” trong giới lập trình di động. Điều này cũng không có gì lạ, bởi nó nổi tiếng một cách nhanh chóng trong thế giới công nghệ bởi nó cung cấp giải pháp lập trình ứng dụng di động đồng thời cho cả iOS và Android.
React Native – Một framework đứng trên tất cả
React Native đã được áp dụng thành công bởi hàng nghìn doanh nghiệp trên khắp thế giới, bao gồm có Uber, Microsoft và Facebook, và được sử dụng rộng rãi trong rất nhiều ngành công nghiệp.
Tuy nhiên trước khi bạn quyết định “dấn bước” và React Native thì bạn cần phải hiểu được React Native là gì? Nó hoạt động như thế nào ? Làm sao để cài đặt React Native? Và phải học nó như thế nào? Đừng lo, bài viết này sẽ giải đáp tất cả các thắc mắc trên của bạn để biết rằng liệu bạn có phù hợp với framework này hay không.
Nội dung
1. React Native là gì ?
1.1. Khái niệm
React Native là một framework lập trình ứng dụng di động dựa trên JavaScript nổi tiếng cho phép bạn xây dựng các ứng dụng di động gốc cho iOS và Android. Framework cho phép bạn tạo ra một ứng dụng trên nhiều nền tảng sử dụng cùng một codebase.
React Native được ra mắt lần đầu bởi Facebook dưới dạng một dự án mã nguồn mở vào năm 2015. Chỉ trong một vài năm, nó trở thành giải pháp hàng đầu cho phát triển ứng dụng di động. React Native đã cung cấp hỗ trợ cho một trong những ứng dụng di dộng hàng đầu thế giới, bao gồm Instagram, Facebook, Skype,..v..v..
1.2. Tại sao React Native lại trở nên phổ biến ?
Khi các nhà phát triển tạo ra một ứng dụng gốc, họ cần phải gấp đôi số tiền đầu tư dự tính để tạo ra ứng dụng cho các thiết bị trên cả Android lẫn iOS. Kết quả là chi phí sẽ tăng lên, và việc phảt triển ứng dụng sẽ trở nên phức tạp và tốn thời gian hơi. Trái lại, phát triển ứng dụng liên nền tảng giúp các lập trình viên chỉ cần sử dụng cùng một code base.
Một trong những framework liên nền tảng tổt nhất đó là React Native, là giải pháp phát triển trên nền tảng di động phổ biến nhất cho các startups và các nhà phát triển ứng dụng hiện nay.
Các framework phát triển ứng dụng di động trong năm 2019-2020
Nguồn: Statista
1.3. React Native hoạt động như thế nào ?
Có 2 luồng quan trọng chạy trong tất cả các ứng dụng React Native. Một trong số đó là luồng chính, cũng được chạy trong tất cả các ứng dụng gốc tiêu chuẩn. Nó quản lý về hiển thị các phần tử của giao diện và xử lý cử chỉ của người dùng. Luồng còn lại là của riêng React Native. Nhiệm vụ của nó là thực thi code JavaScript trong một JavaScript engine khác. JavaScript đảm nhiệm về logic nghiệp vụ của ứng dụng. Nó cũng định nghĩa cấu trúc và các chức năng của giao diện người dùng. Hai chuỗi này không bao giờ truyền thẳng và cũng không bao giờ chặn nhau.
Như đã đề cập đến ở phía trên, React Native được viết bằng sự kết hợp giữa JavaScript và JXL, một code đánh dấu đặc biệt giống như XML. Framework có thể giao tiếp với cả 2 miền: Các luồng của JavaScript và các luồng sẵn có của ứng dụng gốc. Giao tiếp này hoạt động như thế nào? React Native sử dụng một concept được gọi là cầu nối (bridge). Trong khi các luồng JavaScript và luồng gốc được viết bằng các ngôn ngữ hoàn toàn khác nhau, chức năng cầu nối sẽ giúp cho việc giao tiếp 2 chiều khả thi.
Sau đây là mô tả trực quan về concept cầu nối:
Nguồn: Hackernoon
Điều này có nghĩa là nếu bạn đã có một ứng dụng iOS hay Android gốc, bạn vẫn có thể dùng các thành phần của nó hoặc chuyển sang lập trình bằng React Native.
1.4. Tại sao lại sử dụng React Native làm Framework phát triển ứng dụng?
Giao diện người dùng tương tác
Lý do chính cho thành công của công nghệ React Native đó là việc đơn giản hóa giao diện người dùng di động. Như đã nói đến ở trên, đây là một mạng lưới mã nguồn mở để các lâpj trình viên có thể sử dụng các dãy cụ thể để xây dựng ứng dụng. Hơn nữa, ứng dụng xây dựng bằng React Native phản hồi tốt hơn, tốn ít thời gian tải hơn và cung cấp một trải nghiệm người dùng liền mạch.
Framework phát triển ứng dụng hiệu quả về chi phí
Việc tái sử dụng code giúp giảm thiếu một cách đáng kể chi phí phát triển ứng dụng cho iOS và Android. Với framework này, các nhà phát triển không cần phải viết code cho cả 2 nền tảng và code cho ứng dụng ngôn ngữ sẵn có. Do vậy, bạn sẽ giảm thiểu số lượng các nhà phát triển gốc cần thiết và thời gian hoàn thành dự án.
Độ tin cậy cao
React Native đảm bảo an toàn cho việc liên kết dữ liệu và ngăn dữ liệu cha không bị ảnh hưởng bởi các thành phần con. Vì vậy, ứng dụng sẽ trở nên đáng tin cậy và mạnh mẽ hơn. Nếu nhà phát triển muốn đưa ra các thay đổi thì họ sẽ phải thay đổi trạng thái trước tiên. Điều này cho phép các nhà phát triển chỉ cập nhật các thành phần được cho phép.
Cải thiện hiệu năng
Các module và điều khiển gốc cải thiện hiệu năng của nền tảng. React Native tương tác với các thành phần phát triển ứng dụng của Android và iOS và tạo code cho các API gốc. Và hơn nữa, các dòng code này là tự động và không bị bất kỳ cản trở nào. Ví dụ, khi sử dụng một luồng khác, nó sẽ tự động cải thiện hiệu năng. Cũng có các lựa chọn khác như WebView, nhưng chúng sẽ gây ảnh hưởng đến hiệu năng ứng dụng của bạn.
===> Đăng ký ngay học React Native từ con số 0
Khóa học Front end với React Native
2. Hướng dẫn cài đặt và thiết lập môi trường làm việc của React Native trên Windows
Đầu tiên chúng ta sẽ cùng cài đặt React Native trên Windows 10 sử dụng React Native CLI
2.1. Cài đặt Chocolatey
Chocolatey là một trình quản lý package phổ biến trên Windows. Đầu tiên, chúng ta cần cài đặt nó vào hệ thống.
Để cài đặt Chocolatey. Mở bảng lệnh Command Prompt với quyền quản trị viên và chạy các dòng lệnh sau.
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
2.2. Cài đặt Node.js, Python2 và JDK8
Giờ chúng ta cần cài đặt Node.js, Python2 và JDK bằng Chocolatey. Chúng ta sẽ thực hiện bằng lệnh dưới đây
choco install -y nodejs.install python2 jdk8
2.3. Cài đặt Android Studio
2.4. Thiết lập Android SDK
Android Studio sẽ mặc định cài đặt phiên bản Android SDK mới nhẩt. Tuy nhiên, lập trình một ứng dụng React Native với code gốc sẽ đòi hỏi cụ thể phải có Android 11.0 (R) SDK. Các Android SDK khác có thể được cài đặt thông qua SDK Manager trong Android Studio.
SDK Manager có thể được truy cập từ màn hình Welcome to Android Studio.
Click vào Configure, sau đó chọn SDK Manager.
SDK manager -> SDK platforms
Sau đó tick vào ô bên cạnh “Show Package Details” ở góc dưới bên phải. Tìm và mở rộng mục Android 11.0 (R) , hãy đảm bảo là tất cả mục sau đều được tick:
-
Android SDK Platform 26
-
Google APIs Intel x86 Atom_64 System Image
Các công cụ React Native cần các biến môi trường cho việc thiết lập để có thể xây dựng ứng dụng bằng code gốc.
Mở phần System bên dưới System and Security trong Windows Control Panel, sau đó click vào Change settings. Mở tab Advanced và click vào Environment Variables. Click New để tạo một biến người dùng mới là ANDROID_HOME trỏ về đường dẫn đến Android SDK của bạn:
c:\Users\YOUR_USERNAME\AppData\Local\Android\Sdk
2.5. Cài đặt React Native CLI
Chúng ta có thể dễ dàng cài đặt React Native CLI sử dụng NPM. Bạn có thể thực hiện bằng lệnh dưới đây trong Command Prompt/ Powershell trên hệ thống của bạn.
npm install -g react-native-cli
2.6. Tạo một ứng dụng mới
Với React Native CLI, chúng ta có thể tạo một dự án React Native mới.
react-native init NewProject
Ở đây mình sẽ đặt tên dự án là NewProject.
2.7. Chạy ứng dụng
Giờ chúng ta có thể chạy ứng dụng vừa tạo trên điện thoại Android. Tuy nhiên trước hết, chúng ta cần phải thiết lập thiết bị di động.
Bạn cũng có thể chạy ứng dụng trên Android Virtual Device(AVD) được tạo ra từ Android Studio.
2.7.1. Thiết lập thiết bị Android
Chúng ta cần phải bật USB debugging trong thiết bị Android để chạy ứng dụng React Native mà chúng ta vừa tạo.
-
Trên thiết bị Android của bạn, đi tới phần Settings->About
-
Chúng ta có thể thấy menu Build Version.
-
Tiếp tục click vào lựa chọn Build Version cho đến khi nó cho phép tùy chọn Developer options.
-
Trở về Settings và click vào menu Developer options.
-
Bật tùy chọn USB debugging trong Developer options.
Kết nối thiết bị di động của bạn với hệ thống Windows bằng cáp USB. Nhập dòng lệnh dưới đây để xác định xem thiết bị của chúng ta đã được kết nối hay chưa.
adb devices
Bây giờ, chạy lệnh dưới đây đề chạy ứng dụng React Native trên thiết bị di động của bạn.
react-native run-android
Mình khuyến khích các bạn nên sử dụng Visual Studio Code làm trình biên tập mã nguồn để làm việc với các dự án React Native.
Trên đây chúng ta đã học về các bước để cài đặt React Native on our Windows 10 sử dụng React Native CLI. Ngoài ra bạn còn có thể sử dụng Expo CLI nếu muốn cài đặt và thiết lập React Native dễ dàng hơn.
3.Hướng dẫn học React Native từ cơ bản đến nâng cao
Sau khi đã thiết lập xong React Native thì mình biết chắc rằng các bạn đang nóng lòng muốn biết tất cả các kiến thức nhưng chớ có vội. Trước hết, chúng ta phải biết được các yêu cầu cơ bản để giúp bạn không bị bỡ ngỡ và chuẩn bị các kỹ năng cần thiết để có thể bắt tay vào học React Native:
-
Bạn cần có các kiến thức lập trình cơ bản như hàm, đối tượng, mảng, và các lớp
-
Bạn cần có các kiến thức cơ bản về JavaScript
-
Đã có kiến thức về HTML và CSS
-
Cuối cùng, nếu như trước đó bạn đã làm việc với React.js, thì bạn cũng sẽ biết được rất nhiều kiến thức về React Native, và do vậy sẽ tiếp thu dễ dàng hơn rất nhiều.
Sau khi đã biết được chúng ta cần trang bị những gì, chúng ta hãy cùng tìm hiểu về các kiến thức React Native từ cơ bản đến nâng cao:
I.Kiến thức cơ bản
Phần 1: Ứng dụng đầu tiên “Hello World”
Sẽ không thể thiếu được chương trình đầu tiên và cơ bản nhất đối với mọi ngôn ngữ lập trình. Hãy cùng xây dựng ứng dụng React Native đầu tiên trên Windows với vai trò hệ điều hành phát triển và Android là hệ điều hành mục tiêu.
-
Các bước để tạo ứng dụng React Native
-
Khởi động trình giả lập Android (Android Emulator) và chạy nó.
-
Tạo một thư mục (ReactNative) trên bất kỳ ổ đĩa nào.
-
Mở "Command Prompt" và đến thư mục ReactNative.
-
Viết một lệnh react-native init FirstApp để khởi tạo ứng dụng
"FirstApp"
của bạn.
-
Đi tới vị trí thư mục "FirstApp" và chạy lệnh
react-native run-android
. Nó sẽ khởi động máy chủ Node và chạy ứng dụng của bạn trên một trình giả lập thiết bị.
Output:
2. Xem code của ứng dụng React Native
Mở bất kỳ IDE nào có hỗ trợ JavaScript mà bạn thích và mở tệp App.js trong ứng dụng FirstApp.
Dưới đây là code mặc định của ứng dụng React Native đầu tiên.
App.js
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
android:
'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<Text style={styles.instructions}>To get started, edit App.js</Text>
<Text style={styles.instructions}>{instructions}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
index.js
/** @format */
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
3. Tạo một ứng dụng React Native "Hello World" đơn giản
Chúng ta có thể tạo ứng dụng "Hello World" bằng cách biên tập tệp App.js của FirstApp.
Lưu ứng dụng và tải lại bằng cách nhấn đúp phím "R" hoặc dùng tổ hợp phím Ctrl+M (Reload).
App.js
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View>
<Text>Hello World</Text>
</View>
);
}
}
Output:
4. Biên tập ứng dụng React Native "Hello World"
Chúng ta sẽ biên tập ứng dụng React Native "Hello World" bằng StyleSheet.
App.js
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View>
<Text style={styles.welcome}>Hello World</Text>
</View>
);
}
}
const styles = StyleSheet.create({
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
}
});
Output:
Giải thích code của React Native Code:
-
import React, {Component} from 'react':
import thư viện và các thành phần khác từ react module và chỉ định chúng đến biến React.
-
const instruction:
các bộ hiển thị thông báo cụ thể theo từng nền tảng.
-
export default class App extends Component:
định nghĩa các lớp mà mở rộng thành phần React. Modifier export default class làm cho lớp trở nên "công khai". Khối code định nghĩa các thành phần đại diện cho giao diện người dùng.
-
render():
trả về một phần tử React element.
-
return():
trả về kết quả của layout và các thành phần UI.
-
View:
một container hỗ trợ các điều chỉnh các tính năng truy cập layout. Đây là một thành phần cơ bản để xây dựng UI.
-
Text:
là thành phần React để hiển thị văn bản.
-
style:
một property sử dụng để tạo kiểu cho các thành phần bằng StyleSheet.
-
styles:
sử dụng để thiết kế riêng từng thành phần.
-
const styles = StyleSheet.create({}):
là lớp StyleSheet tạo ra các đối tượng kiểu để điều chỉnh layout và bề ngoài của các thành phần. Nó tương tự như Cascading Style Sheets
(CSS) sử dụng trên Web.
Phần 2: View, State và Prop
1. React Native View
View là một thành phần cơ bản của React Native để xây dựng giao diện người dùng (UI). Nó là một container that hỗ tợ layout với flexbox, kiểu, thao tác chạm, và các điều khiển khả năng truy cập. Nó ánh xạ trực tiếp vào view gốc tương tự như bất kì nền tảng nào mà ứng dụng React Native đang hoạt động trên đó. Nó hiển thị các thành phần bất kể với UIView, <div>, android.view, ..v..v..
Thành phần View có thể được lồng vào nhau, chứa các view khác bên trong nó. Nó có thể chứa từ 0 đến rất nhiều thành phần con của bất kỳ loại nào.
Chú ý: Thành phần View được sử dụng cùng StyleSheet khiến nó rõ ràng và đạt hiệu năng tôt hơn well performed, tuy nhiên, nó cũng hỗ trợ các kiểu inline.
Các Prop của View
onStartShouldSetResponder |
accessibilityLabel |
accessibilityHint |
hitSlop |
nativeID |
onAccessibilityTap |
onLayout |
onMagicTap |
onMoveShouldSetResponder |
onMoveShouldSetResponderCapture |
onResponderGrant |
onResponderMove |
onResponderReject |
onResponderRelease |
onResponderTerminate |
onResponderTerminationRequest |
accessible |
onStartShouldSetResponderCapture |
pointerEvents |
removeClippedSubviews |
style |
testID |
accessibilityComponentType |
accessibilityLiveRegion |
collapsable |
importantForAccessibility |
needsOffscreenAlphaCompositing |
renderToHardwareTextureAndroid |
accessibilityRole |
accessibilityStates |
accessibilityTraits |
accessibilityViewIsModal |
accessibilityElementsHidden |
accessibilityIgnoresInvertColors |
shouldRasterizeIOS |
|
Ví dụ về React Native View
Trong ví dụ này, chúng ta sẽ tạo thành phần View chứa 2 hộp màu và và một thành phần văn bản liền kề nhau với các kích thước chiều cao và chiều rộng.
App.js
import React, { Component } from 'react'
import {StyleSheet,View, Text} from 'react-native'
export default class SwitchExample extends Component {
render() {
return (
<View style={styles.container}>
<View style={{backgroundColor: 'blue', flex: 0.3}} />
<View style={{backgroundColor: 'red', flex: 0.5}} />
<Text style={{fontSize: 18}}>View Example</Text>
</View>
);
}
}
const styles = StyleSheet.create ({
container: {
flex: 1,
flexDirection: 'row',
height: 100,
width: "80%",
backgroundColor:"#5ead97"
}
})
Output:
2. React Native State
Có 2 kiểu dữ liệu đó là state và props trong React Native để điều khiển các thành phần. Các thành phần sử dụng state có thể biến đổi. Chúng có thể được thay đổi sau nếu cần thiết. Các thành phần props là không thể biến đổi và cố định trong toàn bộ thời gian hoạt động.
State thường được khởi chạy trong hàm dựng và sau đó gọi setState khi chúng ta muốn thay đổi nó.
React Native state Ví dụ 1
Trong ví dụ này, Chúng ta tạo một thành phần Text với dữ liệu state. Nội dung của thành phần Text sẽ được cập nhật bằng cách click lên nó. Sự kiện onPress sẽ gọi setState, và nó sẽ cập nhật state của văn bản "myState"
.
import React, {Component} from 'react';
import { Text, View } from 'react-native';
export default class App extends Component {
state = {
myState: 'This is a text component, created using state data. It will change or updated on clicking it.'
}
updateState = () => this.setState({myState: 'The state is updated'})
render() {
return (
<View>
<Text onPress={this.updateState}> {this.state.myState} </Text>
</View>
);
}
}
Output
React Native state Ví dụ 2
Chúng ta hãy cùng tạo một thành phần khác của dữ liệu state để thay đổi xen kẽ giá trị của Text giữa "Show"
và "Hide"
để hiển thị và ẩn phần nhập mật khẩu.
Tạo 3 biến state mà sẽ được thay đổi khi click vào thành phần Text được định nghĩa như một state. Click vào thành phần Text component sẽ gọi hàm handleToggle, và state hiện tại của biến Boolean "isPasswordVisible"
được chỉ định trong nó. Lúc này, if sẽ kiểm tra giá trị của "isPasswordVisible"
và tiến hành tiếp tùy theo kểt quả.
import React, { Component } from 'react';
import {StyleSheet,Text,View,TextInput,TouchableOpacity} from 'react-native';
export default class App extends Component {
state: {
password: string,
isPasswordVisible: boolean,
toggleText: string,
}
constructor(props: Props) {
super(props);
this.state = {
password: '',
isPasswordVisible: true,
toggleText: 'Show',
};
}
handleToggle = () => {
const { isPasswordVisible } = this.state;
if (isPasswordVisible) {
this.setState({ isPasswordVisible: false });
this.setState({ toggleText: 'Hide' });
} else {
this.setState({ isPasswordVisible: true });
this.setState({ toggleText: 'Show' });
}
};
render() {
return (
<View style={styles.container}>
<TextInput
secureTextEntry={this.state.isPasswordVisible}
style={{ width: 400, height: 50, backgroundColor: '#a7a6a9', color: 'white', fontSize: 20 }}
/>
<TouchableOpacity onPress={this.handleToggle}>
<Text style={{fontSize: 20}}>{this.state.toggleText}</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
});
Output
3. React Native Props
Các property của thành phần React Native components được gọi đơn giản là props. Trong React Native, các thành phần có thể được tùy chỉnh trong quá trình tạo ra chúng với các tham số khác nhau. Các tham số này chính là các props. Chúng là không thể biến đổi và không thể thay đổi được.
Một ví dụ về props đó là source property nếu thành phần Image điều chỉnh các hình ảnh được hiển thị trên màn hình của thiết bị.
Props mặc định của React Native
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Image,
Text,
View
} from 'react-native';
export default class App extends Component<{}> {
render() {
let imagePath = { uri: 'https://facebook.github.io/react-native/img/header_logo.png'};
"rel=nofollow"
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<Image source={imagePath} style={{width: 250, height: 250}} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#a7a6a9',
},
welcome: {
fontSize: 30,
textAlign: 'center',
margin: 20,
}
});
Output:
Sử dụng props trong thành phần của riêng bạn
Chúng ta có thể sử dụng props trong các thành phần của riêng mình. Một thành phần có thể được sử dụng ở nhiều nơi trong ứng dụng bằng cách dùng các property hơi khác nhau một chút ở từng nơi. Để cài đặt props vào thành phần, this.props sẽ được thêm vào và sau đó là property.
Ví dụ, một trong những thành phần cơ bản của React Native là Text. Khi chúng ta tạo một thành phần Text, chúng ta có thể dùng một prop "name"
là props để điều chỉnh bề ngoài của nó. Chúng ta cũng sẽ áp dụng StyleSheet vào thành phần của chúng ta.
App.js
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
class ChildClass extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Text style={styles.welcome}>Hello {this.props.name}!</Text>
</View>
);
}
}
export default class ParentsClass extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<ChildClass name='Ashu' />
<ChildClass name='Aman' />
<ChildClass name='Max' />
</View>
);
}
}
const styles = StyleSheet.create({
welcome: {
fontSize: 30,
}
});
// skip this line if using Create React Native App
//AppRegistry.registerComponent('MyReactNativeApp', () => ParentsClass);
Output:
Phần 3: React Native Style
React Native chỉ sử dụng JavaScript để tạo kiểu cho các thành phần cốt lõi. Chúng ta không cần bất kỳ ngôn ngữ hay cú pháp đặc biệt nào để định nghĩa cho kiểu. Tất cả các thành phần cốt lõi đều sử dụng một prop (property) đó là style. Các tên và giá trị của style names cũng tương tự như CSS của web. Khác biệt duy nhất là cách viết tên liền nhau không dấu, chẳng hạn như fontSize thay vì font-size.
Style prop is đơn giản là một đối tượng JavaScript, là cách đơn giản nhất để tạo kiểu cho code.
Có nhiều cách để thiết kế các thành phần, sử dụng kiểu inline và StyleSheet.create
. Khi các thành phần phức tạp hơn ,thì tốt hơn là nên dùng StyleSheet.create
để định nghĩa nhiều kiểu ở cùng một nơi.
React Native style Ví dụ 1
Trong ví dụ này, chúng ta sẽ sử dụng cả kiểu inline và StyleSheet.create
. Kiểu inline được áp dụng khi các thành phần được tạo.
App.js
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
export default class ImplementingStyle extends Component {
render() {
return (
<View>
<Text style={{ backgroundColor: '#a7a6a9', color: 'yellow', fontSize: 20 }}>this is inline style</Text>
<Text style={styles.green}>just green</Text>
<Text style={styles.biggray}>just biggray</Text>
<Text style={[styles.biggray, styles.green]}>biggray, then green</Text>
<Text style={[styles.green, styles.biggray]}>green, then biggray</Text>
</View>
);
}
}
const styles = StyleSheet.create({
biggray: {
color: 'gray',
fontWeight: 'bold',
fontSize: 30,
},
green: {
color: 'green',
},
});
Output
React Native style Ví dụ 2
Chúng ta cũng có thể sử dụng các tệp JavaScript bên ngoài để tạo kiểu cho các thành phần. Trong ví dụ này, we chúng ta sẽ tạo tệp JS bên ngoài và import nó vào tệp App.js của chúng ta.
StyleComponent.js
import React, { Component } from 'react'
import { Text, View, StyleSheet } from 'react-native'
const StyleComponent = (props) => {
return (
<View>
<Text style = {styles.myState}>
{props.myState}
</Text>
</View>
)
}
export default StyleComponent
const styles = StyleSheet.create ({
myState: {
marginTop: 20,
textAlign: 'center',
color: 'green',
fontWeight: 'bold',
fontSize: 20
}
})
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import StyleComponent from './StyleComponent'
export default class App extends React.Component {
state = {
myState: 'This is my state, style through external style'
}
render() {
return (
<View>
<StyleComponent myState = {this.state.myState}/>
</View>
);
}
}
Output
Phần 4: Chiều cao và chiều rộng
Chiều cao và chiều rộng quyết định kích cỡ của thành phần trên màn hình. Có 2 cách để đặt chiều cao và chiều rộng của thành phần: Fixed Dimensions và Flex Dimensions.
Fixed Dimensions (Chiều không gian cố định)
Sử dụng chiều cao cố định và chiều rộng cố định trong style là cách đơn giản nhất để đặt không gian của thành phần. Các chiều không gian của thành phần React Native là không có đơn vị, và chúng đại diện cho các pixel độc lập với mật độ.
Thiết lập không gian của thành phần với kích cỡ cố định là thông thường và chính xác về kích cỡ, bất kể không gian của màn hình.
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
export default class HeightWidth extends Component {
render() {
return (
<View>
<View style={styles.powderblue} />
<View style={styles.skyblue} />
<View style={styles.steelblue} />
</View>
);
}
}
const styles = StyleSheet.create({
powderblue:{
width: 100, height: 100, backgroundColor: 'powderblue'
},
skyblue:{
width: 200, height: 200, backgroundColor: 'skyblue'
},
steelblue:{
height: 300, backgroundColor: 'steelblue'
},
})
Output
Flex Dimensions (Chiều không gian linh hoạt)
Flex property tạo kiểu cho các thành phần để có thể mở rộng hoặc co lại một cách linh động tùy theo không gian đang có. Đặt flex: 1
sẽ lấp đầy các khoảng không gian trống bằng cả thành phần, và được chia đều giữa các thành phần có cùng thành phần cha. Giá trị flex càng cao, thì thành phần đó sẽ chiếm tỉ lệ trong không gia cao hơn so với các thành phần họ hàng của nó.
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
export default class HeightWidth extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.powderblue} />
<View style={styles.skyblue} />
<View style={styles.steelblue} />
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex:1
},
powderblue:{
flex:1,
backgroundColor: 'powderblue',
},
skyblue:{
flex:2,
backgroundColor: 'skyblue',
},
steelblue:{
flex:3,
backgroundColor: 'steelblue',
},
})
Output
Phần 5: Các nút React Native (Buttons)
Phần lớn người dùng tương tác với các thiết bị di động qua cảm ứng chạm. Có một tập hợp các cử chỉ với nó, chẳng hạn như gõ vào nút, phóng to bản đồ, cuộn một danh sách, ..v..v.. Nút là một trong những thành phần để thao tác với các click.
Nút React Native là một thành phần cơ bản hoạt động bằng cách click lên nó. Nó import lớp Button của react-native.
Các Prop của Button
Prop |
Kiểu |
Bắt buộc |
Mô tả |
onPress |
function |
Có |
Gọi handler khi người dùng click vào nút. |
title |
string |
Có |
Hiển thị văn bản bên trong nút. |
accessibilityLabel |
string |
Không |
Hiển thị văn bản cho các chức năng truy cập dành cho người khiếm thị. |
color |
Color |
Không |
Đặt màu nền của nút Android hoặc màu của văn bản iOS. |
disabled |
bool |
Không |
Vô hiệu hóa tất cả các tương tác của thành phần, nếu là true. |
textID |
string |
Không |
Sử dụng để định vị view trong kiểm thử đầu-cuối. |
hasTVPreferredFocus |
bool |
Không |
Hiệu ứng TV preffered focus, chỉ hoạt động trên Apple TV. |
Ví dụ về React Native Button
Trong ví dụ này, chúng ta sẽ làm việc với thành phần button.Thành phần React Native Button
import lớp Button của thư viện react-native. Nó có một vài props như title, onPress, accessibilityLabel, v..v... như đã được nhắc đến phía trên.
Trong code dưới đây title prop
sẽ đặt title của nút, onPress prop
gọi hàm mention
và thực hiện một sự kiện. Color prop
sẽ đặt màu của nút, và disabled={true}
sẽ vô hiệu hóa nút.
import React, { Component } from 'react';
import { Alert, AppRegistry, Button, StyleSheet, View } from 'react-native';
export default class ButtonBasics extends Component {
onPressButton() {
Alert.alert('You clicked the button!')
}
render() {
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button
onPress={this.onPressButton}
title="Press Me"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={this.onPressButton}
title="Press Me"
color="#009933"
/>
</View>
<View style={styles.multiButtonContainer}>
<Button
onPress={this.onPressButton}
title="A disabled button"
disabled={true}
/>
<Button
onPress={this.onPressButton}
title="OK!"
color="#009933"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
buttonContainer: {
margin: 20
},
multiButtonContainer: {
margin: 20,
flexDirection: 'row',
justifyContent: 'space-between'
}
})
Output:
Phần 6: Layout và Flexbox
React Native Flexbox là một thuật toán để chỉ rõ layout thành phần con của một thành phần cha. Nó sẽ đưa ra layout đồng nhất trên các kích cỡ màn hình khác nhau.
Property của Flexbox
Flexbox
cung cấp 3 property chính để đạt được layout mong muốn. 3 property này bao gồm: flexDirection, justifyContent,
và alignItems.
Property |
Các giá trị |
Mô tả |
flexDirection |
'column', 'row' |
Sử dụng để sắp xếp các phần tử thẳng hàng theo chiều dọc hoặc chiều ngang. |
justifyContent |
'center', 'flex-start', 'flex-end', 'space-around', 'space-between' |
Sử dụng để phân bổ các phần tử bên trong container. |
alignItems |
'center', 'flex-start', 'flex-end', 'stretched' |
Sử dụn để phân bổ các thành phần bên trong container với một trục thứ 2 (đối lập với flexDirection). |
React Native Flex Direction
flexDirection
thêm kiểu vào các thành phần trên một trục chính trong layout của nó. Nó có một property hàng và cột để sắp xếp các thành phần con lần lượt theo chiều ngang và chiều dọc. default flexDirection
là một cột.
import React, { Component } from 'react';
import { StyleSheet,View } from 'react-native';
export default class FlexDirectionBasics extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.powderblue} />
<View style={styles.skyblue} />
<View style={styles.steelblue} />
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
flexDirection: 'row',// set elements horizontally, try column.
},
powderblue:{
width: 60,
height: 60,
backgroundColor: 'powderblue',
},
skyblue:{
width: 60,
height: 60,
backgroundColor: 'skyblue',
},
steelblue:{
width: 60,
height: 60,
backgroundColor: 'steelblue',
}
})
Output
React Native Justify Content
justifyContent
quyết định sự phân bổ các thành phần con theo trục chính. Thành phần con được phân bố ở đầu, cuối, giữa, hay được căn đều.
import React, { Component } from 'react';
import { StyleSheet,View } from 'react-native';
export default class JustifyContentBasics extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.powderblue} />
<View style={styles.skyblue} />
<View style={styles.steelblue} />
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
flexDirection: 'column', // set elements horizontally`.
justifyContent: 'center',
},
powderblue:{
width: 60,
height: 60,
backgroundColor: 'powderblue'
},
skyblue:{
width: 60,
height: 60,
backgroundColor: 'skyblue',
},
steelblue:{
width: 60,
height: 60,
backgroundColor: 'steelblue',
}
})
Output
React Native Align Items
alignItems
quyết định việc sắp xếp các thành phần con theo một trục phụ thứ 2. Nếu trục chính là một cột, thì trục phụ sẽ là một hàng và ngược lại. Sử dụng alignItems
, các thành phần con sẽ được xếp thẳng hàng ở đầu, cuối, giữa, hoặc được kéo dãn ra.
import React, { Component } from 'react';
import { StyleSheet,View } from 'react-native';
export default class AlignItemsBasics extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.powderblue} />
<View style={styles.skyblue} />
<View style={styles.steelblue} />
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
flexDirection: 'column', // set elements horizontally`.
justifyContent: 'center',
alignItems: 'stretch',
},
powderblue:{
width: 60,
height: 60,
backgroundColor: 'powderblue'
},
skyblue:{
width: 60,
height: 60,
backgroundColor: 'skyblue',
},
steelblue:{
/*width: 60,*/
height: 60,
backgroundColor: 'steelblue',
}
})
Output
Chú ý: Kéo dãn sẽ không có tác dụng nếu thành phần con có một chiều không gian cố định theo trục phụ. Trong ví dụ trên, alignItems: stretch sẽ không có tác dụng nếu chúng ta không loại bỏ width: 50.
Phần 7: Đặt vị trí phần tử với Flex
Trong bài trước về Layout và Flexbox, chúng ta đã thảo luận về Flexbox và các property của nó. Trong bài này, chúng ta sẽ đặt vị trí của các phần tử với Flex.
Ví dụ 1
Tạo một thành phần View và đặt 2 phần tử TextInput và Button. Thành phần View với flex property (1)
sẽ chiếm hết không gian của thiết bị. Phần tử TextInput và Button được đặt ở default flex axis
(như một cột).
import React, { Component } from "react";
import { StyleSheet, TextInput, View , Button } from "react-native";
export default class App extends Component {
state = {
placeName: "",
places: []
};
placeNameChangedHandler = val => {
this.setState({
placeName: val
});
};
placeSubmitHandler = () => {
alert("button clicked")
};
render() {
return (
<View style={styles.container}>
<TextInput
placeholder="An awesome place"
onChangeText={this.placeNameChangedHandler}
style={styles.placeInput}
/>
<Button
title="Button"
onPress={this.placeSubmitHandler}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 26,
backgroundColor: "#fff",
justifyContent: "flex-start"
}
});
Output:
Ví dụ 2
Trong ví dụ này chúng ta sẽ đặt phần tử Button ở phía bên phải của phần tử TextInput
. Thêm một thành phần con View vào trong thành phần cha View với flex: 1
và flexDirtection : "row"
. Đặt flex: 1
để View bên trong chiếm toàn bộ không gian từ trên xuống dưới và từ trái sang phải. flexDirtection: "row"
đặt các phần tử theo hàng trong thành phần View ở phía bên trong.
import React, { Component } from "react";
import { StyleSheet, View, TextInput, Button } from "react-native";
export default class App extends Component {
state = {
placeName: "",
places: []
};
placeNameChangedHandler = val => {
this.setState({
placeName: val
});
};
placeSubmitHandler = () => {
alert("button clicked")
};
render() {
return (
<View style={styles.container}>
<View style={styles.innerContainer}>
<TextInput
placeholder="An awesome place"
onChangeText={this.placeNameChangedHandler}
/>
<Button
title="Button"
onPress={this.placeSubmitHandler}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 26,
backgroundColor: "#fff",
justifyContent: "flex-start"
},
innerContainer:{
flex: 1,
flexDirection: "row"
}
});
Output:
flex:1
để View phía bên trong chiếm toàn bộ không gian trông sẽ không đẹp mắt như để TextInput và Button chiếm toàn bộ không gian từ trên xuống dưới.
Ví dụ 3
Trong ví dụ này, chúng ta sẽ loại bỏ flex property
của View phía bên trong và thêm width: 100%. Loại bỏ flex từ View phía bên trong sẽ đặt chiều không gian mặc định của các phần tử. Đặt width :"100%"
để View phía bên trong chiếm trọn chiều ngang và chiều cao mặc định của các phần tử.
import React, { Component } from "react";
import { StyleSheet, View, TextInput, Button } from "react-native";
export default class App extends Component {
state = {
placeName: "",
places: []
};
placeNameChangedHandler = val => {
this.setState({
placeName: val
});
};
placeSubmitHandler = () => {
alert("button clicked")
};
render() {
return (
<View style={styles.container}>
<View style={styles.innerContainer}>
<TextInput
placeholder="An awesome place"
onChangeText={this.placeNameChangedHandler}
style={styles.textStyle}
/>
<Button
title="Button"
onPress={this.placeSubmitHandler}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 26,
backgroundColor: "#fff",
justifyContent: "flex-start"
},
innerContainer:{
// flex: 1,
width: "100%",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center"
},
textStyle:{
width: "70%",
backgroundColor: "gray",
},
buttonStyle:{
width: "30%",
}
});
Output:
Phần 8: React Native ScrollView
ScrollView
là một container thông thường có thể cuộn được, và có thể cuộn được nhiều thành phần con và view bên trong nó. Trong ScrollView
, chúng ta có thể cuộn các thành phần theo chiều dọc and và chiều ngang. Mặc định, ScrollView
container cuộn các thành phần và view của nó theo chiều dọc Để cuộn các thành phần theo chiều ngang, nó sử dụng các prop horizontal: true
(mặc định, horizontal: false
).
Các Props của ScrollView
alwaysBounceVertical |
onScroll |
horizontal |
|
contentContainerStyle |
scrollEnabled |
bouncesZoom |
zoomScale |
onScrollBeginDrag |
onContentSizeChange |
maximumZoomScale |
minimumZoomScale |
onScrollBeginDrag |
onContentSizeChange |
maximumZoomScale |
minimumZoomScale |
onScrollEndDrag |
centerContent |
contentInset |
refreshControl |
pagingEnabled |
scrollsToTop |
snapToAlignment |
showsHorizontalScrollIndicator |
snapToStart |
snapToEnd |
indicatorStyle |
showsHorizontalScrollIndicator |
Ví dụ về React Native ScrollView
Trong ví dụ này, Chúng ta sẽ tạo ScrollView
theo chiều dọc sử dụng các thành phần Text và Button.
App.js
import React, { Component } from 'react';
import { AppRegistry, ScrollView, Image, Text, Button, StyleSheet } from 'react-native';
export default class ScrolledViewExample extends Component {
onPressButton() {
alert('You clicked the button!')
}
render() {
return (
<ScrollView >
<Text style={{fontSize:20}}>Scroll me plz</Text>
<Button title={'Button 1'} onPress={this.onPressButton} />
<Text style={{fontSize:20}}>React Native Example of ScrollView</Text>
<Button title={'Button 2'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>React Native ScrollView Example</Text>
<Button title={'Button 3'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>If you like</Text>
<Button title={'Button 4'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>Scrolling down</Text>
<Button title={'Button 5'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>Scrolling down</Text>
<Button title={'Button 6'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>What's the best</Text>
<Button title={'Button 7'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>What's the best</Text>
<Button title={'Button 8'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>Framework around?</Text>
<Button title={'Button 9'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>Framework around?</Text>
<Button title={'Button 10'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>React Native</Text>
<Button title={'Button 11'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>Scroll me plz</Text>
<Button title={'Button 12'} onPress={this.onPressButton} />
<Text style={{fontSize:20}}>Scroll me plz</Text>
<Button title={'Button 13'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>If you like</Text>
<Button title={'Button 14'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>If you like</Text>
<Button title={'Button 15'} onPress={this.onPressButton}/>
<Text style={{fontSize:20}}>Scrolling down</Text>
<Button title={'Button 16'} onPress={this.onPressButton}/>
</ScrollView>
);
}
}
// skip this line if you are using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => ScrolledViewExample);
Output:
Ví dụ về React Native ScrollView theo chiều ngang
ScrollView
theo chiều ngang cuộn các thành phần và view từ trái sang phải. Nó sẽ được cài đặt bằng cách đặt cách đặt giá trị của các props horizontal
thành true (horizontal={true})
.
App.js
import React, { Component } from 'react';
import { AppRegistry, ScrollView, View, Image, Text, Button, StyleSheet } from 'react-native';
export default class ScrolledViewExample extends Component {
onPressButton() {
alert('You clicked the button!')
}
render() {
return (
<ScrollView horizontal={true} style={styles.container}>
<Text style={{fontSize:22, padding: 10}}>Horizontal ScrollView</Text>
<View style={[{ width: 220,height: 70,padding: 10 }]}>
<Button
onPress={this.onPressButton}
title="Button 1"
color="#FF3D00"
/>
</View>
<Text style={{fontSize:22, padding: 10}}>javatpoint</Text>
<View style={[{ width: 220,height: 70,padding: 10 }]}>
<Button
onPress={this.onPressButton}
title="Button 2"
color="#3D00FF"
/>
</View>
<Text style={{fontSize:22, padding: 10}}>React Native ScrollView Example</Text>
<View style={[{ width: 220,height: 70,padding: 10 }]}>
<Button
onPress={this.onPressButton}
title="Button 3"
color="#FFFF3D"
/>
</View>
<Text style={{fontSize:22, padding: 10}}>If you like</Text>
<View style={[{ width: 220,height: 70,padding: 10 }]}>
<Button
onPress={this.onPressButton}
title="Button 4"
color="#FF3DFF"
/>
</View>
<Text style={{fontSize:22, padding: 10}}>Scrolling horizontal</Text>
<View style={[{ width: 220,height: 70,padding: 10 }]}>
<Button
onPress={this.onPressButton}
title="Button 5"
color="#3DFF00"
/>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
},
/* buttonStyle:{
height: 50,
width: 70,
}*/
})
// skip this line if you are using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => ScrolledViewExample);
Output:
Phần 9: React Native List
1. React Native FlatList
Thành phần FlatList
hiển thị các dữ liệu có cấu trúc tương tự nhau trong một danh sách có thể cuộn được. Nó hoạt động tốt với các danh sách dữ liệu lớn khi mà số item trong danh sách có thể thay đổi theo thời gian. FlatList
chỉ cho thấy các thành phần được render đang được hiển thị trên màn hình, không phải tất cả các phần tử trong danh sách cùng một lúc.
Thành phần FlatList
phải có 2 props: data
và renderItem
.
data
là nguồn của phần tử cho danh sách, và renderItem
lấy một item từ nguồn và trả về một thành phần đã được định dạng để render.
Để cài đặt thành phần FlatList, chúng ta cần phải import FlatList
từ thư viện 'react-native'
.
Ví dụ về React Native FlatList
Chúng ra, chúng ta sẽ cung cấp các phần tử đã được hardcode cho data prop. Mỗi phần tử trong các data props được render như một thành phần Text.
ItemSeparatorComponent prop
của FlatList được dùng để đặt dấu ngăn cách giữa các phần tử trong danh sách. Để thực hiện sự kiện trên các item trong danh sách, chúng ta sử dụng onPress prop
đến Text.
import React, { Component } from 'react';
import { AppRegistry, FlatList,
StyleSheet, Text, View,Alert } from 'react-native';
export default class FlatListBasics extends Component {
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: "100%",
backgroundColor: "#000",
}}
/>
);
};
//handling onPress action
getListViewItem = (item) => {
Alert.alert(item.key);
}
render() {
return (
<View style={styles.container}>
<FlatList
data={[
{key: 'Android'},{key: 'iOS'}, {key: 'Java'},{key: 'Swift'},
{key: 'Php'},{key: 'Hadoop'},{key: 'Sap'},
{key: 'Python'},{key: 'Ajax'}, {key: 'C++'},
{key: 'Ruby'},{key: 'Rails'},{key: '.Net'},
{key: 'Perl'},{key: 'Sap'},{key: 'Python'},
{key: 'Ajax'}, {key: 'C++'},{key: 'Ruby'},
{key: 'Rails'},{key: '.Net'},{key: 'Perl'}
]}
renderItem={({item}) =>
<Text style={styles.item}
onPress={this.getListViewItem.bind(this, item)}>{item.key}</Text>}
ItemSeparatorComponent={this.renderSeparator}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
})
AppRegistry.registerComponent('AwesomeProject', () => FlatListBasics);
Output:
2. React Native SectionList
Thành phần React Native SectionList
là một thành phần list view đặt các danh sách của dữ liệu thành các phần logic nhỏ hơn. Các phần dữ liệu đã được chia nhỏ có thể được cài đặt bằng cách sử dụng section header prop renderSectionHeader
của nó.
Để cài đặt thành phần SectionList component
, chúng ta cần phải import SectionList
từ thư viện 'react-native'.
Các props của SectionList
sections |
renderItem |
initialNumToRender |
keyExtractor |
renderSectionHeader |
renderSectionFooter |
onRefresh |
inverted |
extraData |
onEndReached |
keyExtractor |
legacyImplementation |
onViewableItemsChanged |
refreshing |
removeClippedSubviews |
ListHeaderComponent |
SectionSeparatorComponent |
stickySectionHeadersEnabled |
onEndReachedThreshold |
ListEmptyComponent |
Ví dụ về React Native SectionList
Trong ví dụ này, chúng ta sẽ tạo một SectionList
với title và dữ liệu. sections prop
được sử dụng để tạo danh sách của các giá trị của title and dữ liệu. renderSectionHeader
hiển thị phần tiêu đề của list view
.
import React, { Component } from 'react';
import { AppRegistry, SectionList, StyleSheet, Text, View } from 'react-native';
export default class SectionListBasics extends Component {
render() {
return (
<View style={styles.container}>
<SectionList
sections={[
{title: 'A', data: ['ALTERED','ABBY','ACTION U.S.A.','AMUCK','ANGUISH']},
{title: 'B', data: ['BEST MEN','BEYOND JUSTICE','BLACK GUNN','BLOOD RANCH','BEASTIES']},
{title: 'C', data: ['CARTEL', 'CASTLE OF EVIL', 'CHANCE', 'COP GAME', 'CROSS FIRE',]},
]}
renderItem={({item}) => <Text style={styles.item}>{item}</Text>}
renderSectionHeader={({section}) => <Text style={styles.sectionHeader}>{section.title}</Text>}
keyExtractor={(item, index) => index}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#5ead97"
},
sectionHeader: {
paddingTop: 2,
paddingLeft: 10,
paddingRight: 10,
paddingBottom: 2,
fontSize: 22,
fontWeight: 'bold',
color: "#fff",
backgroundColor: '#8fb1aa',
},
item: {
padding: 10,
fontSize: 18,
height: 44,
}
})
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => SectionListBasics);
Output:
Adding Separator in SectionList
ItemSeparatorComponent
thêm dấu phân cách giữa các danh sách data . Để sử dụng phần hỗ trợ này, hãy gọi một renderSeparatormethod
, trong đó chúng ta thêm một thành phần View
làm dấu phân cách.
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: "100%",
backgroundColor: "#000",
}}
/>
);
};
ItemSeparatorComponent={this.renderSeparator}
Performing action on SectionList items
Để thực hiện một hành động khi nhấp (nhấn) vào mục danh sách, chúng ta sử dụng một phần mềm hỗ trợ onPress
. Hỗ trợ onPress
và xử lý sự kiện trong phương thức getListViewItem
khác.
//handling onPress action
getListViewItem = (item) => {
alert(item);
}
renderItem={({item}) => <Text style={styles.item}
onPress={this.getListViewItem.bind(this, item)}>{item}</Text>}
Output:
Phần 10: React Native Touchables
Các thành phần Touchable
cung cấp khả năng thực hiện các chức năng cảm ứng chạm. Thành phần touchable
có thể được cài đặt để thay thế cho các nút cơ bản nếu chúng không phù hợp với ứng dụng của bạn. Sử dụng các thành phần này thì bạn có thể xây dựng nút riêng của mình. Gõ vào các thành phần này, bạn có thể hiển thị các phản hồi.
Các thành phần touchables
không cung cấp bất kỳ kiểu mặc định nào, vì vậy bạn sẽ phải tự tạo kiểu để trình bày trong ứng dụng.
Các kiểu thành phần Touchable
Có 4 thành phần touchable được cung cấp bởi React Native. Lựa chọn các thành phần này tùy theo kiểu phản hồi mà bạn muốn cung cấp:
-
TouchableHighlight
-
TouchableNativeFeedback
-
TouchableOpacity
-
TouchableWithoutFeedback.
React Native TouchableHighlight
TouchableHighlight
có thể đước sử dụng ở các nút hoặc link trên web. Nền của thành phần này sẽ tối đi nếu bạn nhấn vào nó.
Props
Props |
Kiểu |
Bắt buộc |
Nền tảng |
Mô tả |
activeOpacity |
number |
Không |
|
Quyết định độ mờ của wrapped view khi được chạm vào. |
onHideUnderlay |
function |
Không |
|
Gọi ngay lập tức khi lớp dưới bị ẩn đi. |
onShowUnderlay |
function |
Không |
|
Gọi ngay lập tức khi lớp dưới được hiện ra. |
style |
View.style |
Không |
|
|
underlayColor |
color |
Không |
|
Hiển thị màu lớp dưới khi kích hoạt chạm. |
hasTVPreferredFocus |
bool |
Không |
iOS |
Hiệu ứng TV preferred focus, chỉ hoạt động với iOS. |
tvParallaxProperties |
object |
Không |
iOS |
Là một đối tượng với các property điều kiển các hiệu ứng parallax của Apple TV. |
React Native TouchableNativeFeedback
TouchableNativeFeedback
khiến một view phản hồi đúng khi chạm vào. Thành phần này chỉ hoạt động với hệ điều hành Android. Nó sử dụng native state drawable
để hiển thị phản hồi chạm.
Nó chỉ hỗ trợ một lần View
đơn nhất như một node con. Nó được cài đặt bằng cách thay thế View với một lần RCTView node
khác.
Props
Props |
Kiểu |
Bắt buộc |
Mô tả |
background |
backgroundPropType |
no |
Quyết định background drawable được hiển thị là một phản hồi. |
useForeground |
bool |
no |
Tạo hiệu ứng sóng cho phần nổi của view, thay vì phần nền. |
React Native TouchableOpacity
TouchableOpacity wrapper
được dùng để giảm độ mờ của nút. Nó cho phép có thể thấy được hình nền khi nhấn xuống. Độ mờ của nút được kiểm soát bằng cách gói thành phần con trong một Animation.
Props
Props |
Kiểu |
Bắt buộc |
Nền tảng |
Mô tả |
activeOpacity |
number |
Không |
|
Quyết định độ mờ của wrapped view khi được chạm vào. |
tvParallaxProperties |
object |
Không |
iOS |
Là một đối tượng với property được sử dụng để kiểm soát các hiệu ứng parallax của Apple TV. |
hasTVPreferredFocus |
bool |
Không |
iOS |
Hiệu ứng TV preferred focus, chỉ hoạt động với Apple TV. |
Các phương thức
Phương thức |
Mô tả |
setOpacityTo() |
Tạo hoạt ảnh cho touchable đến một độ mờ mới. |
React Native TouchableWithoutFeedback
TouchableWithoutFeedback
sử dụng khi người dùng muốn thao tác với chức năng chạm nhưng không muốn hiển thị phản hồi.
Props
Props |
Kiểu |
Bắt buộc |
Mô tả |
hitSlop |
object |
Không |
Định nghĩa vùng bạn có thể chạm được là bao xa kể từ nút. |
onAccessibilityTap |
function |
Không |
Nếu accessible được đặt là true, hệ thống sẽ khởi động chức năng khi người dùng thực hiện các cử chỉ tiện ích truy cập. |
accessibilityHint |
string |
Không |
Giúp người dùng hiểu điều gì sẽ xảy ra khi họ thực hiện hành động trên phần tử tiện ích truy cập. |
accessibilityLabel |
node |
Không |
Đè lên phần văn bản, mà sẽ được đọc bởi trình đọc màn hình khi người dùng tương tác với phần tử. |
delayLongPress |
number |
Không |
Hoãn cuộc gọi onPressIn của onLongPress trong khoảng milli-giây. |
Đôi khi người dùng nhấn vào view và giữ trong một khoảng thời gian. Việc nhấn giữ sẽ được xử lý bởi một hàm sử đụng onLongPress props
của bất kỳ các thành phần "Touchable"
nào ở trên.
Ví dụ về React Native Touchables
import React, { Component } from 'react';
import { Alert,Platform,StyleSheet,Text,TouchableHighlight,TouchableOpacity,
TouchableNativeFeedback,TouchableWithoutFeedback, View } from 'react-native';
export default class Touchables extends Component {
_onPressButton() {
Alert.alert('You tapped the button!')
}
_onLongPressButton() {
Alert.alert('You long-pressed the button!')
}
render() {
return (
<View style={styles.container}>
<TouchableHighlight onPress={this._onPressButton} underlayColor="white">
<View style={styles.button}>
<Text style={styles.buttonText}>TouchableHighlight</Text>
</View>
</TouchableHighlight>
<TouchableOpacity onPress={this._onPressButton}>
<View style={styles.button}>
<Text style={styles.buttonText}>TouchableOpacity</Text>
</View>
</TouchableOpacity>
<TouchableNativeFeedback
onPress={this._onPressButton}
background={Platform.OS === 'android' ? TouchableNativeFeedback.SelectableBackground() : ''}>
<View style={styles.button}>
<Text style={styles.buttonText}>TouchableNativeFeedback</Text>
</View>
</TouchableNativeFeedback>
<TouchableWithoutFeedback
onPress={this._onPressButton}
>
<View style={styles.button}>
<Text style={styles.buttonText}>TouchableWithoutFeedback</Text>
</View>
</TouchableWithoutFeedback>
<TouchableHighlight onPress={this._onPressButton} onLongPress={this._onLongPressButton} underlayColor="white">
<View style={styles.button}>
<Text style={styles.buttonText}>Touchable with Long Press</Text>
</View>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
paddingTop: 60,
alignItems: 'center'
},
button: {
marginBottom: 30,
width: 260,
alignItems: 'center',
backgroundColor: '#5ead97'
},
buttonText: {
padding: 20,
color: 'white',
fontSize: 18
}
});
Output:
Phần 11: React Native Text Input
TextInput
là một thành phần cơ bản để nhập văn bản. Nó có một vài prop để tùy chỉnh các chức năng khác nhau, chẳng hạn như onChangeText
lấy một hàm function và gọi nó bất cứ khi nào văn bản thay đổi. onSubmitEditing
lấy một hàm và gọi nó bất cứ khi nào một văn bản được gửi đi.
Có mộ vài việc mà bạn có thể làm với text input
, chẳng hạn như xác thực văn bản bên trong khi người nhập gõ vào.
React Native TextInput Ví dụ 1
Trong ví dụ này, chúng ta tạo một TextInput
và thực hiện một hành động onChangeText
. Bất cứ lúc nào văn bản thay đổi, nó sẽ gọi setState
và kiểm tra điều kiện của một split. Nếu input text
tìm thấy ''space, it displays''
trong văn bản. Văn bản sẽ được đặt vào một state
mà sẽ thay đổi liên tục.
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,backgroundColor: 'azure', fontSize: 20}}
placeholder="Type here to translate!"
onChangeText={(text) => this.setState({text})}
/>
<Text style={{padding: 100, fontSize: 50}}>
{this.state.text.split(' ').map((word) => word && '🍕').join(' ')}
</Text>*
</View>
);
}
}
Output
Các property của TextInput
allowFontScaling |
autoCapitalize |
autoCorrect |
autoFocus |
blurOnSubmit |
caretHidden |
clearButtonMode |
clearTextOnFocus |
contextMenuHidden |
dataDetectorTypes |
defaultValue |
disableFullscreenUI |
editable |
enablesReturnKeyAutomatically |
inlineImageLeft |
inlineImagePadding |
keyboardAppearance |
keyboardType |
maxLength |
multiline |
numberOfLines |
onBlur |
onChange |
onChangeText |
onContentSizeChange |
onEndEditing |
onFocus |
onKeyPress |
onLayout |
onScroll |
onSelectionChange |
onSubmitEditing |
placeholder |
placeholderTextColor |
returnKeyLabel |
returnKeyType |
scrollEnabled |
secureTextEntry |
selection |
selectionColor |
selectionColor |
selectionState |
selectTextOnFocus |
spellCheck |
textContentType |
style |
textBreakStrategy |
underlineColorAndroid |
Phương thức .focus()
và .blur()
được phô ra từ các phần tử gốc. Các phương thức này sẽ tập trung vào hoặc làm mờ TextInput
theo như đã lập trình sẵn.
Multiline TextInput
multiline prop
cung cấp cơ sở để nhập nhiều dòng văn bản. Một số prop của TextInput
chỉ tương thích với multiline
, chẳng hạn như, multiline={true/false}
. Property borderButtomColor
sẽ không hoạt động nếu multiline = false
.
React Native TextInput Ví dụ 2
import React, { Component } from 'react';
import { AppRegistry, View, TextInput } from 'react-native';
class UselessTextInput extends Component {
render() {
return (
<TextInput
{...this.props} // Inherit any props passed to it; e.g., multiline, numberOfLines below
editable = {true}
maxLength = {40}
/>
);
}
}
export default class UselessTextInputMultiline extends Component {
constructor(props) {
super(props);
this.state = {
text: 'Useless Multiline Placeholder',
};
}
render() {
return (
<View style={{
backgroundColor: this.state.text,
borderBottomColor: '#000000',
borderBottomWidth: 1,
}}
>
<UselessTextInput
multiline = {true}
numberOfLines = {10}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
style={{fontSize: 20}}
/>
</View>
);
}
}
Output
Phần 12: React Native ActivityIndicator
ActivityIndicator
sử dụng để hiển thị biểu tượng đang tải hình tròn.
Props
Props |
Mô tả |
animating |
Lựa chọn để hiển thị biểu tượng (mặc định là true) hoặc ẩn nó đi (false). |
size |
Đặt kích cỡ của biểu tượng ('small','large', số). kích cỡ mặc định là small. Định dạng số chỉ hỗ trợ trên Android. |
color |
Đặt màu phần nổi của con quay (mặc định là màu xám). |
hidesWhenStopped |
Lựa chọn hiển thị hoặc ẩn biểu tượng khi không có hoạt động (mặc định là true). |
Ví dụ về React Native ActivityIndicator
Trong ví dụ này, animating property
sẽ đặt hoạt động của biểu tượng thành true
, và hiển thị trên màn hình. Khi thành phần được tải lên, biểu tượng chỉ thị hoạt động sẽ được tắt đi sau 6 giây, sử dụng phương thức closeActivityIndicator()
.
import React, { Component } from 'react'
import {
ActivityIndicator,
AppRegistry,
StyleSheet,
Text,
View,
} from 'react-native'
export default class ActivityIndicatorDemo extends Component {
state = { animating: true }
closeActivityIndicator = () => setTimeout(() => this.setState({
animating: false }), 6000)
componentDidMount = () => this.closeActivityIndicator()
render() {
const animating = this.state.animating
return (
<View style={[styles.container, styles.horizontal]} >
<ActivityIndicator animating = {animating} size="large" color="#ff0000" />
<ActivityIndicator size="small" color="#44ff00" />
<ActivityIndicator size="large" color="#rtwrw" />
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center'
},
horizontal: {
flexDirection: 'row',
justifyContent: 'space-around',
padding: 10
}
})
AppRegistry.registerComponent('App', () => ActivityIndicatorDemo)
Output:
Phần 13: React Native Picker
React Native Picker
là một hoạt động để chọn một item từ nhiều lựa chọn. Việc này sẽ tương tự như lựa chọn Dropdown
. Picker được sử dụng khi chúng ta cần cung cấp một lựa chọn thay thế từ nhiều phương án.
Nó được sử dụng bằng cách import
thành phần Picker từ thư viện react-native
.
Các Prop của Picker
Prop |
Mô tả |
onValueChange( itemValue, itemPosition) |
Là một callback prop và được gọi khi item được chọn. Nó cần 2 tham số (itemValue: item (giá trị) được chọn, itemPosition: vị trí (chỉ mục) của item được chọn). |
selectedValue |
Trả về giá trị được chọn. |
style |
Là một kiểu picket style. |
testID |
Sử dụng để xác định view trong kiểm thử đầu-cuối. |
enabled |
Là một Boolean prop để vô hiệu hóa picker khi được đặt về false. Nếu nó được đặt về false thì người dùng sẽ không thể lựa chọn được. |
mode |
Trên Android, nó xác định cụ thể cách hiển thị các item lựa chọn khi người dùng click vào picker. Nó có các property là "dialog" và "dropdown". Dialog là chế độ mặc định và sẽ hiển thị là một hộp thoại thông báo. Dropdown hiển thị picker là một view neo thả. |
prompt |
Được sử dụng trên Android với chế độ hộp thoại như là title của hộp thoại. |
itemStyle |
Tạo kiểu cho mỗi item của các nhãn picker. |
Ví dụ về React Native Picker
Trong ví dụ này, chúng ta sẽ tạo 3 item label trong thành phần Picker. Khi item
được chọn từ Picker, nó gọi hàm callback onValueChange
và đặt item
được chọn vào picker. Chỉ mục của item được đọc từ itemPosition. Vị trí của item
được hiển thị rong một thành phần Text.
App.js
import React, { Component } from 'react'
import {StyleSheet,View, Text,Picker} from 'react-native'
export default class SwitchExample extends Component {
state = {
choosenIndex: 0
};
render() {
return (
<View style={styles.container}>
<Text style={styles.textStyle}>Picker Example</Text>
<Picker style={styles.pickerStyle}
selectedValue={this.state.language}
onValueChange={(itemValue, itemPosition) =>
this.setState({language: itemValue, choosenIndex: itemPosition})}
>
<Picker.Item label="Java" value="java" />
<Picker.Item label="JavaScript" value="js" />
<Picker.Item label="React Native" value="rn" />
</Picker>
<Text style={styles.textStyle}> {"Index ="+this.state.choosenIndex}</Text>
</View>
);
}
}
const styles = StyleSheet.create ({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
textStyle:{
margin: 24,
fontSize: 25,
fontWeight: 'bold',
textAlign: 'center',
},
pickerStyle:{
height: 150,
width: "80%",
color: '#344953',
justifyContent: 'center',
}
})
Output:
Phần 14: React Native StatusBar
React Native StatusBar
là một thành phần để trang trí thanh trạng thái của ứng dụng. Nó được sử dụng bằng cách Import
thành phần StatusBar
từ thư viện react-native
. Chúng ta có thể sử dụng nhiều StatusBar cùng một lúc.
<View>
<StatusBar
backgroundColor = "#b3e6ff"
barStyle = "dark-content"
/>
</View>
<View>
<StatusBar
backgroundColor = "#b3e6ff"
barStyle = "dark-content"
/>
<View>
<StatusBar
hidden={route.statusBarHidden} />
</View>
</View>
Các Prop của React Native StatusBar
Props |
Description |
animated |
Thanh trạng thái sẽ có hoạt ảnh nếu property của nó thay đổi. Nó hỗ trợ backgrondColor, hidden, và barStyle. |
barStyle |
Nó đặt màu của văn bản trên thanh trạng thái. |
hidden |
Dùng để ẩn và hiện thânh trạng thái. Mặc định sẽ là false. Nếu hidden = {false} thì nó sẽ được hiển thị, nếu hidden = {true}, thì nó sẽ ẩn thanh trạng thái. |
backgroundColor |
Đặt màu nền của thanh trạng thái. |
translucent |
Nếu được đặt về true, ứng dụng sẽ được xây dựng bên dưới thanh trạng thái. |
showHideTransition |
Hiển thị hiệu ứng chuyển đổi khi hiển thị và ẩn thanh trạng thái. Giá trị mặc định là 'fade'. |
networkActivityIndicatorVisible |
Kiểm tra biểu tượng mạng có hiển thị hay không. Hỗ trợ trong iOS. |
Các phương thức của React Native StatusBar
setHidden |
setBarStyle |
setBackgroundColor |
setNetworkActivityIndicatorVisible |
setTranslucent |
|
React Native StatusBar Ví dụ 1
Hãy tạo một StatusBar
đơn giản và thay đổi màu nền của nó.
App.js
import React, { Component } from 'react'
import {
View,StyleSheet,AppRegistry,StatusBar
} from 'react-native'
export default class ActivityIndicatorDemo extends Component {
render() {
return (
<View style = {styles.container}>
<StatusBar
backgroundColor = "#b3e6ff"
barStyle = "dark-content"
hidden = {false}
translucent = {true}
/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
}
})
AppRegistry.registerComponent('App', () => ActivityIndicatorDemo)
Output:
React Native StatusBar Ví dụ 2 (ẩn thanh trạng thái, toàn màn hình)
Trong ví dụ này, chúng ta sẽ ẩn StatusBar
bằng property hidden = true
. Ẩn StatusBar
thì sẽ hiển thị toàn màn hình.
import React, { Component } from 'react'
import {
View,StyleSheet,AppRegistry,StatusBar
} from 'react-native'
export default class ActivityIndicatorDemo extends Component {
render() {
return (
<View>
<StatusBar backgroundColor="#b3e6ff" barStyle="light-content" />
<View>
<StatusBar hidden={true} />
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
}
})
AppRegistry.registerComponent('App', () => ActivityIndicatorDemo)
Output:
Phần 15: React Native Switch
React Native Switch
là một thành phần điều khiển kiểu Boolean
đặt các giá trị của nó thành true
hoặc false
. Nó có một phương thức callback onValueChange
để cập nhật prop giá trị của nó. Nếu prop
giá trị không thay đổi, thành phần Switch
tiếp tục cung cấp cho prop
giá trị thay vì kết quả được kì vọng của bất kì hành động nào của người dùng.
Các props của Switch
Props |
Mô tả |
disabled |
Là một Boolean property, nếu được đặt về true thì sẽ không thể bật/tắt công tắc. Giá trị mặc định là false. |
trackColor |
Sử dụng để tùy chỉnh màu của rãnh công tắc. |
ios_backgroundColor |
Đặt màu nền trên iOS. Nền có thể được hiển thị khi giá trị của công tắc là bị vô hiệu hóa hay khi switch là false. |
onValueChange |
Kích hoạt khi giá trị của công tắc thay đổi. |
testID |
Sử dụng để định vị view trong kiểm thử đầu-cuối. |
thumbColor |
Đổi màu phần nổi của tay nắm công tắc. Khi được chuyển sang iOS, tay nắm công tắc sẽ mất đi phần đổ bóng. |
tintColor |
Đặt màu viền trên iOS và màu nền trên Android khi công tắc được tắt. Property này hiện không còn được dùng nữa; chúng ta sử dụng trackColor để thay thế. |
value |
Là giá trị của công tắc. Nếu đặt là true thì công tắc bật. Giá trị mặc định là false. |
Ví dụ về React Native Switch
Trong ví dụ này, ban đầu chúng ta sẽ đặt giá trị của Switch là false
và hiển thị dòng văn bản là 'off'
. Khi giá trị của Switch chuyển sang true
bằng cách gọi onValueChange
thì thành phần Text được chuyển thành 'on'
.
App.js
import React, { Component } from 'react'
import {StyleSheet, Switch, View, Text} from 'react-native'
export default class SwitchExample extends Component {
state = {
switchValue: false
};
render() {
return (
<View style={styles.container}>
<Text style={styles.textStyle}>Switch Example</Text>
<Text style={styles.textStyle}>{this.state.switchValue ? 'on' :'off'}</Text>
<Switch
value={this.state.switchValue}
onValueChange ={(switchValue)=>this.setState({switchValue})}/>
</View>
);
}
}
const styles = StyleSheet.create ({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
textStyle:{
margin: 24,
fontSize: 25,
fontWeight: 'bold',
textAlign: 'center',
color: '#344953'
}
})
Output:
Phần 16: React Native WebView
React Native WebView
được sử dụng để tải nội dung web content
hoặc trang web. Thành phần WebView
được import
từ thư viện core react-native
. Hiện tại, WebView được thay từ thư viện built-in core react-native
, và được đặt trong thư viện react-native-webview
.
Chú ý: React Native WebView được khuyển khích import từ thư viện react-native-webview
hoặc từ thư viện react-native-community.
Các props của WebView
source |
injectJavaScript |
injectedJavaScript |
onError |
onLoad |
onLoadEnd |
onLoadStart |
onMessage |
originWhitelist |
renderError |
style |
userAgent |
html |
url |
geolocationEnabled |
scrollEnabled |
contentInset |
bounces |
allowFileAccess |
nativeConfig |
Các kiểu nội dung của WebView:
Hiển thị code HTML dưới dạng một chuỗi: Chuỗi code HTML được truyền vào html prop
trong source property
.
<WebView
source={{html: '<h1>Hello javaTpoint</h1>'}}
/>
Hiển thị trang web nội bộ: Tạo một trang web bên trong một thư mục và chuyển đường dẫn đầy đủ của nó vào source property
.
<WebView
source={require("./resources/index.html")}
/>
Hiển thị trang web từ xa: Tải một trang web từ xa bằng thẻ uri
với source property
.
<WebView
source = {{ uri:'https://www.javatpoint.com' }}
/>
React Native WebView Ví dụ 1
Trong ví dụ này, chúng ta sẽ tải một trang web bằng cách truyền URL của nó vào source prop
của thành phần WebView.
App.js
1. import React, { Component } from 'react'
2. import {
3. View,WebView,StyleSheet,AppRegistry
4. } from 'react-native'
5.
6. export default class ActivityIndicatorDemo extends Component {
7. render() {
8. return (
9. <View style = {styles.container}>
10. <WebView
11. source = {{ uri:'https://www.javatpoint.com' }}
12. />
13. </View>
14. )
15. }
16. }
17. const styles = StyleSheet.create({
18. container: {
19. flex: 1,
20. }
21. })
22.
23. AppRegistry.registerComponent('App', () => ActivityIndicatorDemo)
Output :
React Native WebView Ví dụ 2
Trong ví dụ này, chúng ta sẽ import WebView từ react-native-webview
.
App.js
import React, { Component } from 'react'
import {
View,StyleSheet,AppRegistry
} from 'react-native'
import {WebView} from 'react-native-webview'
export default class ActivityIndicatorDemo extends Component {
render() {
return (
<View style = {styles.container}>
{/*<WebView
source={{html: '<h1>Hello javaTpoint</h1>'}}
/>*/}
{/* <WebView
source={require("./resources/index.html")}
/>*/}
<WebView
source = {{ uri:'https://www.javatpoint.com' }}
/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
}
})
AppRegistry.registerComponent('App', () => ActivityIndicatorDemo)
Output:
Note: Nếu bạn nhận được thông báo lỗi module react-native-webview không tồn tại trong module map react native. Thì hãy chắc chắn là bạn đã cài đặt các thư viện dưới đây:
-
npm install -g yarn
-
yarn add react-native-webview
-
react-native link react-native-webview
Phần 17: React Native ProgressBar
1. React Native ProgressBarAndroid
Thành phần ProgressBarAndroid của React Native được sử dụng để biểu thị tiến trình của một số hoạt động hay ứng dụng đang tải một cái gì đó. Thành phần ProgressBarAndroid chỉ hoạt động trên nền tảng Android. Để sử dụng thanh tiến trình trên nền tảng iOS thì chúng ta sẽ sử dụng thành phần ProgressViewIOS .
Các Props của ProgressBarAndroid
Props |
Kiểu |
Bắt buộc |
Mô tả |
animating |
bool |
Không |
Được sử dụng để hiện hoặc ẩn thanh tiến trình. Giá trị mặc định là true để hiện, (false để ẩn). |
color |
color |
Không |
Đặt màu của thanh tiến trình. |
indeterminate |
indeterminateType |
Không |
Hiển thị trạng thái tiến trình trung bình của thanh tiến trình. Chỉ có thể là false nếu styleAttr của thanh tiến trình là Horizontal. |
progress |
number |
Không |
Là giá trị của tiến trình giữa 0 và 1. |
styleAttr |
enum |
Không |
Đặt kiểu của thanh tiến trình. Có nhiều kiểu thanh tiến trình trong React Native như Horizontal, Normal (mặc định), Small, Large, Inverse, SmallInverse, và LargeInverse. |
testID |
string |
Không |
Sử dụng để định vị view trong kiểm thử đầu cuối. |
Ví dụ về React Native ProgressBarAndroid
Trong ví dụ này, chúng ta sẽ đặt ProgressBarAndroid ngang và thực hiện hành động trên thành phần TouchableOpacity. Trạng thái tiến trình sẽ được hiển thị trong thành phần Text chỉ lên đến 3 chữ số.
import React, { Component } from 'react';
import { Platform, StyleSheet, View, Text, TouchableOpacity, ProgressBarAndroid, ProgressViewIOS } from 'react-native';
export default class MyApp extends Component<{}>{
constructor() {
super();
this.state = {
progressStatus: 0,
}
}
start_Progress = () => {
this.value = setInterval( () => {
if(this.state.progressStatus <= 1){
this.setState({progressStatus: this.state.progressStatus+ .01})
}
}, 100 );
}
stop_Progress = () =>{
clearInterval(this.value);
}
clear_Progress =()=>{
this.setState({progressStatus : 0.0})
}
render()
{
return(
<View style = { styles.MainContainer }>
<Text style = {{fontSize: 20, color: '#000'}}> Progress Value: { parseFloat((this.state.progressStatus * 100).toFixed(3))} %</Text>{
( Platform.OS === 'android' )
?
( <ProgressBarAndroid styleAttr = "Horizontal" progress = { this.state.progressStatus } indeterminate = { false } /> )
:
( <ProgressViewIOS progress = { this.state.progressStatus } /> )
}
<TouchableOpacity activeOpacity = { 1 } style = { styles.button } onPress = { this.start_Progress }>
<Text style = { styles.TextStyle }> Start Progress </Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity = { 1 } style = { styles.button } onPress = { this.stop_Progress }>
<Text style = { styles.TextStyle }> Stop Progress </Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity = { 1 } style = { styles.button } onPress = { this.clear_Progress }>
<Text style = { styles.TextStyle }> Reset Progress </Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create(
{
MainContainer:
{
flex: 1,
justifyContent: 'center',
paddingTop: ( Platform.OS === 'ios' ) ? 20 : 0,
margin: 20
},
button: {
width: '100%',
backgroundColor: '#00BCD4',
borderRadius:5,
padding: 10,
marginTop: 10,
},
TextStyle:{
color:'#fff',
textAlign:'center',
fontWeight: 'bold',
}
});
Output:
2. React Native ProgressBar Với Animated
Trong phần trước về ProgressBarAndroid chúng ta đã học cách hiển thị thanh tiến trình mặc định. Tuy nhiên, chúng ta cũng có thể tùy chỉnh thanh tiến trình với lớp Animated.
Ví dụ về React Native ProgressBar với Animated
Để tạo một thanh tiến trình có hoạt ảnh thì chúng ta sẽ import lớp Animated. Thêm các thành phần Animated.View và Animated.Text vào trong View. Đặt giá trị ban đầu cho biến trạng thái tiến trình thành 0 và gọi phương thức onAnimate()
. Phương thức này sẽ kích hoạt khi màn hình tải xong hoàn toàn (gọi componentDidMount()
). Thêm một listener trên phương thức onAnimate() method
để cập nhật trạng thái tiến trình.
App.js
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Animated} from 'react-native';
export default class App extends Component {
state={
progressStatus: 0,
}
anim = new Animated.Value(0);
componentDidMount(){
this.onAnimate();
}
onAnimate = () =>{
this.anim.addListener(({value})=> {
this.setState({progressStatus: parseInt(value,10)});
});
Animated.timing(this.anim,{
toValue: 100,
duration: 50000,
}).start();
}
render() {
return (
<View style={styles.container}>
<Animated.View
style={[
styles.inner,{width: this.state.progressStatus +"%"},
]}
/>
<Animated.Text style={styles.label}>
{this.state.progressStatus }%
</Animated.Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
width: "100%",
height: 40,
padding: 3,
borderColor: "#FAA",
borderWidth: 3,
borderRadius: 30,
marginTop: 200,
justifyContent: "center",
},
inner:{
width: "100%",
height: 30,
borderRadius: 15,
backgroundColor:"green",
},
label:{
fontSize:23,
color: "black",
position: "absolute",
zIndex: 1,
alignSelf: "center",
}
});
Trạng thái tiến trình của thanh tiến trình được cập nhật với chu kỳ mỗi 0.5 giây (50000 micro giây). Cùng lúc đó thì chiều dài của thanh tiến trình được quyết định bằng trạng thái của tiến trình, và trạng thái của nó được đặt vào thành phần Animated.Text.
Output:
II. Kiến thức nâng cao
Phần 1: React Native Animation và Image
1. React Native Animation
React Native Animations cung cấp thêm các hiệu ứng và trải nghiệm người dùng tuyệt vời cho ứng dụng. Các hoạt ảnh thể hiện chuyển động của các phần tử trong giao diện của bạn.
Có 2 loại hệ thống hoạt ảnh bổ sung trong React Native. Đó là:
-
Animated: Animated API để điều kiển một cách tương tác các giá trị. Nó tập trung vào mối quan hệ khai báo giữa các input và output. Nó có các phương thức start và stop để điều khiển việc thực thi các hoạt ảnh dựa trên thời gian.
Animated export 4 thành phần hiệu ứng khác nhau đó là View, Text, Image và ScrollView. Chúng ta có thể tạo thành phần animated của riêng mình bằng Animated.createAnimatedComponent()
.
-
LayoutAnimated: LayoutAnimated sử dụng để tạo hiệu ứng cho các giao tác (transactions) của toàn bộ layout.
Các phương thức của Animated
Methods |
Description |
Animated.timing() |
Tạo hiệu ứng cho giá trị theo thời gian sử dụng nhiều đường cong nới, hoặc sử dụng hàm của riêng nó. |
Animated.event() |
Nó trực tiếp sắp xếp sự kiện vào các giá trị được tạo hiệu ứng. |
Animated.spring() |
Tạo hiệu ứng cho giá trị. Nó theo dõi tốc độ của state để tạo ra các chuyển động mượt mà dưới dạng các cập nhật toValue . |
Animated.decay() |
Nó khởi động hiệu ứng với một tốc độ ban đầu và chậm dần đến khi dừng lại. |
React Native Animation Ví dụ 1 (Animated.timing())
Trong ví dụ này, chúng ta sẽ tạo hiệu ứng quay tròn trên hình ảnh sử dụng Animated.timing()
.
App.js
import React, { Component } from 'react';
import {StyleSheet, AppRegistry,Text, View,Animated,Easing} from 'react-native';
export default class DisplayAnImage extends Component {
constructor () {
super()
this.spinValue = new Animated.Value(0)//declare spinValue as a new Animated.Value and pass 0 (zero) in it.
}
componentDidMount () {
this.spin()
}
//create a spin method and call it from componentDidMount
spin () {
this.spinValue.setValue(0) //set spinValue to 0 (zero)
Animated.timing( //calling Animated.timing() method, it takes two arguments:
this.spinValue, // value
{ // and config object
toValue: 1, //and setting spinValue to 1
duration: 4000, //within 4000 milliseconds
easing: Easing.linear
}
).start(() => this.spin())
}
render () {
const spin = this.spinValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg']
})
return (
<View style={styles.container}>
<Animated.Image
style={{
width: 227,
height: 200,
transform: [{rotate: spin}] }}
source={require('MyReactNativeApp/img/react-logo.png')}
/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
})
// skip this line if you are using Create React Native App
AppRegistry.registerComponent('DisplayAnImage', () => DisplayAnImage);
Phương thức interpolate()
gọi bất kỳ Animated.Value nào. Nó sẽ thêm vào giá trị trước khi cập nhật property. Trong ví dụ trên, chúng ta đã sắp đặt từ 0 (zero) độ đến 360 độ.
Chúng ta truyền một inputRange [0,1] và lấy mảng outputRange['0deg', '360deg']
.
Output:
React Native Animation Ví dụ 2 (Animated.timing())
Trong ví dụ này, chúng ta sẽ khai báo một giá trị có hiệu ứng duy nhất this.aninatedValue
và sử dụng nó với interpolate để tạo nhiều hiệu ứng như: marginLeft, opacity, fontSize, và rotate. Chúng ta sẽ thêm vào các property dành cho tạo kiểu như opacity, margins, text sizes, và rotation.
App.js
import React, { Component } from 'react';
import {StyleSheet, AppRegistry,Text, View,Animated,Easing} from 'react-native';
export default class DisplayAnImage extends Component {
constructor () {
super()
this.animatedValue = new Animated.Value(0)
}
componentDidMount () {
this.animate()
}//animate method is call from componentDidMount
animate () {
this.animatedValue.setValue(0)
Animated.timing(
this.animatedValue,
{
toValue: 1,
duration: 2000,
easing: Easing.linear
}
).start(() => this.animate())
}
render() {
const marginLeft = this.animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 300]
})
const opacity = this.animatedValue.interpolate({
inputRange: [0, 0.5, 1],
outputRange: [0, 1, 0]
})
const movingMargin = this.animatedValue.interpolate({
inputRange: [0, 0.5, 1],
outputRange: [0, 300, 0]
})
const textSize = this.animatedValue.interpolate({
inputRange: [0, 0.5, 1],
outputRange: [18, 32, 18]
})
const rotateX = this.animatedValue.interpolate({
inputRange: [0, 0.5, 1],
outputRange: ['0deg', '180deg', '0deg']
})
return (
<View style={styles.container}>
<Animated.View //returns Animated.View
style={{
marginLeft,
height: 30,
width: 40,
backgroundColor: 'red'}} />
<Animated.View
style={{
opacity,
marginTop: 10,
height: 30,
width: 40,
backgroundColor: 'blue'}} />
<Animated.View
style={{
marginLeft: movingMargin,
marginTop: 10,
height: 30,
width: 40,
backgroundColor: 'orange'}} />
<Animated.Text // returns Animated.Text
style={{
fontSize: textSize,
marginTop: 10,
color: 'green'}} >
Animated Text!
</Animated.Text>
<Animated.View
style={{
transform: [{rotateX}],
marginTop: 50,
height: 30,
width: 40,
backgroundColor: 'black'}}>
<Text style={{color: 'white'}}>Hello from TransformX</Text>
</Animated.View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 150
}
})
// skip this line if you are using Create React Native App
AppRegistry.registerComponent('DisplayAnImage', () => DisplayAnImage);
Output:
LayoutAnimation API
LayoutAnimation cho phép hiệu chỉnh, tạo và , cập nhật toàn bộ hiệu ứng. Nó sẽ được sử dụng cho tất cả các view trong chu kỳ render/layout kế tiếp.
LayoutAnimation khá là hữu dụng, nó có ít điều khiển hơn so với Animated và các thư viện hoạt ảnh khác.
Để sử dụng API này trong Android chúng ta cần phải đặt các cờ (flags) sau thông qua UIManager:
-
UIManager.setLayoutAnimationEnabledExperimental &&
-
UIManager.setLayoutAnimationEnabledExperimental(true);
Ví dụ về React Native LayoutAnimation
Trong ví dụ này, chúng ta sẽ taoh một thành phần TouchableOpacity và một thành phần View. Việc nhấn vào thành phần TouchableOpacity sẽ gọi phương thức the _onPress()
và tạo hiệu ứng cho thành phần View bằng cách tăng chiều rộng và chiều cao của View thêm 15 đơn vị.
import React from 'react';
import {
NativeModules,
LayoutAnimation,
Text,
TouchableOpacity,
StyleSheet,
View,
} from 'react-native';
const { UIManager } = NativeModules;
UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true);
export default class App extends React.Component {
state = {
w: 100,
h: 100,
};
_onPress = () => {
// Animate the update
LayoutAnimation.spring();
this.setState({w: this.state.w + 15, h: this.state.h + 15})
}
render() {
return (
<View style={styles.container}>
<View style={[styles.box, {width: this.state.w, height: this.state.h}]} />
<TouchableOpacity onPress={this._onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Press me!</Text>
</View>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
box: {
width: 200,
height: 200,
backgroundColor: 'blue',
},
button: {
backgroundColor: 'green',
paddingHorizontal: 20,
paddingVertical: 15,
marginTop: 15,
},
buttonText: {
color: '#fff',
fontWeight: 'bold',
},
});
Output:
2. React Native Image
Thành phần Image sử dụng để hiển thị hình ảnh trên màn hình. Hình ảnh có thể được tải từ các nguồn khác nhau như các nguồn tài nguyên tĩnh, các tệp cục bộ tạm thòi, ổ đĩa cục bộ, các hình ảnh trên mạng,..v..v...
Các nguồn tài nguyên hình ảnh tĩnh
Các hình ảnh tĩnh được thêm vào ứng dụng bằng cách đặt nó trong thư mục source code và cung cấp đường dẫn của nó như sau:
-
<Image source={require('./icon_name.png')} />
Trong cú pháp trên, trình đóng gói (packager) sẽ tìm kiếm icon_name.png trong cũng một thư mục với thành phần mà yêu cầu nó. Để tải hình ảnh trên một nền tảng cụ thể, thì nó cần phải được đặt tên bằng cách xác định cụ thể như một phần mở rộng, chẳng hạn như icon_name.ios.png và icon_name.android.png.
Hình ảnh từ các nguồn tài nguyên của Ứng dụng tổng hợp
Các ứng dụng tổng hợp được xây dựng (UI) bằng cả React Native và code của nền tảng cũng có thể sử dụng các hình ảnh được đóng gói cùng với ứng dụng.
Hình ảnh được đi kèm thông qua các bảng kê asset Xcode hay trong các thư mục Android drawable được sử dụng mà không có các phần ở rộng của chúng:
-
<Image source={{uri: 'icon_name'}} style={{width: 60, height: 60}} />
Các hình ảnh trong thư mục Android assets, sử dụng scheme: asset:/ với phần mở rộng của hình ảnh:
-
<Image source={{uri: 'asset:/icon_name.png'}} style={{width: 60, height: 60}} />
Các hình ảnh trên mạng
CÁc hình ảnh động và hình ảnh trên mạng cũng có thể được hiển thị trong thành phần Image. Để truy cập hình ảnh trên mạng thì bắt buộc phải xác định cụ thể các chiều của hình ảnh một cách thủ công.
Nên sử dụng https để đáp ứng các yêu cầu App Transport Security trên iOS.
// GOOD
<Image source={{uri: 'https://url_of_image.png'}}
style={{width: 60, height: 60}} />
// BAD
<Image source={{uri: 'https://url_of_image.png'}} />
Các hình ảnh Uri Data
Dữ liệu hình ảnh được mã hóa sử dụng scheme "data:" uri trong thành phần image. Hình ảnh dữ liệu sẽ được yêu cầu để xác định cụ thể các chiều của hình ảnh.
<Image
style={{width: 66, height: 66}}
source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='}}
/>
Hình nền thông qua phương pháp lồng nhau
Hình nền được đặt bằng thành phần ImageBackground. Nó cùng có các props như Image. Chúng ta có thể thêm bất kì thành phần con nào vào bên trên nó.
return (
<ImageBackground source={...} style={{width: '100%', height: '100%'}}>
<Text>Inside</Text>
</ImageBackground>
);
Ví dụ về React Native Image
App.js
import React, { Component } from 'react';
import {StyleSheet, AppRegistry,Text, View, Image,ImageBackground } from 'react-native';
export default class DisplayAnImage extends Component {
render() {
return (
<ImageBackground source = {{uri:'https://www.javatpoint.com/tutorial/react-native/images/react-native-tutorial.png'}}
style={{width: '100%', height: '100%'}}>
<Image source={require('./favicon.png')} />
<Image
source={require('/ReactNative/MyReactNativeApp/img/favicon.png')}
/>
<Image
source={require('MyReactNativeApp/img/favicon.png')}
/>
<Image source={{uri: 'asset:/images/favicon.png'}} style={{width: 60, height: 60}} />
<Image source = {{uri:'https://www.javatpoint.com/images/logo/jtp_logo.png'}}
style = {{ width: '80%', height: 70 }}
/>
<Image
style={{width: 60, height: 60}}
source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='}}
/>
</ImageBackground>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('DisplayAnImage', () => DisplayAnImage);
Output:
Phần 2: React Native APIs
1. React Native Alert
React Native Alert là một API được sử dụng để hiển thị các hộp thoại thông báo với các tiêu đề và nội dung cụ thể. Nó sử dụng một phương thức alert() để nhắc một hộp thoại thông báo. Hộp thoại Alert cung cấp 3 danh sách nút khác nhau (các tổ hợp của neutral, negative, và positive) để thực hiện các hành động. Nhấn bất kỳ nút nào sẽ gọi phương thức callback onPress và tắt thông báo đó đi. Ở mặc định, Alert chỉ có một nút positive (OK).
Alert có thể nhắc việc nhập thông tin được tạo ra bằng cách sử dụng AlertIOS. Điều này chỉ được hỗ trợ trên iOS.
React Native Alert trong iOS
Trong iOS, chúng ta có thể xác định cụ thể số nút. Mỗi nút có thể có một kiểu riêng, là một trong số default, cancel, hoặc destructive.
React Native Alert trong Android
Trong Android, nút của Alert được xác định bằng 3 nút. Những nút này là neutral, negative và positive:
Các nút Alertđược chia cụ thể thành 3 tổ hợp. Đó là:
-
Nếu chỉ xác định một nút, thì đó sẽ là nút 'positive' (chẳng hạn như 'OK').
-
Nếu xác định 2 nút, thì sẽ là 'negative' và 'positive' (chẳng hạn như 'Cancel' và 'OK').
-
Xác định 3 nút sẽ bao gồm cả 'neutral', 'negative', 'positive' (chẳng hạn như 'Later', 'Cancel', 'OK').
Trong Android, các thông báo mặc định được tắt đi bằng cách click vào bên ngoài hộp thoại thông báo. Việc tắt thông báo sẽ được xử lý bằng một tham số tùy chọn, với một onDismiss callback property { onDismiss: () => {} }. Tuy nhiên, chúng ta có thể vô hiệu hóa property tắt thông báo bằng cách sử dụng property {cancelable: false}.
Ví dụ về React Native Alert
Trong ví dụ này, chúng ta sẽ tạo 2 thông báo trên 2 nút. Một thông báo chứa 2 nút lựa chọn và không có property cancelable. Thông báo còn lại chứa 3 nút lựa chọn và giá trị của property cancelable là false.
App.js
import React, { Component } from 'react';
import { Alert, AppRegistry, Button, StyleSheet, View } from 'react-native';
export default class ButtonBasics extends Component {
showAlert1() {
Alert.alert(
'Alert Title',
'My Alert Msg',
[
{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel',
},
{text: 'OK', onPress: () => console.log('OK Pressed')},
]
);
}
showAlert2() {
Alert.alert(
'Alert Title',
'My Alert Msg',
[
{text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
{
text: 'Cancel',
onPress: () => console.log('Cancel Pressed'),
style: 'cancel',
},
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{cancelable: false}
)
}
render() {
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button
onPress={this.showAlert1}
title="Button 1"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={this.showAlert2}
title="Button 2"
color="#009933"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
buttonContainer: {
margin: 20
},
multiButtonContainer: {
margin: 20,
flexDirection: 'row',
justifyContent: 'space-between'
}
})
Output:
2. React Native Geolocation
Geolocation API được sử dụng để lấy vị trí địa lý (vĩ độ và kinh độ) của một địa điểm. Nó mở rộng phần vị trí địa lý của web. API này có sẵn trên toàn cầu thông qua navigator.geolocation, vì vậy bạn sẽ không cần phải import nó.
Trong Android, Geolocation API sử dụng android.location API. Tuy nhiên, API không được Google khuyên dùng bởi nó kém chính xác và chậm hơn so với Google Location Services API. Để sử dụng Google Location Services API trong React Native, chúng ta sử dụng module react-native-geolocation-service
.
Các tùy chỉnh và Thiết lập của React Native
Trong phần này, chúng ta sẽ thảo luận về các dự án được tạo bởi react-native init, expo init hoặc Create React Native App.
iOS:
Với nền tảng iOS, chúng ta sẽ bao gồm khóa NSLocationWhenInUseUsageDescription
vào Info.plist để bật geolocation. Geolocation mặc định được bật khi ứng dụng được tạo bằng react-native init.
Để bật Geolocation chạy ẩn, chúng ta sẽ bao gồm khóa 'NSLocationAlwaysUsageDescription'
trong Info.plist. Điều này đòi hỏi phải thêm các vị trí như một chế độ nền trong tab 'Capabilities' của Xcode.
Android:
Để truy cập vào vị trí trên Android, chúng ta cần phải thêm <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
vào tệp AndroidManifest.xml.
Android API >=23 đòi hỏi phải yêu cầu quyền ACCESS_FINE_LOCATION sử dụng PermissionsAndroid API.
Các phương thức của Geolocation
Phương thức |
Mô tả |
getCurrentPosition() |
Kích hoạt success callback một lần với thông tin mới nhất về vị trí. |
watchPosition() |
Kích hoạt success callback khi nào vị trí thay đổi. Nó trả về một watchId (số). |
clearWatch() |
Xóa watchId của watchPosition(). |
stopObserving() |
Ngừng quan sát thay đổi vị trí của thiết bị cũng như loại bỏ tất cả các listener đã được đăng ký trước đó. |
setRNConfiguration() |
Đặt các lựa chọn tùy chỉnh, được sử dụng trong tất cả các yêu cầu vị trí. |
requestAuthorization() |
Nó yêu cầu các quyền vị trí thích hợp dựa trên khóa được tùy chỉnh trên pList. |
Ví dụ về React Native Geolocation
App.js
import React from 'react';
import { StyleSheet,Platform, Text, View } from 'react-native';
export default class App extends React.Component {
constructor(){
super();
this.state = {
ready: false,
where: {lat:null, lng:null},
error: null
}
}
componentDidMount(){
let geoOptions = {
enableHighAccuracy:false,
timeOut: 20000, //20 second
// maximumAge: 1000 //1 second
};
this.setState({ready:false, error: null });
navigator.geolocation.getCurrentPosition( this.geoSuccess,
this.geoFailure,
geoOptions);
}
geoSuccess = (position) => {
console.log(position.coords.latitude);
this.setState({
ready:true,
where: {lat: position.coords.latitude,lng:position.coords.longitude }
})
}
geoFailure = (err) => {
this.setState({error: err.message});
}
render() {
return (
<View style={styles.container}>
{ !this.state.ready && (
<Text style={styles.big}>Using Geolocation in React Native.</Text>
)}
{ this.state.error && (
<Text style={styles.big}>Error: {this.state.error}</Text>
)}
{ this.state.ready && (
<Text style={styles.big}>
Latitude: {this.state.where.lat}
Longitude: {this.state.where.lng}
</Text>
)}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
},
big: {
fontSize: 25
}
});
Output:
3. Liên kết và sử dụng các thư viện bên thứ ba
Thư viện của bên thứ ba cung cấp tính năng cho ứng dụng gốc mà không có trong React Native. Nếu tham khảo trong tài liệu của React Native chúng ta sẽ thấy có rất nhiều chức năng bị thiếu (chẳng hạn như maps).
Do vậy, chúng ta cần phải thêm các thư viện của bên thứ ba vào dự án. Trong phần này, chúng ta sẽ học cách thêm các thư viện từ bên thứ ba vào ứng dụng (thêm các biểu tượng của bên thư ba). Có sẵn rất nhiều bộ các gói biểu tượng. Dưới đây chúng ta có thể kể đến một số:
-
AntDesign
-
Entypo
-
EvilIcons
-
Feather
-
FontAwesome
-
FontAwesome 5
-
Foundation
-
Ionicons
-
MaterialIcons
-
MaterialCommunityIcons
-
Octicons
-
Zocial
-
SimpleLineIcons
Cài đặt các thư viện
Có rất nhiều phương pháp và lệnh để cài đặt các thư viện tùy thuộc vào OS phát triển và OS đích. Chúng ta sẽ cài đặt các thư viện Ionicons. Để cài đặt trên Windows, chúng ta chạy lệnh: $ npm install react-native-vector-icons --save.
Tạo một dự án và chạy 'npm install --save react-native-vector-icons'
với đường dẫn D:\ReactNative\navigationApp>npm install --save react-native-vector-icons
Liên kết các thư viện trên Android
Mở tệp android/settings.gradle và thêm vào các dòng code dưới đây. Ở đây, chúng ta chỉ thêm vào thư viện Ionicons. Nếu bạn muốn thêm các thư viện khác, chỉ cần thêm chúng vào thẻ include kèm theo đường dẫn và thư viện trong thư mục android ở project như dưới đây.
-
include ':react-native-vector-icons'
-
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
Bây giờ, hãy thêm phần phụ thuộc sau vào android / app / build.gradle:
-
implementation project(':react-native-vector-icons')
Trước đó, cho đến năm 2018, thuật ngữ biên dịch được sử dụng thay thế cho việc triển khai.
Trong, android/app/src/main/java/com/{project_directory}/MainApplication.java
import com.oblador.vectoricons.VectorIconsPackage;
...
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new VectorIconsPackage()
);
}
Để thêm nhiều thư viện hơn, chỉ cần phân tách chúng bằng dấu phẩy và thêm gói thư viện. Các thủ tục trên là phổ biến để thêm thư viện gốc trong Android.
Bây giờ, trong 'android / app / build.gradle', hãy thêm phần phụ thuộc sau:
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
project.ext.vectoricons = [
iconFontNames: ['Ionicons.ttf'] // Name of the font files you want to copy
]
Ví dụ về liên kết thư viện bên thứ ba trong React Native
Trong ví dụ này, chúng ta sẽ thêm trash icon của thư viện Ionicons. Mở ứng dụng của bạn và import biểu tượng từ package 'react-native-vector-icons/Ionicons'
. Tìm biểu tượng bạn muốn thêm tại trang ionicons.com (ở đây sẽ là ios-trash).
Trong npm doc, Bạn sẽ tìm thấy thành phần Icon và các property của nó.
App.js
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, TouchableOpacity,Alert} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
type Props = {};
export default class App extends Component<Props> {
deleteItem = ()=>{
Alert.alert("delete icon pressed")
}
render() {
return (
<View style={styles.container}>
<Text style={styles.textStyle}>Adding Ionicons library</Text>
<TouchableOpacity style={styles.touchableStyle} onPress= {this.deleteItem} >
<Icon size={30} name="ios-trash" color="red"/>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
textStyle:{
fontSize:25,
marginTop: 30,
textAlign: 'center',
},
touchableStyle:{
marginTop: 80,
justifyContent: 'center',
alignItems: "flex-end",
marginRight: 50,
}
});
Output:
Phần 3: Điều hướng
1. React Native Navigation
React Native Navigation được sử dụng để quản lý việc trình bày, và chuyển đổi giữa các trang. Có 2 kiểu điều hướng trong các ứng dụng di động. Đó là kiểu điều hướng stack và điều hướng tabbed.
Cài đặt React Navigation
React Navigation được tạo ra bởi cộng đồng React Native để cung cấp giải pháp điều hướng bằng JavaScript.
Tạo một dự án React Native và cài đặt các package và phần phụ thuộc cần thiết.
Cài đặt package react-navigation trong dự án React Native bằng một trong các lệnh sau:
-
yarn add react-navigation
-
# or with npm
-
# npm install --save react-navigation
Sau khi đã thực thi thành công các lệnh trên, nó sẽ thêm "react-navigation": "^3.3.0"
(3.3.0 là số phiên bản) trong tệp package.json.
Sau đó, cài đặt package react-native-gesture-handler:
-
yarn add react-native-gesture-handler
-
# or with npm
-
# npm install --save react-native-gesture-handler
Bây giờ, liên kết tất cả các phần phụ thuộc gốc với nhau sử dụng lệnh sau:
-
react-native link react-native-gesture-handler
Để hoàn thành cài đặt 'react-native-gesture-handler'
cho Android, chỉnh sửa như dưới đây trong MainActivity.java:
projectDirectory/android/app/src/main/java/com/project/MainActivity.java
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
. . .
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
Tạo một stack navigator
Để tạo một điều hướng stack, chúng ta import các hàm createStackNavigator và createAppContainer của thư viện react-navigation .
App.js
import React from "react";
import {Button, View, Text } from "react-native";
import { createStackNavigator, createAppContainer } from "react-navigation";
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
}
}
const AppNavigator = createStackNavigator({
Home: {
screen: HomeScreen
}
});
export default createAppContainer(AppNavigator);
createStackNavigator là một hàm mà lấy một đối tượng điều chỉnh tuyến (route) và một đối tượng các tùy chọn. Nó trả về một thành phần.
MainActivity.java
package com.naviexe;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
public class MainActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "naviExe";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
}
Khi chúng ta chạy code như trên, chúng ta sẽ thấy một thanh điều hướng trống chứa thành phần HomeScreen.
Output:
Tùy chỉnh tuyến tốc ký
Chúng ta chỉ có một trang đơn là một tuyến duy nhất, đó là thành phần Home, chúng ta không cần phải dùng {screen: HomeScreen}
, có thể trực tiếp sử dụng thành phần home.
const AppNavigator = createStackNavigator({
Home: HomeScreen
});
Thêm tiêu đề và kiểu cho điều hướng
static navigationOptions = {
title: 'Home',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#0ff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
import React from 'react';
import { View, Text } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
headerStyle: {
backgroundColor: '#f4511e',
},
// headerTintColor: '#0ff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
}
const AppNavigator = createStackNavigator({
Home: HomeScreen
});
export default createAppContainer(AppNavigator);
Thêm một trang tuyến (route screen) thứ hai
Tạo một lớp khác (ProfileScreen) trong tệp App.js để thêm trang tuyến thứ hai vào stack navigator.
class ProfileScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Details Screen</Text>
</View>
);
}
}
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
Profile: ProfileScreen
},
{
initialRouteName: "Home"
}
);
Đối tượng tùy chọn initialRouteName xác định cụ thể tuyến ban đầu của điều hướng stack.
Code hoàn chỉnh:
App.js
import React from 'react';
import { View, Text } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
}
class ProfileScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Details Screen</Text>
</View>
);
}
}
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
Profile: ProfileScreen
},
{
initialRouteName: "Home"
}
);
export default createAppContainer(AppNavigator);
Output:
Trong phần tiếp theo, chúng ta sẽ học cách để đi từ tuyến Home đến tuyến Profile (từ trang này sang trang khác).
2.Tùy chỉnh thanh tiêu đề
Property tĩnh của một thành phần screen được gọi là navaigationOptions
. Nó có thể là một đối tượng hoặc một hàm. Nó trả về một đối tượng chứa một vài lựa chọn tùy chỉnh.
Các props của thanh tiêu đề
Props |
Mô tả |
title |
Đặt tiêu đề của trang hoạt động. |
headerStyle |
Thêm kiểu vào trang tiêu đề. |
backgroundColor |
Đặt màu nền của thanh tiêu đề. |
headerTintColor |
Đặt màu của dòng tiêu đề. |
headerTitleStyle |
Thêm kiểu cho dòng tiêu đề. |
fontWeight |
Đặt kiểu font cho dòng tiêu đề. |
static navigationOptions = {
title: 'HeaderTitle',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#0ff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
Chuyển từ trang này sang trang khác trong React Native Ví dụ 1
Trong ví dụ này, Chúng ta tạo 2 trang là 'Home'
và 'Profile'
. Trang Home được đặt là trang đầu tiên sử dụng "initialRouteName"
property và trang Profile là trang thứ hai.
App.js
import React from 'react';
import { View, Text, Button } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
headerStyle: {
backgroundColor: '#f4511e',
},
//headerTintColor: '#0ff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Profile"
onPress={() => this.props.navigation.push('Profile')}
/>
</View>
);
}
}
class ProfileScreen extends React.Component {
static navigationOptions = {
title: 'Profile',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#0ff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Profile Screen</Text>
<Button
title="Go to Profile... again"
onPress={() => this.props.navigation.push('Profile')}
/>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
}
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
Profile: ProfileScreen
},
{
initialRouteName: "Home"
}
);
const AppContainer = createAppContainer(AppNavigator);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
Output:
Sử dụng các param trong tiêu đề
Để sử dụng các params (tham số) như một dòng tiêu đề, chúng ta cần phải làm cho hàm navigationOptions trả về một đối tượng tùy chỉnh bằng cách sử dụng this.props trong navigationOptions. Bởi nó là property tĩnh của thành phần, "this"
ở đây không phải là một phiên bản của thành phần và do đó nó sẽ không có prop nào
Biến navigationOptions
thành một hàm trả về một đối tượng chứa {navigation, navigationOptions, screenProps}
. navigation là một đối tượng được truyền đến screen props đó là this.props.navigation. Chúng ta cúng có thể lấy các tham số từ điều hướng sử dụng navigation.getParam
hay navigation.state.params.
class ProfileScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('otherParam', 'A Param Header'),
};
};
}
Tùy chỉnh navigationOtions của trang hoạt động cũng có thể được cập nhật từ chính thành phần trang hiện tại.
//inside render
<Button
title="Update the title"
onPress={() => this.props.navigation.setParams({otherParam: 'Header Updated!'})}
/>
Code hoàn chỉnh
Trong ví dụ này, chúng ta tạo 2 trang "Home"
và "Profile"
. Trang Profile đặt dòng tiêu đề của nó bằng: title: navigation.getParam('otherParam', 'A Param Header')
App.js
import React from 'react';
import { View, Text, Button } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
headerStyle: {
backgroundColor: '#f4511e',
},
//headerTintColor: '#0ff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Profile"
onPress={() => this.props.navigation.push('Profile')}
/>
</View>
);
}
}
class ProfileScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('otherParam', 'A Param Header'),
};
};
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Profile Screen</Text>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
<Button
title="Update the title"
onPress={() => this.props.navigation.setParams({otherParam: 'Header Updated!'})}
/>
</View>
);
}
}
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
Profile: ProfileScreen
},
{
initialRouteName: "Home"
}
);
const AppContainer = createAppContainer(AppNavigator);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
3.Di chuyển giữa các trang
Trong phần này, chúng ta sẽ cùng thảo luận cách di chuyển từ một trang tuyến này sang một trang tuyến khác và quay lại tuyến đầu tiên. Trong phần trước của phần Điều hướng, chúng ta đã tạo stack navigator với 2 trang tuyến (route screen) là Home và Profile.
Chúng ta thực hiện chuyển từ trang này sang trang khác bằng navigation prop, mà sẽ truyền các thành phần screen của chúng ta. Điều này tương tự như viết các dòng code sau cho một trình duyệt web:
-
<a href="profiles.html">Go to Profile</a>
Cách khác để viết điều này sẽ là
<a href="profiles.html">Go to Profile</a>
The other way to write this would be:
<a onClick={() => { document.location.href = "profile.html"; }}>Go to Profile</a>
Điều hướng sang trang mới
Có thể điều hướng từ trang này sang trang khác bằng những cách khác nhau:
1. <Button
2. title="Go to URL"
3. onPress={() => this.props.navigation.navigate('url')}
4. />
App.js
import React from 'react';
import { View, Text, Button } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Profile"
onPress={() => this.props.navigation.navigate('Profile')}
/>
</View>
);
}
}
class ProfileScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Profile Screen</Text>
</View>
);
}
}
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
Profile: ProfileScreen
},
{
initialRouteName: "Home"
}
);
const AppContainer = createAppContainer(AppNavigator);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
Thêm một thành phần Button trong 'HomeScreen'
và thực hiện một hành động onPress{}
để gọi hàm this.props.navigation.navigate('Profile')
. Click vào thành phần Button sẽ di chuyển trang đến layout 'ProfileScreen'.
import React from 'react';
import { View, Text, Button } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Profile"
onPress={() => this.props.navigation.navigate('Profile')}
/>
</View>
);
}
}
class ProfileScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Profile Screen</Text>
</View>
);
}
}
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
Profile: ProfileScreen
},
{
initialRouteName: "Home"
}
);
const AppContainer = createAppContainer(AppNavigator);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
Output:
-
this.props.navigation: navigation prop được truyền với tất cả các thành phần screen trong điều hướng stack.
-
navigate('Profile'): Gọi hàm navigate với tên tuyến mà chúng ta muốn chuyển đến.
Điều hướng đến một trang tuyến nhiều lần
Thêm điều hướng 'ProfileScreen'
đến 'Profile'
URL sẽ không thay đổi gì bởi chúng ta đã ở tuyến Profile.
class ProfileScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Profile Screen</Text>
<Button
title="Go to Profile"
onPress={() => this.props.navigation.navigate('Profile')}
/>
</View>
);
}
}
Để gọi trang Profiles, chủ yếu là trong trường hợp truyền các dữ liệu độc nhất (các tham số) đến mỗi tuyến. Để thực hiện, chúng ta sẽ truyền điều hướng đến push. Phương thức Navigate push biểu thị ý định thêm một tuyến bất kể lịch sử điều hướng hiện tại.
<Button
title="Go to Profile"
onPress={() => this.props.navigation.push('Profile')}
/>
Khi nhấn nút chúng ta sẽ gọi phương thức push mỗi lần và thêm một tuyến mới vào stack điều hướng.
Quay lại
Tiêu đề của stack navigator tự động có một nút quay lại khi có thể quay lại từ trang hiện tại. Điều hướng stack của trang đơn sẽ không có nút quay lại bởi sẽ không có gì để chúng ta có thể quay lại
Đôi khi, chúng ta sẽ phải lập trình để thiếp lập hành vi quay lại, chúng ta sẽ gọi đây là hàm this.props.navigation.goBack();
.
App.js
import React from 'react';
import { View, Text, Button } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Profile"
onPress={() => this.props.navigation.push('Profile')}
/>
</View>
);
}
}
class ProfileScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Profile Screen</Text>
<Button
title="Go to Profile... again"
onPress={() => this.props.navigation.push('Profile')}
/>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
}
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
Profile: ProfileScreen
},
{
initialRouteName: "Home"
}
);
const AppContainer = createAppContainer(AppNavigator);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
Output:
4. Truyền giá trị giữa các trang
Khi tạo một ứng dụng nhiều trang thì đôi khi yêu cầu cần phải truyền giá trị giữa trang này và trang khác. Chúng ta có thể thực hiện điều này sử dụng hàm this.props.navigation.navigate()
.
Hàm này được sử dụng để điều hướng giữa các trang khác nhau.
Trước khi đi vào ví dụ, bạn cần phải đọc qua phần React Native Navigation.
Ví dụ
Trong ví dụ này, chúng ta sẽ nhập giá trị vào trang đầu tiên và đưa nó vào trang thứ hai.
Giá trị (tham số) được truyền như một đối tượng trong trang thứ nhất đến hàm navigation.navigate :
-
this.props.navigation.navigate('RouteName', { /* params go here */ })
Cùng một giá trị (tham số) được đọc trong trang thứ hai như sau:
-
this.props.navigation.getParam(paramName, defaultValue)
Tạo một tệp HomeScreen.js và thêm một thành phần TextInput để nhập giá trị và một Button để gửi. Thành phần TextInput có một onChangeText prop mà cần một hàm để gọi mỗi khi văn bản thay đổi.
HomeScreen.js
import React from 'react';
//import react in our code.
import { StyleSheet, View, Button, TextInput } from 'react-native';
export default class HomeScreen extends React.Component {
constructor(props) {
//constructor to set default state
super(props);
this.state = {
username: '',
};
}
static navigationOptions = {
title: 'Home',
headerStyle: {
backgroundColor: '#f4511e',
},
//headerTintColor: '#0ff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
render() {
const { navigate } = this.props.navigation;
return (
//View to hold our multiple components
<View style={styles.container}>
{/*Input to get the value from the user*/}
<TextInput
value={this.state.username}
onChangeText={username => this.setState({ username })}
placeholder={'Enter Any value'}
style={styles.textInput}
/>
<View style={styles.buttonStyle}>
<Button
title="Submit"
// color="#00B0FF"
onPress={() =>
this.props.navigation.navigate('Profile', {
userName: this.state.username,
otherParam: '101',
})
}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
padding: 16,
},
textInput: {
height: 45,width: "95%",borderColor: "gray",borderWidth: 1,fontSize:20,
},
buttonStyle:{
width: "93%",
marginTop: 50,
backgroundColor: "red",
}
});
Trong code trên userName: this.state.username
, trữ giá trị nhập vào thành phần TextInput và otherParam: '101'
trực tiếp chỉ định một giá trị. Khi click vào nút, userName và otherParam được truyền đến trang Profile.
ProfileScreen.js
Trong trang này, chúng ta nhân giá trị của userName và otherParam sử dụng navigation.getParam('paramValue', default value)
và lần lượt lưu trữ vào đối tượng user_name
và other_param
. Giá trị của đối tượng JavaScript được chuyển đổi sang chuỗi sử dụng hàm JSON.stringify(object)
.
import React from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
export default class ProfileScreen extends React.Component {
static navigationOptions = {
title: 'Profile',
headerStyle: {
backgroundColor: '#f4511e',
},
//headerTintColor: '#0ff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
render() {
{/*Using the navigation prop we can get the
value passed from the previous screen*/}
const { navigation } = this.props;
const user_name = navigation.getParam('userName', 'NO-User');
const other_param = navigation.getParam('otherParam', 'some default value');
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text style={{ marginTop: 16,fontSize: 20,}}>
This is Profile Screen and we receive value from Home Screen
</Text>
<Text style={styles.textStyle}>User Name: {JSON.stringify(user_name)}</Text>
<Text style={styles.textStyle}>Other Param: {JSON.stringify(other_param)}</Text>
<View style={styles.buttonStyle}>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
textStyle: {
fontSize: 23,
textAlign: 'center',
color: '#f00',
},
buttonStyle:{
width: "93%",
marginTop: 50,
backgroundColor: "red",
}
});
App.js
Tạo tệp App.js là điểm bắt đầu của ứng dụng và import HomeScreen và ProfileScreen. HomeScreen được đặt là trang đầu tiên sử dụng initialRouteName.
1. import React from 'react';
2. import {createStackNavigator,createAppContainer} from 'react-navigation';
3. import HomeScreen from './HomeScreen';
4. import ProfileScreen from './ProfileScreen';
5.
6. const AppNavigator = createStackNavigator(
7. {
8. Home: HomeScreen,
9. Profile: ProfileScreen
10. },
11. {
12. initialRouteName: "Home"
13. }
14. );
15. export default createAppContainer(AppNavigator);
Output:
Chúng ta cũng gửi và nhận các tham số thành JSON chẳng hạn như:
HomeScreen.js
onPress={() =>
navigate('Profile', {
JSON_ListView_Clicked_Item: this.state.username,
})
}
ProfileScreen.js
Trong này đọc giá trị theo 2 cách mà không kiểm tra.
-
{this.props.navigation.state.params.JSON_ListView_Clicked_Item}
Hoặc kiểm tra giá trị nhập vào có phải là rỗng (null) hay không
{this.props.navigation.state.params.JSON_ListView_Clicked_Item
? this.props.navigation.state.params.JSON_ListView_Clicked_Item
: 'No Value Passed'}
<Text style={styles.textStyle}>
{this.props.navigation.state.params.JSON_ListView_Clicked_Item}
</Text>
<Text style={{ marginTop: 16,fontSize: 20, }}>With Check</Text>
{/*If you want to check the value is passed or not,
you can use conditional operator.*/}
<Text style={styles.textStyle}>
{this.props.navigation.state.params.JSON_ListView_Clicked_Item
? this.props.navigation.state.params.JSON_ListView_Clicked_Item
: 'No Value Passed'}
Output:
5. Điều hướng Tab
Điều hướng Tab là kiểu điều hướng phổ biến nhất trong các ứng dụng di động. Điều hướng Tab được gắn ở cuối trang hoặc ở đầu trang bên dưới phần tiêu đề hoặc đôi khi chính là phần tiêu đề. Nó được sử dụng để chuyển qua lại giữa các trang tuyến.
Để tạo điều hướng Tab, trước tiên chúng ta import createBottomTabNavigator
và createAppContainer
và trong các hàm gốc của thư viện react-navigation
.
Tùy chỉnh Bottom Tab Navigator
Có nhiều prop có thể tùy chỉnh được của BottomTabNavigator. Một trong số đó có thể kể đến:
Prop |
Mô tả |
initialRouteName |
Định nghĩa tuyến tab đầu tiên khi ứng dụng khởi động. |
order |
Là một mảng của trang tuyến, dùng để sắp xếp thứ tự của các tab. |
paths |
Cung cấp sơ đồ của các trang tuyến đến path config mà sẽ ghi đè lên các đường dẫn được đặt trong routeConfigs. |
lazy |
Đặt là {true} thì sẽ render tab khi tab hoạt động lần đầu. Nếu đặt là false, tất cả các tab đều được render ngay lập tức. Giá trị mặc định là true. |
tabBarComponent |
Nó đè lên các thành phần, được sử dụng làm thanh tab. Không bắt buộc phải sử dụng. |
tabBarOptions |
Là một đối tượng của các property sau: activeTintColor, activeBackgroundColor, inactiveTintColor , inactiveBackgroundColor, showLabel, showIcon, style, labelStyle, tabStyle, allowFontScaling. |
Ví dụ về điều hướng Tab
Tạo 2 lớp tên là HomeScreen và ProfileScreen. Đăng kí các lớp này trong hàm createBottomTabNavigator function
lần lượt với Home và Profile tab.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Home Screen</Text>
</View>
);
}
}
class ProfileScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Profile Screen</Text>
</View>
);
}
}
const TabNavigator = createBottomTabNavigator({
Home: HomeScreen,
Profile: ProfileScreen,
});
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
});
export default createAppContainer(TabNavigator);
Output:
Nếu chúng ta đặt initialRouteName: "Profile"
thì nó sẽ tải "ProfileScreen"
là tuyến tab ban đầu.
const TabNavigator = createBottomTabNavigator({
Home: HomeScreen,
Profile: ProfileScreen,
},
{
initialRouteName: "Profile"
}
);
5. Thêm biểu tượng vào bên dưới điều hướng Tab
Trong phần này, chúng ta sẽ thêm các biểu tượng vào bên dưới điều hướng Tab. Trước khi đi vào phần này, hãy đọc lại phần Điều hướng Tab để biết cách cài đặt Điều hướng Tab cuối trang.
Ví dụ
Đầu tiên, thêm các thư viện và phần phụ thuộc cần thiết vào dự án React Native:
1. Thêm thư viện react navigation với lệnh sau:
-
yarn add react-navigation
2. Thêm thư viện react native gesture handler với lệnh sau:
-
yarn add react-native-gesture-handler
3. Thêm thư viện react native vector icons với lệnh sau:
-
yarn add react-native-vector-icons
Sau khi đã thực thi thành công các lệnh trên, liên kết các thư viện này đến dự án react native với lệnh sau:
-
react-native link
Lệnh trên hãy thêm các phần phụ thuộc dưới đây vào tệp D:\your_directory\your_reactNativeProject\package.json file.
-
"react-native-gesture-handler": "^1.1.0",
-
"react-native-vector-icons": "^6.3.0",
-
"react-navigation": "^3.3.2"
D:\your_directory\your_reactNativeProject\android\app\build.gragle
-
implementation project(':react-native-vector-icons')
-
implementation project(':react-native-gesture-handler')
D:\your_directory\your_reactNativeProject\android\settings.gradle file:
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '..\node_modules\react-native-vector-icons\android')
include ':react-native-gesture-handler'
project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '..\node_modules\react-native-gesture-handler\android')
Thực hiện một chút thay đổi (thay thế '\' bằng '/') trong cấu trúc tuyến đường ở trên như:
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
include ':react-native-gesture-handler'
project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android')
D:\your_directory\your_reactNativeProject\android\app\src\main\java\com\ reactNativeProject\MainApplication.java
import com.oblador.vectoricons.VectorIconsPackage;
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
. . .
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new VectorIconsPackage(),
new RNGestureHandlerPackage()
);
}
App.js
Tạo 2 lớp "HomeScreen"
và "ProfileScreen"
lần lượt cho 2 tab "Home"
và "Profile"
. Hàm createBottomTabNavigator
tạo một thanh tab bên dưới trang để bạn có thể chuyển qua lại giữa các tuyến khác nhau.
Đặt "HomeScreen"
vào tiêu đề "Home"
và "ProfileScreen"
vào tiêu đề "Profile"
. Thẻ Icon thêm các biểu tượng vào điều hướng tab. Chúng ta có thể sử dụng các tên biểu tượng khác nhau trên ionicons.com
import React from 'react';
import {StyleSheet, Text, View} from 'react-native';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
import Icon from 'react-native-vector-icons/Ionicons';
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Home Screen</Text>
</View>
);
}
}
class ProfileScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Profile Screen</Text>
</View>
);
}
}
const TabNavigator = createBottomTabNavigator(
{
Home:{
screen:HomeScreen,
navigationOptions:{
tabBarLabel:'Home',
tabBarIcon:({tintColor})=>(
<Icon name="ios-home" color={tintColor} size={25}/>
)
}
},
Profile: {
screen:ProfileScreen,
navigationOptions:{
tabBarLabel:'Profile',
tabBarIcon:({tintColor})=>(
<Icon name="ios-person" color={tintColor} size={25}/>
)
}
},
},
{
initialRouteName: "Home"
},
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
});
export default createAppContainer(TabNavigator);
Output:
6.Tạo Material Bottom Tab Navigator
Kiểu vật liệu (material style) cung cấp thêm hiệu ứng thiết kế cho thanh tab ở phía dưới màn hình. Các thiết kế sẽ khiến bạn chú ý đến các tab phía bên dưới hơn. Các thành phần của trang tab sẽ không được đặt lên cho đến khi các trang được tập trung vào lần đầu.
Để sử dụng material design navigator, cài đặt thư viện react-navigation-material-bottom-tabs
như sau:
-
npm install react-navigation-material-bottom-tabs react-native-paper
Thư viện này sử dụng thành phần BottomNavigation từ react-native-paper.
Nó cũng yêu cầu cần phải cài react-native-vector-icons.
-
createMaterialBottomTabNavigator(RouteConfigs, MaterialBottomTabNavigatorConfig);
Ví dụ
Trong ví dụ này, chúng ta sẽ cài đặt material bottom tab navigator để làm nổi bật biểu tượng của tab đang hoạt động và tiêu đề của nó. Các tab còn lại sẽ chỉ hiển thị biểu tượng mà không có tiêu đề. Để sử dụng các các thiết kế vật liệu, import hàm createMaterialBottomTabNavigator
từ thư viện react-navigation-material-bottom-tabs
.
App.js
import React from 'react';
import {StyleSheet, Text, View,Button} from 'react-native';
import { createBottomTabNavigator, createAppContainer} from 'react-navigation';
import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Home Screen</Text>
</View>
);
}
}
class ProfileScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Profile Screen</Text>
</View>
);
}
}
class ImageScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Image Screen</Text>
</View>
);
}
}
class CartScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Cart Screen</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
});
const TabNavigator = createMaterialBottomTabNavigator(
{
Home: { screen: HomeScreen,
navigationOptions:{
tabBarLabel:'Home',
tabBarIcon: ({ tintColor }) => (
<View>
<Icon style={[{color: tintColor}]} size={25} name={'ios-home'}/>
</View>),
}
},
Profile: { screen: ProfileScreen,
navigationOptions:{
tabBarLabel:'Profile',
tabBarIcon: ({ tintColor }) => (
<View>
<Icon style={[{color: tintColor}]} size={25} name={'ios-person'}/>
</View>),
activeColor: '#f60c0d',
inactiveColor: '#f65a22',
barStyle: { backgroundColor: '#f69b31' },
}
},
Image: { screen: ImageScreen,
navigationOptions:{
tabBarLabel:'History',
tabBarIcon: ({ tintColor }) => (
<View>
<Icon style={[{color: tintColor}]} size={25} name={'ios-images'}/>
</View>),
activeColor: '#615af6',
inactiveColor: '#46f6d7',
barStyle: { backgroundColor: '#67baf6' },
}
},
Cart: {
screen: CartScreen,
navigationOptions:{
tabBarLabel:'Cart',
tabBarIcon: ({ tintColor }) => (
<View>
<Icon style={[{color: tintColor}]} size={25} name={'ios-cart'}/>
</View>),
}
},
},
{
initialRouteName: "Home",
activeColor: '#f0edf6',
inactiveColor: '#226557',
barStyle: { backgroundColor: '#3BAD87' },
},
);
export default createAppContainer(TabNavigator);
Output:
7.React Native Top Tab Navigator (createMaterialTopTabNavigator)
Kiểu vật liệu createMaterialTopTabNavigator
dược dùng để tạo tab navigator ở trên đầu trang. Nó cung cấp chức năng tạo và hiển thị nhiều bộ định tuyến trang. Các trang này đươc chuyển qua lại lẫn nhau bằng cách gõ nhẹ vào tuyến hoặc vuốt theo chiều ngang. Các thành phần tab screen sẽ được đặt lên khi chúng được tập trung vào.
Hàm createMaterialTopTabNavigator
của thư viện react-navigation giúp chúng ta sễ dàng cài đặt top tab navigator:
-
createMaterialTopTabNavigator(RouteConfigs, TabNavigatorConfig);
Ví dụ
Hãy tạo một top tab navigator với thanh trạng thái và phần tiêu đề tùy chọn. Trong ví dụ này, Chúng ta sẽ tạo 3 trang khác nhau cho các bộ định tuyến "Home", "Profile"
và "Settings"
. Mỗi trang định tuyến sẽ được tạo trong các tệp riêng.
Cấu trúc thư mục của ứng dụng
Tạo một thư mục src trong dự án tuyến của bạn. Bên trong thư mục src tạo một tệp index.js và 2 thư mục khác là lib và screens. Trong thư mục screens, chúng ra sẽ đặt 3 tệp của trang đó là index.js (HomeScreen), profile.js (ProfileScreen), và settings.js (SettingsScreen). Trong thư mục lib, chúng ta cài đặt createMaterialTopTabNavigator
để tạo top tab navigator.
topNavigation/index.js
Thay đổi một chút trong tệp topNavigation/index.js
(thay './App'
bằng './src'
).
import {AppRegistry} from 'react-native';
import App from './src';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
Tạo 3 lớp và import Icon từ package 'react-native-vector-icons/Ionicons'
. Cài đặt tabBarIcon và thêm thẻ Icon vào nó.
src/screens/index.js
import React, {Component} from 'react';
import {View,Text} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
export default class HomeScreen extends Component{
render() {
return(
<View>
<Text>This is Home Screen</Text>
</View>
)
}
}
HomeScreen.navigationOptions={
tabBarIcon:({tintColor, focused})=>(
<Icon
name={focused ? 'ios-home' : 'md-home'}
color={tintColor}
size={25}
/>
)
}
src/screens/profile.js
import React, {Component} from 'react';
import {View,Text} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
export default class ProfileScreen extends Component{
render(){
return(
<View>
<Text>this is profile screen</Text>
</View>
)
}
}
ProfileScreen.navigationOptions={
tabBarIcon:({tintColor, focused})=>(
<Icon
name={focused ? 'ios-person' : 'md-person'}
color={tintColor}
size={25}
/>
)
}
src/screens/settings.js
import React, {Component} from 'react';
import {View,Text} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
export default class SettingScreen extends Component{
render(){
return(
<View>
<Text>this is setting screen</Text>
</View>
)
}
}
SettingScreen.navigationOptions={
tabBarIcon:({tintColor, focused})=>(
<Icon
name={focused ? 'ios-settings' : 'md-settings'}
color={tintColor}
size={25}
/>
)
}
src/lib/router.js
Trong tệp router.js, import các hàm createMaterialTopTabNavigator
và createAppContainer
của thư viện 'react-navigation'. Import tất cả các lớp định tuyến trong nó và đặt chúng theo trình tự mà chúng ta muốn hiển thị trên đầu tab navigator.
-
activeTintColor: đặt màu đề cập cho bộ định tuyến đang hoạt động.
-
showIcon: hiển thị
{true}
và ẩn {false}
biểu tượng bộ định tuyến.
-
showLabel: hiển thị
{true}
và ẩn {false}
tiêu đề của bộ định tuyến. Theo mặc định, nó là true.
import React from 'react';
import {createMaterialTopTabNavigator,createAppContainer} from 'react-navigation';
import HomeScreen from "../screens/index";
import ProfileScreen from "../screens/profile";
import SettingScreen from "../screens/settings";
const AppNavigator = createMaterialTopTabNavigator(
{
Home: HomeScreen,
Profile: ProfileScreen,
Settings: SettingScreen,
},
{
tabBarOptions: {
activeTintColor: 'white',
showIcon: true,
showLabel:false,
style: {
backgroundColor:'red'
}
},
}
)
export default createAppContainer(AppNavigator);
src/index.js
Import AppNavigator từ './lib/router'
và chỉ định AppNavigator vào một hằng số AppIndex trong tệp này. Tùy biến thanh trạng thái sử dụng thẻ StatusBar và thêm phần tiêu đề vào trên đầu của tab navigator.
import React, {Component} from 'react';
import {StyleSheet, Text, View,StatusBar} from 'react-native';
import {createAppContainer} from 'react-navigation';
import Icon from 'react-native-vector-icons/Ionicons';
import AppNavigator from './lib/router';
const AppIndex = createAppContainer(AppNavigator)
export default class App extends Component{
render(){
return(
<View style={{flex:1}} >
<StatusBar
backgroundColor='red'
barStyle='light-content'
/>
<View style={styles.header}>
<Icon name='ios-camera' size={28} color='white'/>
<Icon name='ios-menu' size={28} color='white'/>
</View>
<AppIndex/>
</View>
)
}
}
const styles = StyleSheet.create({
wrapper: {
flex: 1,
},
header:{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
backgroundColor: 'red',
paddingHorizontal: 18,
paddingTop: 5,
}
});
Output:
8.Điều hướng Ngăn kéo (createDrawerNavigator)
React Native Drawer Navigation là một bảng UI hiển thị menu điều hướng của ứng dụng. Khi không sử dụng thì nó mặc định sẽ được ẩn đi, nó sẽ hiện ra khi người dùng vuốt ngón tay từ cạnh trang hay khi người dùng chạm vào biểu tượng ngăn kéo trên thanh ứng dụng.
React Native Drawer Navigation import createDrawerNavigator từ thư viện react-navigation:
-
import { createDrawerNavigator } from 'react-navigation'
Cài đặt createDrawerNavigator()
để thêm danh sách các lớp (trang):
-
createDrawerNavigator(RouteConfigs, DrawerNavigatorConfig);
Để đóng và mở các ngăn kéo, sử dụng các phương thức helper:
-
this.props.navigation.openDrawer();
-
this.props.navigation.closeDrawer();
Nếu bạn muốn bật/tắt ngăn kéo thì có thể gọi phương thức sau:
-
this.props.navigation.toggleDrawer();
Mỗi một phương thức openDrawer(), closeDrawer(),
và toggleDrawer()
đơn giản là các hành động truyền đi như:
-
this.props.navigation.dispatch(DrawerActions.openDrawer());
-
this.props.navigation.dispatch(DrawerActions.closeDrawer());
-
this.props.navigation.dispatch(DrawerActions.toggleDrawer());
Ví dụ
Tạo 2 lớp riêng biệt "DashboardScreen"
và "WelcomeScreen"
trong ứng dụng react native để hiển thị trên trang. Thêm các trang này vào createStackNavigator và thêm biểu tượng "md-menu"
của package 'react-native-vector-icons/Ionicons'
. Khi nhấn vào biểu tượng menu, gọi phương thức navigation.openDrawer()
để mở ngăn kéo.
Bây giờ, hãy import createDrawerNavigator từ package 'react-navigation'
và cài đặt createDrawerNavigator()
. Sau đó hãy thêm trang điều hướng stack lên trên nó.
import React, { Component } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import {
createSwitchNavigator,
createAppContainer,
createDrawerNavigator,
createStackNavigator
} from 'react-navigation';
export default class App extends Component {
render() {
return <AppContainer />;
}
}
class WelcomeScreen extends Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>WelcomeScreen</Text>
<Button
title="Go to DashboardScreen"
onPress={() => this.props.navigation.navigate('Dashboard')}
/>
</View>
);
}
}
class DashboardScreen extends Component {
static navigationOptions = {
title: 'Dashboard',
};
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>DashboardScreen</Text>
</View>
);
}
}
const DashboardStackNavigator = createStackNavigator(
{
DashboardNavigator: DashboardScreen
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
)
};
}
}
);
const WelcomeStackNavigator = createStackNavigator(
{
WelcomeNavigator: WelcomeScreen
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
)
};
}
}
);
const AppDrawerNavigator = createDrawerNavigator({
Dashboard: {
screen: DashboardStackNavigator
},
Welcome: {
screen: WelcomeStackNavigator
},
});
const AppSwitchNavigator = createSwitchNavigator({
Dashboard: { screen: AppDrawerNavigator },
Welcome: { screen: WelcomeScreen },
});
const AppContainer = createAppContainer(AppSwitchNavigator);
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
});
Output:
Phần 4 : Storage
1. React Native AsyncStorage
React Native AsyncStorage là một hệ thống lưu trữ đơn giản, không mã hóa, không đối xứng và liên tục, để lưu trữ dữ liệu trên toàn ứng dụng Nó lưu trữ dữ liệu dưới dạng cặp khóa-giá trị.
React Native khuyến khích sử dụng các trừu tượng ngoài AsyncStorage thay vì trực tiếp dùng AsyncStorage bởi nó hoạt động trên toàn ứng dụng.
Trên iOS, AsyncStorage được chấp nhận bởi code gốc. Code gốc của iOS lưu trữ các giá trị nhỏ trong một từ điển được tuần tự hóa và các giá trị lớn trong các tệp riêng.
Trong Android, AsyncStorage sẽ sử dụng SQLite hoặc RocksDB nếu có sẵn.
Để sử dụng AsyncStorage, import thư viện AsyncStorage như sau:
-
import {AsyncStorage} from 'react-native';
Duy trì dữ liệu (persist data)
React Native AsyncStorage lưu trữ dữ liệu sử dụng phương thức setItem() như sau:
-
AsyncStorage.setItem('key', 'value');
Ví dụ duy trì một giá trị đơn:
let name = "Michal";
AsyncStorage.setItem('user',name);
Ví dụ duy trì nhiều giá trị trong một đối tượng:
let obj = {
name: 'Michal',
email: 'michal@gmail.com',
city: 'New York',
}
AsyncStorage.setItem('user',JSON.stringify(obj));
Lấy dữ liệu:
React Native AsyncStorage lấy các dữ liệu được lưu sử dụng phương thức getItem() như sau:
-
await AsyncStorage.getItem('key');
Ví dụ lấy một giá trị đơn:
-
await AsyncStorage.getItem('user');
Ví dụ lấy nhiều giá trị từ một đối tượng:
-
let user = await AsyncStorage.getItem('user');
-
let parsed = JSON.parse(user);
-
alert(parsed.email);
React Native AsyncStorage Ví dụ 1
Trong ví dụ này, chúng ta sẽ tạo 2 thành phần TouchableOpacity, một để lưu và một để lấy dữ liệu. trong thành phần TouchableOpacity đầu tiên, gọi phương thức savaData()
để lưu dữ liệu và từ thành phần TouchableOpacity thứ hai, gọi phương thức displayData()
để lấy dữ liệu.
import React, {Component} from 'react';
import {Platform, StyleSheet, Text,
View,TouchableOpacity, AsyncStorage,
} from 'react-native';
export default class App extends Component<Props> {
saveData(){
let name = "Michal";
AsyncStorage.setItem('user',name);
}
displayData = async ()=>{
try{
let user = await AsyncStorage.getItem('user');
alert(user);
}
catch(error){
alert(error)
}
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress ={this.saveData}>
<Text>Click to save data</Text>
</TouchableOpacity>
<TouchableOpacity onPress ={this.displayData}>
<Text>Click to display data</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});
Output:
React Native AsyncStorage Ví dụ 2
Trong ví dụ này, chúng ta sẽ lưu nhiều giá trị trong form nếu đối tượng JSON sử dụng JSON.stringify(). JSON.stringify()
lấy đối tượng JavaScript chuyển chúng thành chuỗi JSON. Mặt khác, phương thức JSON.parse()
được dùng để lấy dữ liệu AsyncStorage. Phương thức này lấy chuỗi JSON và chuyển nó thành một đối tượng JavaScript trước khi chúng được trả về.
import React, {Component} from 'react';
import {Platform, StyleSheet, Text,
View,TouchableOpacity, AsyncStorage,
} from 'react-native';
export default class App extends Component<Props> {
saveData(){
/*let user = "Michal";*/
let obj = {
name: 'Michal',
email: 'michal@gmail.com',
city: 'New York',
}
/*AsyncStorage.setItem('user',user);*/
AsyncStorage.setItem('user',JSON.stringify(obj));
}
displayData = async ()=>{
try{
let user = await AsyncStorage.getItem('user');
let parsed = JSON.parse(user);
alert(parsed.email);
}
catch(error){
alert(error)
}
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress ={this.saveData}>
<Text>Click to save data</Text>
</TouchableOpacity>
<TouchableOpacity onPress ={this.displayData}>
<Text>Click to display data</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});
Output:
2. Các phương thức AsyncStorage
Có rất nhiều các phương thức của lớp React Native AsyncStorage được mô tả như ở dưới đây:
Các phương thức
setItem()
-
static setItem(key: string, value: string, [callback]: ?(error: ?Error)=>void)
Phương thức setItem()
đặt giá trị của một key và gọi một callback khi biên dịch. Nó trả về một đối tượng Promise.
getItem()
-
static getItem(key: string, [callback]: ?(error: ?Error, result: ?string)) =>void)
Phương thức getItem()
lấy một item từ một key và gọi một callback khi hoàn thành. Nó trả về một đối tượng Promise.
removeItem()
-
static removeItem(key: string, [callback]: ?(error: ?Error) => void)
Phương thức removeItem()
loại bỏ một item cho một key và gọi một callback khi biên dịch. Nó trả về một đối tượng Promise.
mergeItem()
-
static mergeItem(key: string, value: string, [callback]: ?(error: ?Error) => void)
Phương thức mergeItem()
sáp nhập các giá trị của khóa với giá trị nhập và cho rằng cả 2 giá trị là JSON đã được chuỗi hóa. Nó trả về một đối tượng Promise.
Chú ý: Phương thức này không được hỗ trợ bởi tất cả các phiên bản native.
clear()
-
static clear([callback]: ?(error: ?Error) => void)
Phương thức clear()
xóa bỏ tất cả các AsynchStorage từ các máy khách, thư viện, v..v.. Bạn không nên gọi phương thức này, thay vào đó bạn có thể sử dụng removeItem hoặc multiRemove để xóa các khóa của ứng dụng. Nó trả về một đối tượng Promise.
getAllKeys()
-
static getAllKeys([callback]: ?(error: ?Error, keys: ?Array<string>) => void)
Nó lấy tất cả các khóa của ứng dụng, cho tất cả các caller, thư viện, ..v..v.. Nó trả về một đối tượng Promise.
flushGetRequests()
-
static flushGetRequests(): [object Object]
Nó flush bất kỳ yêu cầu đang chờ nào sử dụng một cuộc gọi hàng loạt để lấy dữ liệu.
multiGet()
-
static multiGet(keys: Array<string>, [callback]: ?(errors: ?Array<Error>, result: ?Array<Array<string>>) => void)
Phương thức này cho phép bạn lấy hàng loạt các item được đưa ra trong một mảng các input khóa. Phương thức callback sẽ được gọi với một mảng các cặp khóa-giá trị tương ứng được tìm thấy:
-
multiGet(['k1', 'k2'], cb) -> cb([['k1', 'val1'], ['k2', 'val2']])
Phương thức này trả về một đối tượng Promise.
multiSet()
-
static multiSet(keyValuePairs: Array<Array<string>>, [callback]: ?(errors: ?Array<Error>) => void)
Phương thức này được sử dụng như một quy trình xử lý hàng loạt để lưu trữ nhiều cặp khóa-giá trị. Sau khi xử lý xong bạn sẽ co một callback mà không có lỗi:
-
multiSet([['k1', 'val1'], ['k2', 'val2']], cb);
Phương thức này trả về một đối tượng Promise.
multiRemove()
-
static multiRemove(keys: Array<string>, [callback]: ?(errors: ?Array<Error>) => void)
Phương thức này gọi việc xóa hàng loạt tất cả các khóa trong mảng khóa. Nó trả về một đối tượng Promise.
multiMerge()
-
static multiMerge(keyValuePairs: Array<Array<string>>, [callback]: ?(errors: ?Array<Error>) => void)
Nó thực thi một quy trình hàng loạt để sáp nhập các giá trị đang có với một bộ khóa được cho. Nó cho rằng các giá trị là JSON được chuỗi hóa. Nó trả về một đối tượng Promise.
4.Các ứng dụng với React Native
Sau khi đã học các kiến thức về framework thì việc tiếp theo bạn cần làm là gì? Đó là vận dụng những gì đã học được vào các dự án thực tế. Điều này không những củng cố thêm kiến thức mà còn giúp bạn trau dồi thêm các kỹ năng, phương pháp và các quy trình làm việc để trang bị hành trang sẵn sàng bước chân vào thị trường việc làm của ngành lập trình. Sau đây là một số các ứng dụng di động với React Native để bạn có thể thử sức mình
Ứng dụng trò chuyện
Nếu nói về ý tưởng cho ứng dụng React Native, thì sẽ không thể không nhắc đến ứng dụng trò chuyện. Hẳn là những ứng dụng như Whatsapp, Facebook Messenger, và Telegram thì không cần phải giới thiệu thêm rồi.
Những tính năng phải có của một ứng dụng trò chuyện cần có một giao diện trò chyện thời gian thực với một UI dễ dàng, hấp dẫn và có tính tương tác để người dùng mới có thể nhanh chóng hiểu được và tham gia trò chuyện mà không gặp bất kỳ khó khăn gì. Bạn nên thêm các mã hoá end-to-end để đảm bảo ưu tiên quyền riêng tư cho cuộc trò chuyện cùng với các tính năng khác như cho phép người dùng chia sẻ hình ảnh, link, video với những người dùng khác trong cuộc trò chuyện.
Ứng dụng đọc sách
Ứng dụng đọc sách cũng là một trong những ứng dụng di động phổ biến hiện nay. E-book đã trở thành xu thế được một thời gian, nhưng sự có mặt của audiobook chính là thứ thu hút sự chú ý và là tính năng phải có trong ứng dụng của bạn. Với cuộc sống hàng ngày bận rộn và căng thẳng, audiobook đã trở thành một kiểu trị liệu thư giãn đang ngày càng trở nên phổ biến.
Một ứng dụng đọc sách được hỗ trợ bởi công nghệ React Native nên bao gồm các tính năng như thanh tìm kiếm, sử dụng bộ lọc để phân chia theo thể loại, các chi tiết về sách như tên tác giả, sơ lược nội dung, ..v..v.. và một vài tính năng nâng cao khác như đánh dấu sách, đánh giá của người đọc, chatroom để người đọc thảo luận và còn nhiều nữa. Các khả năng dường như là vô tận.
Ứng dụng tin tức với âm thanh
Sẽ tuyệt vời làm sao nếu bạn có thể nghe tin tức thay vì đọc chúng. Đây là một ý tưởng tương tự như audiobook, ứng dụng tin tức bằng âm thanh đang khá là phát triển và nếu được khai thác tốt sẽ đem lại những tác động ấn tượng và trải nghiệm tốt cho người dùng. Một ứng dụng tin tức đơn giản lấy dữ liệu từ các trang và render dữ liệu tin tức lấy được từ các trang và các cổng thông tin vào ứng dụng của bạn.
Bước đầu tiên đó là xây dựng giao diện người dùng, hoàn thiện các phần tử thiết kế cho ứng dụng, tích hợp dữ liệu như tin tức khi người dùng click vào thì sẽ được điều hướng đến một trang để tải trang tin đó. Nhưng với sự hỗ trợ của các phần mềm âm thanh mã nguồn mở thì đó sẽ là thứ hoàn thiện ứng dụng của bạn. Các tính năng bạn có thể cài đặt bao gồm nhận dạng giọng nói và chuyển thành văn bản, tích hợp RestAP, thanh tìm kiếm, lọc tin tức theo chủ đề và tiêu đề, các reader plugin, và chế độ tối để cải thiện trải nghiệm người dùng.
Ứng dụng chơi nhạc
Cuộc sống sẽ thật buốn tẻ nếu thiếu đi các giai điệu và âm nhạc. Ứng dụng chơi nhạc là một trong số những ứng dụng React Native mà có thể phát triển trong một khoảng thời gian ngắn. Podcast cũng đang cực kì thịnh hành và có nhu cầu ngày càng tăng. Đây cũng sẽ là một lựa chọn rất phù hợp để tích hợp vào ứng dụng của bạn.
Nhưng chỉ có một UI hào nhoáng là chưa đủ, một ứng dụng chơi nhạc phải có các tính năng mượt mà và dễ dàng điều hướng như đặc trưng của ứng dụng React native. Các chức năng mà chắc chắn bạn nên tích hợp đó là danh sách bài hát dựa trên album, thể loại, phim, nghệ sĩ. Phát bài hát trực tiếp cùng với các chức năng chơi nhạc, tạm dừng, chế độ lặp lại, chế độ xáo trộn, và chia sẻ bài hát trên các mạng xã hội.
Ứng dụng mua sắm
Không có khi nào nào tốt hơn lúc này đề xây dựng một ứng dụng mua sắm. Đại dịch COVID-19 đã làm tăng tốc độ chuyển đổi sang mua sắm online. Các nghiên cứu chỉ ra rằng doanh số bán hàng online sales tăng 39% trong Q1 2021, gần gấp 3 lần 14% của Q1 2020, lớn hơn cả Q3 2020 và Q4 2020.
Ứng dụng mua sắm online đã trở thành một tiện ích tối cao cho các khách hàng bởi nó đáp ứng được tất cả các nhu cầu của họ và đồng thời đảm bảo an toàn. Các tính năng chính cần được tích hợp đó là chuyển đổi một cách trôi chảy giữa các loại mặt hàng, một trang giỏ hàng với chức năng huỷ mua, các cổng thanh toán như Paypal, UPI, Razorpay,..v..v... cửa sổ trò chuyện hỗ trợ khách hàng, các chức năng huỷ đơn, trả hàng,..v..v..
5. Một số tài liệu học React Native
Sau đây là một số tài liệu tham khảo để hỗ trợ bạn trong quá trình học React Native:
1. Tài liệu chính thức của React Native
Nếu bạn hỏi một lập trình viên cách để học một cái gì đó thì câu trả lời thường sẽ là “hãy đọc tài liệu đi”. Mình cũng khuyến khích bạn nên làm vậy bởi cách tốt nhất để hiểu cách thức hoạt động của một thứ gì đó là học về các tính năng và logic của nó. Rất may mắn là tài liệu của React Native được viết một cách đơn giản và dễ hiểu và có các ngôn ngữ khác nhau cho bạn lựa chọn.
Bạn có thể truy cập link sau: https://reactnative.dev/docs/getting-started
2. Các khoá học online
Một lựa chọn hiển nhiên đó là bạn có thể học code với các khoá học online cấp tốc. Có rất nhiều khoá học liên quan React trên Udemy. Dưới đây mình đã chọn ra một số khoá học tiêu biểu mà bạn có thể tham khảo:
The Complete React Native and Hooks Course.
Khoá học này giúp bạn hiểu về các kiến thức cơ bản của React, các thuật ngữ, các concepts của Redux.Bạn cũng sẽ được học cách nhanh chóng xây dựng bản mẫu triển khai ứng dụng của bạn lên Apple và Google Play Stores.
Build Full-stack React Native Apps with Express.js Backend.
Đây là một trong nhữn g khoá học thực tiễn nhất bởi khi hoàn thành bạn sẽ có thể xây dựng được 4 ứng dụng sử dụng Redux, React Navigation, MongoDB, Node/Express. Khoá học này ở trình độ trung cấp nên không phù hợp lắm với người mới bắt đầu, tuy nhiên bạn sẽ học được nhiều điều thông qua thực hành nên hãy cứ thử xem sao!
React Native: Advanced Concepts. Khi bạn đã hoàn thành 2 khoá trên thì bạn có thể bắt đầu với các kiến thức nâng cao hơn. Trong khoá học này bạn sẽ học cách xây dựng ứng dụng React Native với Expo, tạo animation, sử dụng các chức năng nâng cao của framework, tận dụng tối đa khả năng của React Navigation, thêm logic vào backend Firebase của bạn với Google Cloud Functions, thu hút người dùng với Push Notifications và sử dụng Redux Persist.
3. Các cuốn sách
Một cuốn sách hay để bổ trợ cho các khoá học online đó là cuốn FullStack: React Native. Nó là một bản hướng dẫn hoàn thiện về React Native bao gồm tất cả các kiến thức từ các thành phần đến triển khai ứng dụng. Chắc chắn là nó sẽ giúp bạn hiểu rõ hơn về các kiến thức đã học trong các khoá online. Một gợi ý nữa cho bạn đó là cuốn Pete Hunt’s tutorial about ReactJS – Thinking in React. Nó sẽ giúp bạn hiểu rõ hơn về logic React và cơ chế của các thành phần.
Kết luận
Qua đây thì hẳn là các bạn cũng có được một cái nhìn tổng quan về React Native, về khái niệm, những kiến thức cơ bản-nâng cao và các ứng dụng của React Native. Đây không phải là một framework đơn giản nên cần phải có sự nỗ lực lớn từ chính bản thân bạn. Hãy tự tìm tòi, khám phá, tham gia các khoá học, tham khảo các cuốn sách hoặc các bài hướng dẫn trên Youtube và tự bắt tay vào xây dựng các ứng dụng của riêng bạn.
Chúc bạn may mắn trên con đường chinh phục React Native.
> Chờ chút: Nếu bạn đang tự học React Native và muốn đi làm nhanh về lĩnh vực này thì hãy tham gia ngay Khóa học Front end với React Native cùng chuyên gia doanh nghiệp. Đào tạo từ số 0 cho người mới bắt đầu. Hỗ trợ giới thiệu thực tập / Việc làm sau khóa học.
---
HỌC VIỆN ĐÀO TẠO CNTT NIIT - ICT HÀ NỘI
Học Lập trình chất lượng cao (Since 2002). Học thực tế + Tuyển dụng ngay!
Đc: Tầng 3, 25T2, N05, Nguyễn Thị Thập, Cầu Giấy, Hà Nội
SĐT: 02435574074 - 0383.180086
Email: hello@niithanoi.edu.vn
Fanpage: https://facebook.com/NIIT.ICT/
#niit #niithanoi #niiticthanoi #hoclaptrinh #khoahocreactnative #khoahoclaptrinh #hoclaptrinhjava #hoclaptrinhphp #java #php #python #react