Flutter ListView và ScrollPhysics: Một cái nhìn chi tiết

Các loại ListView

Chúng ta bắt đầu tìm hiểu các loại listview và sau đó sẽ tìm cách chỉnh sửa các tính năng của chúng. Đây là các loại listview chúng ta cần tìm hiểu :

  1. ListView
  2. ListView.builder
  3. ListView.separated
  4. ListView.custom

Bây giờ chúng ta sẽ đi tìm hiểu từng cái :

1. ListView

Một ListView chứa các item con và có thể cuộn được :

Code:

ListView(
  children: <Widget>[
    ItemOne(),
    ItemTwo(),
    ItemThree(),
  ],
),

Thông thường đối với loại trên sẽ sử dụng với số lượng children (số item) nhỏ nếu bạn cố xây dựng với lượng lớn thì sẽ gây tốn bộ nhớ khiến view bị giật lag.

2. ListView.builder

Contructor builder sẽ repeat số item . Hàm contructor này có 2 params:

itemCount: Tổng số item trong list. itemBuilder: sẽ tạo view cho từng item.

Code:

ListView.builder(
  itemCount: itemCount,
  itemBuilder: (context, position) {
    return listItem();
  },
),

Các item được xây dựng theo cơ chế resuable nghĩa là các item đã được cuộn và ko hiển thị ở màn hình sẽ được tái sử dụng cho các item được hiển thị .

Neat trick: Vì các phẩn tử được tải một cách lười biếng và chỉ cần số phần tử hiển thị trên màn hình nên không cần thiết tổng số item như là 1 pramas bắt buộc và có thể load item đến vô hạn .

3. ListView.separated

Khi sử dụng ListView này thì giữa các item sẽ có khoảng cách

Trong hàm constructor này có 2 thành phần : main list item và list khoảng cách item. Tuy nhiên hàm này ko giống ListView.builder phải cần số itemCount .

ListView.separated(
      itemBuilder: (context, position) {
        return ListItem();
      },
      separatorBuilder: (context, position) {
        return SeparatorItem();
      },
      itemCount: itemCount,
),

4. ListView.custom

Hàm custom() cho phép tạo các ListViews với các thành phần con tuỳ chỉnh. Các số tham số tuỳ chỉnh bắt buộc :

1. SliverChildListDelegate

2. SliverChildBuilderDelegate

SliverChildListDelegate cho phép trực tiếp các list child item nhưng SliverChildBuiderDelegate cho phép IndexedWidgetBuilder(function builder chúng tôi dùng).

Contructor ListView giống với ListView.custom khi dùng SliverChildListDelegate

Tôi đã giới thiệu các bạn loại ListView , bây giờ hãy xem qua ScrollPhysics.

ScrollPhysics

Để kiểm soát cách cuộn của các ListView chúng ta sẽ đặt thêm 1 param vào trong các hàm constructor của ListView. Các loại cuộn :

  1. NeverScrollableScrollPhysics
  2. BouncingScrollPhysics
  3. ClampingScrollPhysics
  4. FixedExtentScrollPhysics

1. NeverScrollableScrollPhysics

Đúng như tên gọi dùng để disable việc scroll của listview.

2. BouncingScrollPhysics

Khi cuộn đến item cuối cùng thì nó sẽ trả về item đầu tiên .

Bạn có thể xem ảnh demo ở đây :

3. ClampingScrollPhysics

Đây là cách cuộn hay được dùng ở bên Android. Khi cuộn đến item cuối cùng thì sẽ có 1 hiệu ứng.

4. FixedExtentScrollPhysics

Cách cuộn này hơi khác với các cách cuộn trên và chỉ làm việc với FixedExtendScrollControllers . Nó chỉ cuộn đến item có offset ở giữa.

Code :

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,
),

Một số điều cần biết

1, Làm cách nào để các phần tử không bị destroy và vẫn tồn tại trong list ?

TL : Flutter cung cấp hàm KeepAlive() để giúp các item không bị destroy. Trong list , các phần tử sẽ được wrap default bằng widget AutomaticKeepAlive

AutomaticKeepAlives có thể disable bằng set addAutomaticKeepAlives = false

2, Tại sao ListView của tôi có khoảng cách với widget bên ngoài

TL: Mặc đinh ListView luôn có padding , để xóa padding bạn cần set EdgeInsets.all(0.0).

Tài liệu tham khảo :

https://medium.com/flutter-community/flutter-listview-and-scrollphysics-a-detailed-look-7f0912df2754


All Rights Reserved