This is the 21st day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Here is nut front-end small classroom, if you like, you can follow my public number “nut front-end,” or add my friends, for more wonderful content

Nested lists – ShrinkWrap with Slivers

List list for ShrinkWrap

Here is some code to render list lists using ListView objects, with inner lists shrinkWrap set to true. ShrinkWrap forces the evaluation of the entire internal list, allowing it to request a finite height instead of the usual ListView object height, which is infinite!

Here is the basic code structure:

ListView( // Setting `shrinkWrap` to `true` here is both unnecessary and expensive. children: <Widget>[ ListView.builder( itemCount: list1Children.length, itemBuilder: (BuildContext context, int index) { return list1Children[index];  }, // This forces the `ListView` to build all of its children up front, // negating much of the benefit of using `ListView.builder`. shrinkWrap: true, ), ListView.builder( itemCount: list2Children.length, itemBuilder: (BuildContext context, int index) { return list2Children[index];  }, // This forces the `ListView` to build all of its children up front, // negating much of the benefit of using `ListView.builder`. shrinkWrap: true, ), ... ] .)Copy the code

Note: Observe that the external ListView does not set its shrinkWrap value to true. ShrinkWrap needs to be set only for internal lists.

Also note: While listView.Builder (by default) effectively builds its subitems, saving you the unnecessary cost of building off-screen widgets, setting shrinkWrap to true overwrites this default behavior!

import 'package:flutter/material.dart'; import 'dart:math' as math; void main() { runApp(ShrinkWrApp()); } class ShrinkWrApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'ShrinkWrap vs Slivers', home: Scaffold( appBar: AppBar( title: const Text("ShrinkWrap, Street Rat, I don't, Buy that!" ), ), body: const ShrinkWrapSlivers(), ), ); } } class ShrinkWrapSlivers extends StatefulWidget { const ShrinkWrapSlivers({ Key? key, }) : super(key: key); @override _ShrinkWrapSliversState createState() => _ShrinkWrapSliversState(); } class _ShrinkWrapSliversState extends State<ShrinkWrapSlivers> { List<ListView> innerLists = []; final numLists = 15; final numberOfItemsPerList = 100; @override void initState() { super.initState(); for (int i = 0; i < numLists; i++) { final _innerList = <ColorRow>[]; 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(), ), ); } } @override Widget build(BuildContext context) { return ListView.builder( itemCount: numLists, itemBuilder: (context, index) => innerLists[index]); } } @immutable class ColorRow extends StatefulWidget { const ColorRow({Key? key}) : super(key: key); @override State createState() => ColorRowState(); } class ColorRowState extends State<ColorRow> { 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: <Widget>[Padding(Padding: const EdgeInsets. All (8.0), child: height: 50, width: 50, color: RGB (0, 0, 0)) Colors.white), ), Flexible( child: Column( children: const <Widget>[ Padding( padding: EdgeInsets.all(8), child: The Text (' here is nuts front small classroom! ', style: TextStyle (color: Colors. White)),),),),),,,); }} Color randomColor() => Color((math.random ().nextDouble() * 0xFFFFFF).toint ()).withopacity (1.0);Copy the code

Everything is set up!

The scary part comes when you scroll through the UI and notice how the colorBarstate.build method is called. Each internal list contains 100 elements, so when the UI loads, you’ll immediately see 100 instances of “Building ColorBarState” printed to the console,

Even worse, once you scroll down about a hundred lines, it regenerates into a hundred lines. 😱 😱 😱

And the list shakes when you swipe fast!

Rebuild the nested list

To learn how to keep your users safe from stashing, wait for my second section, which will rebuild the same UI using Slivers instead of ListViews.