Flutter List View và ScrollPhysics: Cách nhìn cụ thể
Bài đăng này đã không được cập nhật trong 3 năm
ListView
trong Flutter là một danh sách tuyến tính gồm các item có thể cuộn được (scrollable
) - tương tự với ListView
hoặc RecyclerView
bên Android. Chúng ta có thể sử dụng nó để tạo danh sách các đối tượng có thể cuộn được hoặc danh sách các đối tượng lặp lại.
Khám phá các loại ListView
Chúng ta sẽ bắt đâu bằng việc xem xét các loại ListView
, sau đó xem xét các tính năng khác và sửa đổi chúng một chút.
Ta có các loại ListView
dưới đây:
- ListView
- ListView.builder
- ListView.separated
- ListView.custom
Hãy cùng đi khám phá từng loại List View
nhé!
ListView
Đây là phương thức khởi tạo mặc định của class ListView
. ListView
chỉ đơn giản là lấy một danh sách các con (children
) và làm cho nó có thể cuộn được (scrollable
)
Code của chúng ta sẽ nhìn như thế này:
ListView(
children: <Widget>[
ItemOne(),
ItemTwo(),
ItemThree(),
],
),
Cách này thường chỉ được sử dụng với một số lượng nhỏ children
. Nếu ta sử dụng với 1 danh sách đủ dài, sẽ rất mất thời gian để triển khai chúng vào code.
ListView.builder()
Hàm khởi tạo builder()
xây dựng 1 danh sách lặp lại các item
. Constructor lúc này sẽ nhận 2 tham số chính: itemCount
đại diện cho số lượng item, và itemBuilder
đại diện cho từng mục hiển thị trong danh sách.
Code của chúng ta sẽ nhìn như thế này:
ListView.builder(
itemCount: itemCount,
itemBuilder: (context, position) {
return listItem();
},
),
Danh sách các item được khởi tạo một cách lazily
, nghĩa là chỉ một số item cụ thể được tạo, và khi người dùng thực hiện thao tác cuộn xuống dưới, các item trước đó sẽ bị hủy - khá tương đồng với cách hoạt động của RecyclerView
trong Android.
Trick: Vì các item được load một cách lazily và chỉ có 1 số item cần thiết được load, ta sẽ không thực sự cần tới itemCount
là tham số bắt buộc và List có thể có chiều dài vô hạn.
ListView.builder(
itemBuilder: (context, position) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(position.toString(), style: TextStyle(fontSize: 22.0),),
),
);
},
),
ListView.separated()
Với hàm khởi tạo separated()
, chúng ta tạo ra 1 list các item và có thể định nghĩa hiển thị ngăn cách giữa các item
Về bản chất, chúng ta đang xây dựng 2 list đan xen với nhau - 1 là danh sách chính bao gồm các item - 2 là danh sách các separated
.
Lưu ý rằng độ dài vô hạn không thể được sử dụng trong trường hợp này - bắt buộc chúng ta phải sử dụng itemCount
trong hàm khởi tạo:
ListView.separated(
itemBuilder: (context, position) {
return ListItem();
},
separatorBuilder: (context, position) {
return SeparatorItem();
},
itemCount: itemCount,
),
Kiểu list này cho phép ta xác định các separated
, có các loại item
khác nhau tương ứng với các separated
khác nhau, thêm hoặc xóa separated
khi cần...
Việc triển khai này cũng có thể được sử dụng để chèn các loại item khác (ví dụ: quảng cáo) một cách dễ dàng.
Lưu ý: Độ dài của list separated
sẽ nhỏ hơn 1 đơn vị so với độ dài của list các item chính vì separated
không tồn tại sau item cuối cùng của list.
ListView.custom()
Hàm khởi tạo custom()
đúng như tên gọi của nó - cho phép chúng ta tạo ListView
với chức năng tùy chỉnh về cách tạo các item của list. Các tham số chính cần thiết là:
- SliverChildListDelegate
- SliverChildBuilderDelegate
SliverChildListDelegate
chấp nhận trực tiếp một danh sách các item, trong khi SliverChildBuilderDelegate
chấp nhận một IndexedWidgetBuilder
(hàm xây dựng widget tương ứng với item thông qua index
của item)
ListView.builder
về cơ bản là một ListView.custom
với SliverChildBuilderDelegate
.
Phương thức khởi tạo mặc định của ListView
hoạt động giống như ListView.custom
với SliverChildListDelegate
Chúng ta đã xong với phần tìm hiểu các kiểu ListView
, giờ hãy đi sâu hơn về ScrollPhysics
Khám phá ScrollPhysics
Để kiểm soát hành vi cuộn (scrolling) đang diễn ra, ta đặt tham số physics
trong hàm khởi tạo của ListView
. Có các kiểu physics
khác nhau như sau:
NeverScrollableScrollPhysics
NeverScrollableScrollPhysics
khiến cho list không thể cuộn. Ta có thể sử dụng nó để ngăn người dùng thực hiện thao tác cuộn ListView
nhằm thực hiện 1 số tác vụ nào đó.
BouncingScrollPhysics
BouncingScrollPhysics
làm danh sách có hoạt ảnh nẩy lên khi kéo xuống cuối cùng hoặc đầu tiên của ListView
- tương tự hiệu ứng được sử dụng trên hệ điều hành iOS.
ClampingScrollPhysics
ClampingScrollPhysics
là hoạt ảnh mặc định trên hệ điều hành Android. List sẽ dừng ở 2 đầu và hiển thị hiệu ứng đổ bóng
FixedExtentScrollPhysics
Điều này hơi khác so với những thứ chúng ta nêu trên ở chỗ nó chỉ hoạt động với FixedExtendScrollControllers
và danh sách sử dụng chúng. FixedExtendScrollControllers
chỉ cuộn đến các items thay vì bất kỳ phần bù nào ở giữa
Dưới đây là code để triển khai:
FixedExtentScrollController fixedExtentScrollController =
new FixedExtentScrollController();
ListWheelScrollView(
controller: fixedExtentScrollController,
physics: FixedExtentScrollPhysics(),
children: monthsOfTheYear.map((month) {
return Card(
child: Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
month,
style: TextStyle(fontSize: 18.0),
),
)),
],
));
}).toList(),
itemExtent: 60.0,
),
Kết
Hi vọng với bài viết này, các bạn có thể tự tạo ListView
trong ứng dụng của mình một cách hợp lý nhất. Mong mọi người sẽ tiếp tục đón đọc những bài viết về Flutter của mình trong thời gian sắp tới.
All rights reserved