一統天下 flutter - widget Sliver: SliverList, SliverFixedExtentList - 列表(需要在 CustomScrollView 中使用)

源碼 https://github.com/webabcd/flutter_demo
作者 webabcd

一統天下 flutter - widget Sliver: SliverList, SliverFixedExtentList - 列表(需要在 CustomScrollView 中使用)

示例如下:

lib\widget\sliver\sliver_list.dart

/*
 * SliverList - 列表(需要在 CustomScrollView 中使用)
 * SliverFixedExtentList - 在 SliverList 的基礎上增加了對 itemExtent 的支持
 */

import 'dart:math';

import 'package:flutter/material.dart';

class SliverListDemo extends StatefulWidget {
  const SliverListDemo({Key? key}) : super(key: key);

  @override
  _SliverListDemoState createState() => _SliverListDemoState();
}

class _SliverListDemoState extends State<SliverListDemo> {

  final _random = Random();
  Color _getRandomColor() {
    return Color.fromARGB(255, _random.nextInt(256), _random.nextInt(256), _random.nextInt(256),);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          SliverList(
            /// SliverChildListDelegate - 初始化的時就會把所有元素都創建好
            delegate: SliverChildListDelegate(
              [
                Container(color: Colors.red, height: 150,),
                Container(color: Colors.green, height: 150,),
                Container(color: Colors.blue, height: 150,),
              ],
            ),
          ),

          SliverList(
            /// SliverChildBuilderDelegate - 根據滾動的位置按需創建元素,並且根據數據源動態生成對應的元素
            delegate: SliverChildBuilderDelegate((context, index) =>
                Container(color: _getRandomColor(), height: 150,),
              /// 用於指定列表中的元素數量
              childCount: 10,
              /// 是否將列表內元素用 AutomaticKeepAlive 封裝,從而在元素滾動出可視區的時候允許其保持狀態(注:前提是元素支持保持狀態)
              /// 要想使元素可以保持狀態,需要藉助 with AutomaticKeepAliveClientMixin,後面會有詳細說明
              /// 通過測試本例可以發現,這個 SliverList 內的 Container 每次重新滾動到可視區的時候顏色都會變化,其並不會保持狀態
              addAutomaticKeepAlives: true,
              /// 是否將列表內元素用 RepaintBoundary 封裝,從而使滾動的時候避免重繪
              addRepaintBoundaries: true,
            ),
          ),

          SliverFixedExtentList(
            /// 用於定義每個元素在滾動方向上的尺寸
            /// 比如垂直滾動的話,這裏就是設置每個元素的高;水平滾動的話,這裏就是設置每個元素的寬
            /// 也可以不指定這個,那麼就由每個元素自己決定尺寸(注:建議使用 itemExtent 指定尺寸,這樣性能會好一些)
            itemExtent: 50.0,
            delegate: SliverChildBuilderDelegate((context, index) =>
                Container(color: _getRandomColor(),),
              childCount: 10,
            ),
          ),

          SliverFixedExtentList(
            itemExtent: 150.0,
            delegate: SliverChildBuilderDelegate((context, index) =>
                _MyWidget(color: _getRandomColor(),),
              childCount: 10,
              /// 是否將列表內元素用 AutomaticKeepAlive 封裝,從而在元素滾動出可視區的時候允許其保持狀態(注:前提是元素支持保持狀態)
              /// 要想使元素可以保持狀態,需要藉助 with AutomaticKeepAliveClientMixin,請參見本例使用的 _MyWidget 中的說明
              /// 通過測試本例可以發現,這個 SliverList 內的 _MyWidget 每次重新滾動到可視區的時候顏色都不會變化,其會保持狀態
              addAutomaticKeepAlives: true,
            ),
          ),
        ],
      ),
    );
  }
}

class _MyWidget extends StatefulWidget {
  const _MyWidget({Key? key, required this.color}) : super(key: key);

  final Color color;

  @override
  _MyWidgetState createState() => _MyWidgetState();
}

/// 如果需要當前元素可以保持狀態,則可以使用 with AutomaticKeepAliveClientMixin
class _MyWidgetState extends State<_MyWidget> with AutomaticKeepAliveClientMixin {

  @override
  Widget build(BuildContext context) {
    /// 用了 with AutomaticKeepAliveClientMixin 則這裏必須要 super.build(context);
    super.build(context);

    return Container(
      color: widget.color,
    );
  }

  /// 需要保持狀態
  @override
  bool get wantKeepAlive => true;
}

源碼 https://github.com/webabcd/flutter_demo
作者 webabcd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章