Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK
Code

Google Flutter từ đầu: Grids, Lists và Data Sources

by
Difficulty:IntermediateLength:MediumLanguages:
This post is part of a series called Google Flutter From Scratch.
Google Flutter From Scratch: Building Apps With Widgets
Google Flutter From Scratch: Animating Widgets

Vietnamese (Tiếng Việt) translation by Vy Cam Nguyen (you can also view the original English article)

Hầu như mọi ứng dụng di động không tầm thường ngày nay đều có thể có list trong bố cục của nó. Đó là bởi vì sử dụng một list có thể cuộn thường là cách đơn giản nhất để hiển thị một số lượng lớn các mục tương tự trên một màn hình nhỏ.

Flutter framework cung cấp một số widget mà bạn có thể sử dụng hiệu quả và với mã tối thiểu, tạo và hiển thị các list như vậy. Trong hướng dẫn này, tôi sẽ chỉ cho bạn cách sử dụng chúng với cả hai nguồn dữ liệu cục bộ và từ xa.

1. Hiển thị list không thể cuộn

Nếu bạn cần hiển thị một số lượng nhỏ các mục tương tự và bạn chắc chắn rằng màn hình của người dùng sẽ có thể chứa tất cả chúng cùng một lúc, sử dụng tiện ích Column là điều hiệu quả nhất để thực hiện.

Để tạo list trong ứng dụng Flutter của bạn, bạn có thể sử dụng class List mà ngôn ngữ lập trình Dart cung cấp. Sau khi tạo list, bạn có thể sử dụng phương thức add() của nó để thêm bất kỳ số lượng mục nào vào nó. Mã sau đây cho bạn thấy cách tạo list chứa ba tiện ích con RaisedButton:

Lưu ý rằng mỗi mục trong list có một trình xử lý sự kiện onPressed rỗng được liên kết với nó vì, nếu không có, mục đó sẽ bị vô hiệu hóa.

Bây giờ list đã sẵn sàng, bạn có thể gán nó trực tiếp cho thuộc tính con của widget Column được hiển thị. Tuy nhiên, thông thường, bạn cũng sẽ muốn chỉ định vị trí các mục list sẽ được đặt trên màn hình. Vì tiện ích Column là tiện ích con flex, bạn có thể kiểm soát vị trí của các mục dọc theo trục chính và trục chéo bằng cách sử dụng thuộc tính mainAxisAlignment crossAxisAlignment. Theo mặc định, đối với tiện ích Column, trục chính là trục thẳng đứng và trục chéo là trục ngang.

Các mã sau đây cho bạn thấy làm thế nào để kéo dài ba nút trên trục ngang và đặt chúng ở trung tâm của màn hình theo chiều dọc:

Dưới đây là hình thức của colum:

App displaying column with three buttons

Điều quan trọng cần lưu ý là bạn sẽ gặp lỗi runtime nếu tiện ích Column không thể chứa tất cả các con của nó. Ví dụ: nếu bạn có hơn một tá tiện ích RaisedButton trong list thay vì chỉ ba, bạn sẽ thấy thông báo lỗi giống như sau:

App displaying overflow error

2. Hiển thị một list có thể cuộn đơn giản

Đối với các list lớn hơn một chút, các list có nội dung có khả năng tràn màn hình, bạn phải xem xét sử dụng tiện ích ListView vì nó hỗ trợ cuộn.

Bạn có thể đã nhận thấy rằng mã chúng tôi đã viết để tạo list ở bước trước đó đều dài dòng và lặp lại. Tạo một list lớn hơn bằng cách sử dụng cùng một cách tiếp cận có thể rất tẻ nhạt. Cách tiếp cận thay thế dễ dàng là sử dụng hai list thay vào đó: một list chứa dữ liệu và một chứa các tiện ích con.

Dưới đây là cách bạn có thể sử dụng toán tử [] để nhanh chóng tạo list dữ liệu, hiện tại, chỉ chứa một số chuỗi:

Để chuyển đổi list chuỗi ở trên thành list các tiện ích con RaisedButton, bạn có thể sử dụng các phương thức map() toList(). Với phương thức map(), bạn có thể sử dụng từng chuỗi để tạo ra một widget RaisedButton mới. Và với phương thức toList(), bạn có thể chuyển đổi đối tượng Iterable được trả về bởi phương thức map() thành một đối tượng List thực tế. Các mã sau đây cho bạn thấy làm thế nào:

Để hoàn thành, mã trên cũng cho bạn thấy cách tạo trình xử lý sự kiện onPressed sử dụng các phương thức canLaunch() launch() được cung cấp bởi gói url_launcher để mở trang web mà người dùng đã chọn trong trình duyệt mặc định.

Khi list của bạn đã sẵn sàng, bạn có thể chuyển nó tới thuộc tính con của tiện ích ListView để hiển thị nó.

Tại thời điểm này, nếu bạn chạy ứng dụng, bạn sẽ có thể cuộn qua list và nhấn bất kỳ nút nào để khởi chạy trang web được liên kết.

App displaying a scrollable list

3. Tạo Grid

Tiện ích ListView cho phép bạn chỉ đặt một mục trên trục chéo của nó. Theo mặc định, mục sẽ được kéo dài để chiếm tất cả không gian có sẵn trên trục đó. Nếu bạn muốn linh hoạt hơn, bạn nên cân nhắc sử dụng tiện ích GridView thay thế, cho phép bạn chỉ định số lượng mục bạn muốn trên trục chéo.

Đoạn mã sau sử dụng hàm tạo GridView.count() để tạo một widget GridView hiển thị hai mục trên mỗi hàng:

Grid sẽ trông giống như vậy:

App displaying a grid of buttons

4. Hiển thị list lớn

Đối với list dữ liệu chứa nhiều hơn một vài mục, bạn nên tránh tạo list tiện ích theo cách thủ công, cách bạn đã làm trong bước trước đó. Tại sao? Bởi vì việc tạo ra một widget là một hoạt động tốn kém, và các list widget lớn có thể tiêu tốn rất nhiều bộ nhớ.

Thay vào đó, bạn nên sử dụng hàm IndexedWidgetBuilder, cho phép bạn tạo các widget chỉ khi người dùng cần xem chúng. Với nó, bạn có thể lười biếng tạo ra các widget khi người dùng cuộn qua widget ListView của bạn.

Điều đó khá khó mà bạn sẽ có một lượng lớn dữ liệu được xác định ngay bên trong ứng dụng của bạn. Thông thường, bạn sẽ tìm nạp dữ liệu đó từ một remote server. Do đó, để cung cấp cho bạn một ví dụ thực tế, hãy để tôi cho bạn biết cách lấy 100 câu hỏi từ Stack Overflow bằng cách sử dụng Stack Exchange API và hiển thị chúng theo yêu cầu.

Bắt đầu bằng cách tạo một lớp con của lớp StatefulWidget, nó sẽ hoạt động như một container cho widget ListView của bạn và ghi đè phương thức createState() của nó.

Class MyState được đề cập trong đoạn mã trên không tồn tại, vì vậy hãy tạo nó và ghi đè lên phương thức build() của nó.

Tiếp theo, thêm một đối tượng List làm một trong các biến thành viên của lớp. Bạn sẽ sử dụng nó để lưu trữ các câu hỏi bạn đã tải xuống từ Stack Overflow. Ngoài ra, hãy thêm điểm cuối của API dưới dạng biến khác.

Trừ khi bạn muốn người dùng của bạn nhấn một nút để tải xuống các câu hỏi, tôi khuyên bạn nên tự động tải xuống chúng khi tiện ích đang khởi chạy. Theo đó, ghi đè phương thức initState() và thực hiện cuộc gọi đến một phương thức không đồng bộ mới gọi là loadData().

Bên trong phương thức loadData(), bạn có thể sử dụng hàm get() của gói http của Dart để tải xuống các câu hỏi. Điểm cuối API trả về một tài liệu JSON, bạn có thể phân tích bằng cách sử dụng hàm json.decode() có sẵn trong gói chuyển đổi của Dart. Các mã sau đây cho bạn thấy làm thế nào:

Khi tài liệu JSON đã được chuyển đổi thành đối tượng Bản đồ, bạn có thể sử dụng giá trị được liên kết với khóa mục của nó để khởi tạo biến câu hỏi. Tuy nhiên, biến này là một phần của trạng thái của tiện ích. Vì vậy, bạn phải chắc chắn rằng bạn cập nhật nó bên trong phương thức setState(). Dưới đây là cách thực hiện:

Tại thời điểm này, bạn có thể tạo một tiện ích ListView mới bằng cách sử dụng hàm tạo ListView.builder(), dự kiến ​​một hàm IndexedWidgetBuilder và một mục đếm làm đối số của nó. Hiện tại, số lượng mục không là gì ngoài kích thước của list câu hỏi. Theo đó, thêm đoạn mã sau bên trong phương thức build() của lớp MyState:

Bên trong hàm xây dựng, tất cả những gì bạn cần làm là tạo một cây nhỏ để hiển thị các chi tiết khác nhau về mỗi câu hỏi bạn đã tải xuống. Gói vật liệu của Flutter cung cấp một widget rất tiện dụng được gọi là ListTile, cho phép bạn nhanh chóng tạo ra một cây như vậy trong khi tuân thủ các nguyên tắc Material Design.

Đoạn mã sau đây cho bạn thấy cách hiển thị tiêu đề và tác giả của câu hỏi, sử dụng các thuộc tính tiêu đềphụ đề của tiện ích ListTile:

Cuối cùng, tạo một widget Scaffold mới, gán tiện ích ListView cho thuộc tính cơ thể của nó và trả về nó từ phương thức build() để nó có thể được sử dụng với một widget MaterialApp. Theo tùy chọn, bạn có thể thêm tiện ích AppBar vào tiện ích con Giàn giáo.

Dưới đây là ứng dụng sẽ trông như thế nào sau khi đã tải xuống các câu hỏi:

App displaying Stack Overflow data

Tổng kết

Bây giờ bạn biết cách làm việc với các list trong một ứng dụng Flutter. Trong hướng dẫn này, bạn đã học được không chỉ cách tạo list và Grid hỗ trợ các nguồn dữ liệu lớn (data sources), mà còn biết làm thế nào để làm cho mỗi mục bên trong chúng tương tác. Để tìm hiểu thêm về list trong Flutter, bạn có thể tham khảo tài liệu chính thức.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.