Flutter ListView og ScrollPhysics: Et detaljeret look

Udforskning af ListView-widgeten og dens funktioner i dybden

For et stykke tid siden skrev jeg en artikel om det grundlæggende ved brug af en ListView og GridView i Flutter. Denne artikel er beregnet til en mere detaljeret udforskning af ListView-klassen, ScrollPhysics og justeringer og optimeringer til den generelle widget.

En ListView i Flutter er en lineær liste over rullbare genstande. Vi kan bruge den til at lave en liste over genstande, der kan rulles eller oprette en liste over gentagne genstande.

Udforskning af typerne af ListView

Vi begynder med at se på typerne af ListViews og senere se på de andre funktioner og pæne ændringer til det.

Lad os se på hvilke typer ListViews der er:

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

Lad os gå rundt og udforske disse typer én efter én:

Listevisning

Dette er standardkonstruktøren i klassen ListView. En ListView tager blot en liste over børn og gør den rullbar.

En liste konstrueret ved hjælp af standardkonstruktøren

Det generelle format for koden er:

Listevisning (
  børn:  [
    ItemOne (),
    ItemTwo (),
    ItemThree (),
  ],
),

Normalt bør dette bruges sammen med et lille antal børn, da listen også konstruerer de usynlige elementer på listen, og en stor mængde elementer kan gøre dette ineffektivt.

ListView.builder ()

Builder () -konstruktøren konstruerer en gentagende liste over genstande. Konstruktøren tager to hovedparametre: En artikelKonto for antallet af elementer på listen og en artikelbygger til konstrueret hver listepost.

En liste konstrueret ved hjælp af bygherre () -konstruktøren

Det generelle format for koden er:

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

Listeposterne er konstrueret dovne, hvilket betyder, at kun et specifikt antal listeelementer er konstrueret, og når en bruger ruller fremad, ødelægges de tidligere.

Pænt trick: Da elementerne er indlæst doven og kun det nødvendige antal elementer er indlæst, har vi ikke virkelig brug for et elementCount som en obligatorisk parameter, og listen kan være uendelig.

ListView.builder (
  itemBuilder: (kontekst, position) {
    returkort (
      barn: polstring (
        polstring: const EdgeInsets.all (16.0),
        barn: Tekst (position.toString (), stil: TextStyle (fontSize: 22.0),),
      ),
    );
  },
),
En ListView uden parameteren itemCount

ListView.separated ()

I den separerede () konstruktør genererer vi en liste, og vi kan specificere separatoren mellem hvert element.

En ListView konstrueret ved hjælp af ListView.separated () konstruktøren

I det væsentlige konstruerer vi to sammenvævede lister: en som hovedliste, en som separatorliste.

Bemærk, at det uendelige antal, der er diskuteret i den tidligere konstruktør, ikke kan bruges her, og denne konstruktør håndhæver et elementCount.

Koden for denne type er:

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

Denne type liste giver dig mulighed for dynamisk at definere separatorer, have forskellige typer separatorer til forskellige typer elementer, tilføje eller fjerne separatorer efter behov osv.

Denne implementering kan også bruges til at indsætte andre typer elementer (for eksempel reklamer) let og uden nogen ændring af hovedlisten i midten af ​​listen.

Eksempel viser reklame, når positionen kan deles med 4

Bemærk: Separatorlistens længde er 1 mindre end artikellisten, da der ikke findes en separator efter det sidste element.

ListView.custom ()

Den brugerdefinerede () konstruktør, som navnet antyder, giver dig mulighed for at opbygge ListViews med brugerdefineret funktionalitet til, hvordan børnene på listen er bygget. Den vigtigste parameter, der kræves til dette, er et SliverChildDelegate, der bygger elementerne. Typerne af SliverChildDelegates er

  1. SliverChildListDelegate
  2. SliverChildBuilderDelegate

SliverChildListDelegate accepterer en direkte liste over børn, mens SliverChildBuiderDelegate accepterer en IndexedWidgetBuilder (builder-funktionen, vi bruger).

Du kan enten bruge eller underklasse disse til at opbygge dine egne delegater.

ListView.builder er i det væsentlige en ListView.custom med en SliverChildBuilderDelegate.

ListView-standardkonstruktøren opfører sig som en ListView.custom med en SliverChildListDelegate.

Nu hvor vi er færdige med typerne af ListViews, så lad os se på ScrollPhysics.

Udforskning af ScrollPhysics

For at kontrollere, hvordan rulling finder sted, indstiller vi fysikparameteren i ListView-konstruktøren. De forskellige fysiktyper er:

NeverScrollableScrollPhysics

NeverScrollableScrollPhysics gør listen ikke-rullbar. Brug dette til at deaktivere rulning af ListView fuldstændigt.

BouncingScrollPhysics

BouncingScrollPhysics returnerer listen, når listen slutter. En lignende effekt bruges på iOS.

ClampingScrollPhysics

Dette er den standard rullefysik, der bruges på Android. Listen stopper ved slutningen og giver en effekt, der angiver den.

FixedExtentScrollPhysics

Dette er lidt anderledes end de andre på denne liste i den forstand, at det kun fungerer med FixedExtendScrollControllere og lister, der bruger dem. Som et eksempel tager vi en ListWheelScrollView, der fremstiller en hjullignende liste.

FixedExtentScrollPhysics ruller kun til emner i stedet for enhver forskydning derimellem.

Koden til dette eksempel er utroligt enkel:

FixedExtentScrollController fixedExtentScrollController =
    ny FixedExtentScrollController ();
ListWheelScrollView (
  controller: fixedExtentScrollController,
  fysik: FixedExtentScrollPhysics (),
  børn: måneder af TheYear.map ((måned) {
    returkort (
        barn: række (
      børn:  [
        Udvidet (
            barn: polstring (
          polstring: const EdgeInsets.all (8.0),
          barn: tekst (
            måned,
            stil: TextStyle (fontSize: 18.0),
          ),
        )),
      ],
    ));
  }). ToList (),
  vareExtent: 60,0,
),

Et par ting mere at vide

Hvordan opbevares elementer, der bliver ødelagt i live på en liste?

Flutter indeholder en KeepAlive () widget, der holder et element i live, som ellers ville være ødelagt. På en liste indpakkes elementer som standard i en widget AutomaticKeepAlive.

AutomaticKeepAlives kan deaktiveres ved at indstille feltet addAutomaticKeepAlives til false. Dette er nyttigt i tilfælde, hvor elementerne ikke behøver at holdes i live eller til en tilpasset implementering af KeepAlive.

Hvorfor har min ListView plads mellem listen og den ydre widget?

Som standard har en ListView polstring mellem den og den ydre widget, for at fjerne den, indstil polstring til EdgeInsets.all (0.0).

Det er det for denne artikel! Jeg håber du nød det og efterlod et par klapper, hvis du gjorde det. Følg mig for flere Flutter-artikler og kommenter for alle feedback, du måtte have om denne artikel.

Nogle af mine andre artikler