Flutter: Viết ứng dụng Flutter đầu tiên của bạn, phần 1
Mẹo: Chương trình codelab này sẽ hướng dẫn bạn cách viết ứng dụng Flutter đầu tiên trên thiết bị di động. Bạn có thể thích thử viết ứng dụng Flutter đầu tiên của mình trên web. Lưu ý rằng nếu bạn đã bật web, ứng dụng đã hoàn chỉnh sẽ chỉ hoạt động trên tất cả các thiết bị này!
Đây là hướng dẫn để tạo ứng dụng Flutter đầu tiên của bạn. Nếu bạn đã quen thuộc với lập trình hướng đối tượng và các khái niệm lập trình cơ bản như biến, điều kiện và vòng lặp, bạn có thể hoàn thành hướng dẫn này. Bạn không cần có kinh nghiệm trước đó với Dart, thiết bị di động hoặc lập trình web.
Bộ mã này là phần 1 của bộ mã hai phần. Bạn có thể tìm thấy phần 2 trên Google Developers Codelabs (cũng như bản sao của codelab này, phần 1).
Những gì bạn sẽ xây dựng trong phần 1
Bạn sẽ triển khai một ứng dụng đơn giản tạo tên được đề xuất cho một công ty khởi nghiệp. Người dùng có thể chọn và bỏ chọn tên, lưu những tên tốt nhất. Đoạn mã tạo ra 10 tên cùng một lúc. Khi người dùng cuộn, nhiều tên hơn được tạo ra. Không có giới hạn về khoảng cách người dùng có thể cuộn.
Dưới đây là ảnh động hiển thị cách ứng dụng hoạt động khi hoàn thành phần 1:
Những gì bạn sẽ học trong phần 1
- Cách viết một ứng dụng Flutter trông tự nhiên trên iOS, Android và web
- Cấu trúc cơ bản của ứng dụng Flutter
- Tìm và sử dụng các gói để mở rộng chức năng
- Sử dụng tải lại nóng để có chu kỳ phát triển nhanh hơn
- Cách triển khai một widget trạng thái
- Cách tạo danh sách vô hạn, tải chậm
Trong phần 2 của ví dụ này, bạn sẽ thêm tính tương tác, sửa đổi chủ đề của ứng dụng và thêm khả năng điều hướng đến một màn hình mới (được gọi là một route trong Flutter).
Những gì bạn sẽ sử dụng
Bạn cần hai phần mềm để hoàn thành lab này: Flutter SDK và một trình soạn thảo. Đoạn mã này giả định là Android Studio, nhưng bạn có thể sử dụng trình soạn thảo ưa thích của mình.
Bạn có thể chạy đoạn mã này bằng cách sử dụng bất kỳ thiết bị nào sau đây:
- Một thiết bị vật lý (Android hoặc iOS) được kết nối với máy tính của bạn và đặt ở chế độ nhà phát triển
- Trình mô phỏng iOS (yêu cầu cài đặt công cụ Xcode)
- Trình giả lập Android (yêu cầu thiết lập trong Android Studio)
- Trình duyệt (cần có Chrome để gỡ lỗi)
Nếu bạn muốn biên dịch ứng dụng của mình để chạy trên web, bạn phải bật tính năng này (hiện đang trong giai đoạn thử nghiệm). Để bật hỗ trợ web, hãy sử dụng các hướng dẫn sau:
$ flutter channel beta
$ flutter upgrade
$ flutter config --enable-web
Bạn chỉ cần chạy lệnh cấu hình một lần. Sau khi bạn bật hỗ trợ web, mọi ứng dụng Flutter bạn tạo cũng biên dịch cho web. Trong IDE của bạn dưới thanh kéo xuống thiết bị hoặc tại dòng lệnh đang sử dụng flutter devices
, bây giờ bạn sẽ thấy Chrome và máy chủ Web được liệt kê. Thiết bị Chrome sẽ tự động khởi động Chrome. Máy chủ Web khởi động một máy chủ lưu trữ ứng dụng để bạn có thể tải nó từ bất kỳ trình duyệt nào. Sử dụng thiết bị Chrome trong quá trình phát triển để bạn có thể sử dụng DevTools và máy chủ web khi bạn muốn thử nghiệm trên các trình duyệt khác. Để biết thêm thông tin, hãy xem Xây dựng ứng dụng web với Flutter và Viết ứng dụng Flutter đầu tiên của bạn trên web.
Bước 1: Tạo ứng dụng Flutter dành cho người mới bắt đầu
Tạo một ứng dụng Flutter mẫu, đơn giản, bằng cách sử dụng các hướng dẫn trong Bắt đầu với ứng dụng Flutter đầu tiên của bạn. Đặt tên cho dự án là startup_namer (thay vì flay_app).
Mẹo: Nếu bạn không thấy "Dự án Flutter mới" là một tùy chọn trong IDE của mình, hãy đảm bảo rằng bạn đã cài đặt các plugin cho Flutter và Dart.
Bạn sẽ chủ yếu chỉnh sửa lib/main.dart, nơi mã Dart tồn tại.
-
Thay thế nội dung của
lib/main.dart
.
Xóa tất cả code khỏi lib/main.dart. Thay thế bằng mã sau, mã này hiển thị “Hello World” ở giữa màn hình.// Copyright 2018 The Flutter team. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: Scaffold( appBar: AppBar( title: Text('Welcome to Flutter'), ), body: Center( child: Text('Hello World'), ), ), ); } }
Mẹo: Khi dán mã vào ứng dụng của bạn, thụt lề có thể bị lệch. Bạn có thể sửa lỗi này bằng các công cụ Flutter sau:
- Android Studio và IntelliJ IDEA: Nhấp chuột phải vào mã và chọn Reformat Code with dartfmt.
- Mã VS: Nhấp chuột phải và chọn Format Document.
- Terminal: Chạy
flutter format <tên_file>
.
-
Chạy ứng dụng theo cách IDE của bạn mô tả. Bạn sẽ thấy đầu ra của Android, iOS hoặc web, tùy thuộc vào thiết bị của bạn.
Android
iOSMẹo: Lần đầu tiên bạn chạy trên một thiết bị thực, có thể mất một lúc để tải. Sau đó, bạn có thể sử dụng tải lại nóng để cập nhật nhanh chóng. Việc lưu cũng thực hiện tải lại nóng nếu ứng dụng đang chạy. Khi chạy ứng dụng trực tiếp từ bảng điều khiển bằng cách sử dụng
flutter run
, hãy enterr
để thực hiện tải lại nóng.
Quan sát
-
Ví dụ này tạo ứng dụng Material. Material là một ngôn ngữ thiết kế trực quan tiêu chuẩn trên thiết bị di động và web. Flutter cung cấp một bộ vật dụng Vật liệu phong phú. Bạn nên có một đầu vào
uses-material-design: true
trong phầnflutter
của tệppubspec.yaml
của bạn. Điều này sẽ cho phép bạn sử dụng nhiều tính năng hơn của Material, chẳng hạn như tập hợp các Biểu tượng được xác định trước của chúng. - Phương thức
main()
sử dụng ký pháp mũi tên (=>
). Sử dụng ký hiệu mũi tên cho các hàm hoặc phương thức một dòng. - Ứng dụng mở rộng
StatelessWidget
làm cho ứng dụng trở thành một tiện ích. Trong Flutter, hầu hết mọi thứ đều là một widget, bao gồm căn chỉnh, đệm và bố cục. - Widget
Scaffold
, từ thư viện Material, cung cấp một thanh ứng dụng mặc định, và một thuộc tính body chứa cây widget cho màn hình chủ. Cây con widget có thể khá phức tạp. - Công việc chính của widget là cung cấp phương thức
build()
mô tả cách hiển thị widget dưới dạng các widget cấp thấp hơn. - Phần thân của ví dụ này bao gồm một tiện ích con
Center
chứa một tiện ích conText
. Tiện ích Center sẽ căn chỉnh cây con tiện ích con của nó vào giữa màn hình.
Bước 2: Sử dụng gói bên ngoài
Trong bước này, bạn sẽ bắt đầu sử dụng một gói mã nguồn mở có tên english_words, chứa một vài nghìn từ tiếng Anh được sử dụng nhiều nhất cùng với một số chức năng tiện ích.
Bạn có thể tìm thấy gói english_words
này cũng như nhiều gói mã nguồn mở khác trên pub.dev.
-
Tập tin
pubspec.yaml
quản lý các asset và các dependency cho một ứng dụng Flutter. Trongpubspec.yaml
, thêmenglish_words
(3.1.5 hoặc cao hơn) vào danh sách phụ thuộc:
{step1_base → step2_use_package}/pubspec.yaml -
Trong khi xem tệp
pubspec.yaml
trong chế độ xem trình chỉnh sửa của Android Studio, hãy nhấp vào Pub get. Điều này kéo gói vào dự án của bạn. Bạn sẽ thấy những điều sau trong bảng điều khiển:$ flutter pub get Running "flutter pub get" in startup_namer... Process finished with exit code 0
Việc thực hiện
Pub get
cũng tự động tạo tệppubspec.lock
với danh sách tất cả các gói được kéo vào dự án và số phiên bản của chúng. -
Trong
lib/main.dart
, nhập gói mới:lib/main.dartimport 'package: Flagship / material.dart' ; nhập 'gói: english_words / english_words.dart';
Khi bạn nhập, Android Studio cung cấp cho bạn đề xuất về các thư viện để nhập. Sau đó, nó hiển thị chuỗi nhập bằng màu xám, cho bạn biết rằng thư viện đã nhập chưa được sử dụng (cho đến nay).
-
Sử dụng gói từ tiếng Anh để tạo văn bản thay vì sử dụng chuỗi “Hello World”:
{step1_base → step2_use_package}/lib/main.dartLưu ý: “Chữ hoa Pascal” (còn được gọi là “chữ hoa lạc đà”), có nghĩa là mỗi từ trong chuỗi, kể cả từ đầu tiên, bắt đầu bằng một chữ cái viết hoa. Vì vậy, "chữ hoa" trở thành "UpperCamelCase".
-
Nếu ứng dụng đang chạy, hãy tải lại nóng để cập nhật ứng dụng đang chạy. Mỗi lần bạn nhấp vào tải lại nóng hoặc lưu dự án, bạn sẽ thấy một cặp từ khác nhau, được chọn ngẫu nhiên, trong ứng dụng đang chạy. Điều này là do ghép nối từ được tạo bên trong phương thức xây dựng, phương thức này được chạy mỗi khi
MaterialApp
yêu cầu hiển thị hoặc khi chuyển đổi Platform trong Trình kiểm tra Flutter.
Android
iOS
Các vấn đề?
Nếu ứng dụng của bạn chạy không chính xác, hãy tìm lỗi chính tả. Nếu bạn muốn thử một số công cụ gỡ lỗi của Flutter, hãy xem bộ công cụ gỡ lỗi và lập hồ sơ DevTools. Nếu cần, hãy sử dụng mã tại các liên kết sau để trở lại đúng hướng.
Bước 3: Thêm tiện ích Stateful
State less widget là bất biến, có nghĩa là thuộc tính của chúng không thể thay đổi - tất cả các giá trị đều là giá trị cuối cùng.
Các widget trạng thái ful duy trì trạng thái có thể thay đổi trong suốt thời gian tồn tại của widget. Việc triển khai một widget trạng thái yêu cầu ít nhất hai lớp: 1) một lớp StatefulWidget
tạo ra một thể hiện của 2) một lớp State
. Bản thân lớp StatefulWidget
này là bất biến và có thể bị loại bỏ và tái tạo, nhưng lớp State
vẫn tồn tại trong suốt thời gian tồn tại của widget.
Trong bước này, bạn sẽ thêm một tiện ích trạng thái, tiện ích RandomWords
tạo ra lớp State
của nó là _RandomWordsState
. Sau đó, bạn sẽ sử dụng RandomWords
như một đứa trẻ bên trong tiện ích MyApp
không trạng thái hiện có.
-
Tạo mã mẫu cho một widget trạng thái.
Tronglib/main.dart
, đặt con trỏ của bạn sau mã, nhập Return một vài lần để bắt đầu trên một dòng mới. Trong IDE của bạn, bắt đầu nhậpstful
. Trình chỉnh sửa hỏi bạn có muốn tạo mộtStateful
widget hay không. Nhấn Return để chấp nhận. Mã bảng soạn sẵn cho hai lớp xuất hiện và con trỏ được định vị để bạn nhập tên của tiện ích con trạng thái của bạn. -
Nhập
RandomWords
làm tên của tiện ích con của bạn.
WidgetRandomWords
không nhỏ hơn so với việc tạo ra lớpState
của nó.
Sau khi bạn đã nhậpRandomWords
như là tên của tiện ích con trạng thái, IDE sẽ tự động cập nhật lớpState
đi kèm, đặt tên cho nó là_RandomWordsState
. Theo mặc định, tên của lơpState
được đặt trước bằng một thanh gạch dưới. Bắt đầu số nhận dạng với dấu gạch dưới thực thi quyền riêng tư trong ngôn ngữ Dart và là phương pháp hay nhất được đề xuất cho các đối tượngState
.
IDE cũng tự động cập nhật lớp trạng thái để mở rộngState<RandomWords>
, cho biết rằng bạn đang sử dụng một lớpState
chung chuyên để sử dụng vớiRandomWords
. Hầu hết logic của ứng dụng nằm ở đây — nó duy trì trạng thái cho tiện íchRandomWords
. Lớp này lưu danh sách các cặp từ đã tạo, danh sách này phát triển vô hạn khi người dùng cuộn và, trong phần 2 của ví dụ này, các cặp từ yêu thích khi người dùng thêm hoặc xóa chúng khỏi danh sách bằng cách chuyển đổi biểu tượng trái tim.
Cả hai lớp bây giờ trông như sau:class RandomWords extends StatefulWidget { @override _RandomWordsState createState() => _RandomWordsState(); } class _RandomWordsState extends State<RandomWords> { @override Widget build(BuildContext context) { return Container(); } }
-
Cập nhật phương thức
build()
trong_RandomWordsState
:lib / main.dart (_RandomWordsState)class _RandomWordsState extends State<RandomWords> { @override Widget build(BuildContext context) { final wordPair = WordPair.random(); return Text(wordPair.asPascalCase); } }
-
Xóa mã tạo từ từ
MyApp
bằng cách thực hiện các thay đổi được hiển thị trong khác biệt sau:{step2_use_package → step3_stateful_widget}/lib/main.dart -
Khởi động lại ứng dụng. Ứng dụng sẽ hoạt động như trước đây, hiển thị ghép nối từ mỗi khi bạn tải lại nóng hoặc lưu ứng dụng.
Mẹo: Nếu bạn thấy cảnh báo về việc tải lại nóng rằng bạn có thể cần khởi động lại ứng dụng, hãy xem xét khởi động lại ứng dụng. Cảnh báo có thể là khẳng định sai, nhưng việc khởi động lại ứng dụng của bạn đảm bảo rằng các thay đổi của bạn được phản ánh trong giao diện người dùng của ứng dụng.
Các vấn đề?
Nếu ứng dụng của bạn chạy không chính xác, hãy tìm lỗi chính tả. Nếu bạn muốn thử một số công cụ gỡ lỗi của Flutter, hãy xem bộ công cụ gỡ lỗi và lập hồ sơ DevTools. Nếu cần, hãy sử dụng mã tại các liên kết sau để trở lại đúng hướng.
Bước 4: Tạo ListView cuộn vô hạn
Trong bước này, bạn sẽ mở rộng _RandomWordsState
để tạo và hiển thị danh sách các cặp từ. Khi người dùng cuộn, danh sách (được hiển thị trong một ListView
widget) sẽ tăng lên vô hạn. Hàm tạo builder
của ListView
cho phép bạn xây dựng một chế độ xem danh sách một cách lười biếng, theo yêu cầu.
-
Thêm danh sách
_suggestions
vào lớp_RandomWordsState
để lưu các cặp từ được đề xuất. Ngoài ra, hãy thêm một biến_biggerFont
để làm cho kích thước phông chữ lớn hơn.lib / main.dartclass _RandomWordsState extends State<RandomWords> { final _suggestions = <WordPair>[]; final _biggerFont = TextStyle(fontSize: 18.0); // ··· }
Tiếp theo, bạn sẽ thêm phương thức
_buildSuggestions()
vào lớp_RandomWordsState
. Phương thức này xây dựngListView
để hiển thị cặp từ được đề xuất.Các lớp
ListView
cung cấp một thuộc tính builder làitemBuilder
, đó là một factory builder và gọi lại chức năng đã định như một chức năng ẩn danh. Hai tham số được chuyển cho hàm —BuildContext
và vòng lặp hàngi
. Trình lặp bắt đầu từ 0 và tăng lên mỗi khi hàm được gọi. Nó tăng hai lần cho mọi cặp từ được đề xuất: một lần cho ListTile và một lần cho Divider. Mô hình này cho phép danh sách đề xuất tiếp tục phát triển khi người dùng cuộn. -
Thêm phương thức
_buildSuggestions()
vào lớp_RandomWordsState
:lib/main.dart (_buildSuggestions)Widget _buildSuggestions() { return ListView.builder( padding: EdgeInsets.all(16.0), itemBuilder: /*1*/ (context, i) { if (i.isOdd) return Divider(); /*2*/ final index = i ~/ 2; /*3*/ if (index >= _suggestions.length) { _suggestions.addAll(generateWordPairs().take(10)); /*4*/ } return _buildRow(_suggestions[index]); }); }
- /*1*/ Callback
itemBuilder
được gọi một lần cho mỗi cặp từ được đề xuất và đặt mỗi đề xuất thành một hàngListTile
. Đối với các hàng chẵn, hàm thêm một hàngListTile
để ghép từ. Đối với các hàng lẻ, hàm thêm một tiện íchDivider
để phân tách các mục nhập một cách trực quan. Lưu ý rằng dải phân cách có thể khó nhìn thấy trên các thiết bị nhỏ hơn. - /*2*/ Thêm tiện ích con chia độ cao một pixel trước mỗi hàng trong
ListView
. - /*3*/ Biểu thức
i ~/ 2
chia hếti
cho 2 và trả về kết quả là số nguyên. Ví dụ: 1, 2, 3, 4, 5 trở thành 0, 1, 1, 2, 2. Tính toán số lượng các cặp từ thực tế trongListView
, trừ đi các tiện ích con chia. - /*4*/ Nếu bạn đã hoàn thành các cặp từ có sẵn, hãy tạo thêm 10 từ nữa và thêm chúng vào danh sách gợi ý.
Hàm
_buildSuggestions()
gọi_buildRow()
một lần mỗi cặp từ. Hàm này hiển thị từng cặp mới trong mộtListTile
, cho phép bạn làm cho các hàng hấp dẫn hơn trong bước tiếp theo. - /*1*/ Callback
-
Thêm phương thức
_buildRow()
vào_RandomWordsState
:lib/main.dart (_buildRow)Widget _buildRow(WordPair pair) { return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), ); }
-
Trong lớp
_RandomWordsState
, cập nhật phương thứcbuild()
để sử dụng_buildSuggestions()
, thay vì gọi trực tiếp thư viện tạo từ. (Scaffold triển khai bố cục trực quan Material Design cơ bản). Thay thế phần thân phương thức bằng mã được đánh dấu:lib/main.dart (bản dựng)@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Startup Name Generator'), ), body: _buildSuggestions(), ); }
-
Trong lớp
MyApp
, cập nhật phương thứcbuild()
bằng cách thay đổi tiêu đề và thay đổi trang chủ thành một tiện íchRandomWords
:
{step3_stateful_widget → step4_infinite_list}/lib/main.dart -
Khởi động lại ứng dụng. Bạn sẽ thấy danh sách các cặp từ cho dù bạn cuộn bao xa.
Android
iOS
Các vấn đề?
Nếu ứng dụng của bạn chạy không chính xác, hãy tìm lỗi chính tả. Nếu bạn muốn thử một số công cụ gỡ lỗi của Flutter, hãy xem bộ công cụ gỡ lỗi và lập hồ sơ DevTools. Nếu cần, hãy sử dụng mã tại liên kết sau để trở lại đúng hướng.
Chạy profile hoặc release
Quan trọng: Không kiểm thử hiệu năng ứng dụng của bạn với debug và tải lại nóng kích hoạt.
Ví dụ trên ta đang chạy ứng dụng ở chế độ debug. Chế độ gỡ lỗi giao dịch hiệu suất cho các tính năng hữu ích của nhà phát triển như tải lại nóng và gỡ lỗi bước. Không có gì bất ngờ khi thấy hiệu suất chậm và hoạt ảnh lộn xộn trong chế độ gỡ lỗi. Khi bạn đã sẵn sàng phân tích hiệu suất hoặc phát hành ứng dụng của mình, bạn sẽ muốn sử dụng các chế độ build "profile" hoặc "release" của Flutter. Để biết thêm chi tiết, hãy xem các chế độ xây dựng của Flutter.
Quan trọng: Nếu bạn lo lắng về kích thước gói ứng dụng của mình, hãy xem Đo kích thước ứng dụng của bạn.
Bước tiếp theo
Xin chúc mừng!
Bạn đã viết một ứng dụng Flutter tương tác chạy trên cả iOS và Android. Trong bảng mã này, bạn:
- Đã tạo một ứng dụng Flutter từ đầu.
- Viết mã Dart.
- Tận dụng thư viện bên thứ ba, bên ngoài.
- Đã sử dụng tải lại nóng cho chu kỳ phát triển nhanh hơn.
- Đã triển khai một widget trạng thái.
- Đã tạo một danh sách cuộn vô hạn, được tải một cách lười biếng.
Nếu bạn muốn mở rộng ứng dụng này, hãy chuyển sang phần 2 trên trang web Google Developers Codelabs, nơi bạn thêm chức năng sau:
- Triển khai tính tương tác bằng cách thêm biểu tượng trái tim có thể nhấp để lưu các cặp yêu thích.
- Triển khai điều hướng đến một route mới bằng cách thêm một màn hình mới chứa các mục yêu thích đã lưu.
- Sửa đổi màu chủ đề, tạo một ứng dụng toàn màu trắng.
Ứng dụng từ phần 2