天天看點

flutter 中的清單的性能優化續集#yyds幹貨盤點#

重新建構嵌套清單

這一節使用 Slivers 而不是 ListViews 重建相同的 UI。

前奏在這裡

​​https://blog.51cto.com/jianguo/4653002​​

使用 Slivers 的清單清單

下面的代碼建構了與之前相同的 UI,但這次它使用​

​Slivers​

​ 而不是收縮包裝​

​ListView​

​對象。本頁的其餘部分将引導您逐漸完成更改。

如何将嵌套清單遷移到 Slivers

flutter 中的清單的性能優化續集#yyds幹貨盤點#

第1步

首先,将最外面的 ListView 更改為​

​SliverList​

​.

// Before

@override

Widget build(BuildContext context) {

  return ListView.builder(

    itemCount: numberOfLists,

    itemBuilder: (context, index) => innerLists[index],

  );

}      

變成:

// After

@override

Widget build(BuildContext context) {

  return CustomScrollView(slivers: innerLists);

}      

第2步

其次,将内部清單的類型從​

​List​

​更改為 ​

​List​

​。

// Before

List innerLists = [];      

變成:

// After

List innerLists = [];      

第 3 步

現在是時候重建内部清單了。的​

​SliverList​

​類是比原始略有不同​

​ListView​

​的類,與主要差異是的外觀​

​delegate​

​。原始版本​

​ListView​

​對所有内容都使用對象,不知道内部建構器構造函數将被​

​shrinkWrap​

​.

// Before

@override

void initState() {

  super.initState();

  for (int i = 0; i < numberOfLists; i++) {

    final _innerList = [];

    for (int j = 0; j < numberOfItemsPerList; j++) {

      _innerList.add(const ColorRow());

    }

    innerLists.add(

      ListView.builder(

        itemCount: numberOfItemsPerList,

        itemBuilder: (BuildContext context, int index) => _innerList[index],

        shrinkWrap: true,

        physics: const NeverScrollableScrollPhysics(),

      ),

    );

  }

}      
// After

@override

void initState() {

  super.initState();

  for (int i = 0; i < numLists; i++) {

    final _innerList = [];

    for (int j = 0; j < numberOfItemsPerList; j++) {

      _innerList.add(const ColorRow());

    }

    innerLists.add(

      SliverList(

        delegate: SliverChildBuilderDelegate(

          (BuildContext context, int index) => _innerList[index],

          childCount: numberOfItemsPerList,

        ),

      ),

    );

  }

}      
import 'package:flutter/material.dart';

import 'dart:math' as math;



void main() {

  runApp(SliversApp());

}



class SliversApp extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      debugShowCheckedModeBanner: false,

      title: 'ShrinkWrap vs Slivers',

      home: Scaffold(

        appBar: AppBar(

          title: const Text("Revenge of the Slivers"),

        ),

        body: const ShrinkWrapSlivers(),

      ),

    );

  }

}



class ShrinkWrapSlivers extends StatefulWidget {

  const ShrinkWrapSlivers({

    Key? key,

  }) : super(key: key);



  @override

  _ShrinkWrapSliversState createState() => _ShrinkWrapSliversState();

}



class _ShrinkWrapSliversState extends State {

  List innerLists = [];

  final numLists = 15;

  final numberOfItemsPerList = 100;



  @override

  void initState() {

    super.initState();

    for (int i = 0; i < numLists; i++) {

      final _innerList = [];

      for (int j = 0; j < numberOfItemsPerList; j++) {

        _innerList.add(const ColorRow());

      }

      innerLists.add(

        SliverList(

          delegate: SliverChildBuilderDelegate(

            (BuildContext context, int index) => _innerList[index],

            childCount: numberOfItemsPerList,

          ),

        ),

      );

    }

  }



  @override

  Widget build(BuildContext context) {

    return CustomScrollView(slivers: innerLists);

  }

}



@immutable

class ColorRow extends StatefulWidget {

  const ColorRow({Key? key}) : super(key: key);



  @override

  State createState() => ColorRowState();

}



class ColorRowState extends State {

  Color? color;



  @override

  void initState() {

    super.initState();

    color = randomColor();

  }



  @override

  Widget build(BuildContext context) {

    print('Building ColorRowState');

    return Container(

      decoration: BoxDecoration(

        gradient: LinearGradient(

          begin: Alignment.topLeft,

          end: Alignment.bottomRight,

          colors: [

            randomColor(),

            randomColor(),

          ],

        ),

      ),

      child: Row(

        children: [

          Padding(

            padding: const EdgeInsets.all(8.0),

            child: Container(height: 50, width: 50, color: Colors.white),

          ),

          Flexible(

            child: Column(

              children: const [

                Padding(

                  padding: EdgeInsets.all(8),

                  child: Text('這裡是堅果前端小課堂!',

                      style: TextStyle(color: Colors.white)),

                ),

              ],

            ),

          ),

        ],

      ),

    );

  }

}



Color randomColor() =>

    Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);      

Lazy building!