The basic information

ListView({Key Key, Axis scrollDirection: Axis. Vertical, // scrollDirection bool reverse:falseScrollController Controller, // controller bool Primary, ScrollPhysics, bool shrinkWrap:false, 
    EdgeInsetsGeometry padding, 
    double itemExtent, 
    bool addAutomaticKeepAlives: true, 
    bool addRepaintBoundaries: true, 
    bool addSemanticIndexes: true, 
    double cacheExtent, 
    List<Widget> children: const [], 
    int semanticChildCount, 
    DragStartBehavior dragStartBehavior: DragStartBehavior.start
})
Copy the code

When you create the ListView. Builder, you pass in two parameters, an initial length of the list, and an itemBuilder function. ListVIew also supports a sliver-based deferred build model.

Sliver-based delay build pattern: A scrollable component may have many children and occupy a large total height. Building all the children at once will cause poor performance. To this end, the concept of a Sliver is proposed in Flutter. The rolling component then splits the child component into slivers that are built only when the Sliver is in the viewport. This model is also known as the “sliver-based deferred build model”. There are many scrollable components that support sliver-based deferred build models, such as ListView and GridView, but there are also those that do not, such as SingleChildScrollView

Pull down the refresh indicator

RefreshIndicator({Key Key, @required Widget child, // width double Displacement: 40.0, // height @required RefreshCallback onRefresh, // RefreshCallback Color Color, // circle Color Color backgroundColor, / / background color ScrollNotificationPredicate notificationPredicate: DefaultScrollNotificationPredicate, String semanticsLabel, semantic text String semanticsValue})Copy the code

Pull down refresh and pull up load

import 'package:flutter/material.dart';

class TestList extends StatefulWidget {
  @override
  _TestListState createState() => _TestListState();
}

class _TestListState extends State<TestList> {
  final List<String> list = [];
  int page = 0;
  ScrollController _controller = ScrollController();

  @override
  void initState() { _getData(); _controller.addListener((){// The current position == the maximum sliding range, sliding to the bottomif(_controller.position.pixels == _controller.position.maxScrollExtent){
        if(page < 3){ _retrieveData(); }}}); super.initState(); } @override Widget build(BuildContext context) {return MaterialApp(
      title: 'Easy learning',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: Text('test'), body: RefreshIndicator(onRefresh: _onRefresh, //backgroundColor: color. red, //backgroundColor: Child: Listview. separated(controller: _controller, physics: separated) ItemBuilder: (BuildContext Context, int I){// List constructorif(i == list.length){
                if(page < 3){
                  return Container(
                    padding: EdgeInsets.only(top: 10, bottom: 10),
                    alignment: Alignment.center,
                    child: SizedBox(
                      child: CircularProgressIndicator(strokeWidth: 2,),
                      height: 20,
                      width: 20,
                    )
                  );
                } else {
                  return Container(
                    padding: EdgeInsets.only(top: 10, bottom: 10),
                     alignment: Alignment.center,
                    child: Text(
                      '~ I'm the bottom line ~', textAlign: TextAlign.center, style: TextStyle( color: Colors.blue, ) ), ); }}else {
                return ListTile(
                  title: Text('${list[i]}'),
                  leading: Icon(Icons.home),
                );
              }
            }, 
            separatorBuilder:(BuildContext context, int i){
              returnDivider(color: Colors.blue); }, itemCount: list.length+1)),); } void_getData() {for(var i= 0; i < 20; i++){
      list.insert(i, "The first${list.length}Strip raw data");
    }
  }

  Future<void> _onRefresh()async{
    await Future.delayed(Duration(seconds: 2)).then((e){ //
      setState(() {
        page = 0;
        list.clear();
        for(var i= 0; i < 20; i++){
          list.insert(i, "The first${list.length}Strip raw data"); }}); }); } Future<void> _retrieveData()async{ await Future.delayed(Duration(seconds: 2)).then((e){ //setState(() {
        page++;
        for(var i= 0; i < 20; i++){
          list.insert(list.length, "The first${list.length}Strip raw data"); }}); }); } @override voiddispose() { super.dispose(); }}Copy the code

Pull-down refresh, implemented in the onRefresh callback using the RefreshIndicator component, and pull-up load using the ScrollController to determine the scrollbar position

Note: Add an itemCount to fill loading.

A nested ListView cannot scroll

Slideable controls have these two properties, set these two parameters to the child slider, you can make the child ListView follow the parent ListView slide

ShrinkWrap: true, / / solve the problem of infinite high physics: NeverScrollableScrollPhysics (), / / disable sliding event

Refer to the link

A ListView can load a Flutter with a refresh and a pull-down

RefreshIndicator of Flutter pull-down