Flutter-ListView

387 阅读1分钟

Flutter-ListView

ListView普通构造

ListView(
   scrollDirection: Axis.vertical,//滚动方向
   reverse: true,//排版反转
   itemExtent: 100,//item的宽或者高滚动方向上item size
   // controller: ,
   // primary: ,//是否关联父类controller
   children: List.generate(100, (index){//该构造方法一次性创建出所有的item,不是需要的时候才创建,适用于少量的item时候
     return ListTile(
       leading: Icon(Icons.people),
       trailing: Icon(Icons.delete),
       title: Text("联系人${index + 1}"),
       subtitle: Text("联系人电话号码:18812345678"),
     );
   }),
 )

image-20221020112558620

推荐使用的构造模式

ListView.builder(//将要展示的时候才创建item
          itemCount: 100,
          itemBuilder: (BuildContext ctx, int index) {
            return Text("Hello World $index",style: TextStyle(fontSize: 20),);
          }),

image-20221020112526957

分割线模式

ListView.separated(//将要展示的时候才创建item
            itemCount: 100,
            // 传入回调函数,需要的时候会自动调用回调函数
            itemBuilder: (BuildContext ctx, int index) {
              return Text("Hello World $index",style: TextStyle(fontSize: 20),);
            },
          separatorBuilder: (BuildContext ctx ,int Index){
              // return Text("分割线");
            return Divider(color: Colors.red,thickness: 1,height: 20,);//线的颜色,线的高度,线的占据区域
          },
        )

image-20221020112438896

GridView默认构造方法

GridView(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  crossAxisCount: 3,//一行固定个数
  crossAxisSpacing: 10,//交叉轴方向item间隙
  mainAxisSpacing: 10,//主轴方向item的间隙
  childAspectRatio: 1.5,//宽高比 通过该参数确定高度
  ),
  children: List.generate(100, (index){
  return Container(color: Color.fromARGB(255, 
                                         Random().nextInt(256),
                                         Random().nextInt(256),
                                         Random().nextInt(256)),);
  }),
),

image-20221020113743526

GridView(
            // gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            //     crossAxisCount: 3,//一行固定个数
            //   crossAxisSpacing: 10,//交叉轴方向item间隙
            //     mainAxisSpacing: 10,//主轴方向item的间隙
            //     childAspectRatio: 1.5,//宽高比 通过该参数确定高度
            // ),
​
          gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(//不太好用
            maxCrossAxisExtent: 100, //item想要占据的范围
            crossAxisSpacing: 10, //交叉轴方向item间隙
            mainAxisSpacing: 10, //主轴方向item的间隙
          ),
          children: List.generate(100, (index){
              return Container(
                width: 168,
                color: Color.fromARGB(255, Random().nextInt(256),  Random().nextInt(256),  Random().nextInt(256)),);
            }),
          ),

image-20221020114404346

其他构造方法

GridView.count(//代理默认传了SliverGridDelegateWithFixedCrossAxisCount
              crossAxisCount: 3,
            )
          GridView.extent(//代理默认传了SliverGridDelegateWithMaxCrossAxisExtent
              maxCrossAxisExtent: 100
          )

推荐使用构造器

 GridView.builder(
   gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
   crossAxisCount: 3,
   crossAxisSpacing: 8,
   mainAxisSpacing: 8,
   childAspectRatio: 2),
   itemBuilder: (BuildContext ctx, int index) {
     return Container(
       width: 168,
       color: Color.fromARGB(255, Random().nextInt(256),
       Random().nextInt(256), Random().nextInt(256)),
      );
 }),

image-20221020115147022

Slivers

class ListView extends BoxScrollView
  abstract class BoxScrollView extends ScrollView
  abstract class ScrollView extends StatelessWidget
  
  SafeArea(//永不侵犯的安全边界,刘海屏位置不显示东西
              child: CustomScrollView(
                slivers: [
                  SliverSafeArea(//刘海屏显示内容,但是默认不会显示到安全区域内
                      sliver: SliverPadding(//四周的padding可以被推上去
                        padding: EdgeInsets.all(8),
                        sliver: SliverGrid(
                        delegate: SliverChildBuilderDelegate(
                          (BuildContext ctx, int index) {
                            return Container(
                              width: 168,
                              color: Color.fromARGB(255, Random().nextInt(256),
                                  Random().nextInt(256), Random().nextInt(256)),
                            );
                          },
                          childCount: 100,
                        ),
                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 2,
                          mainAxisSpacing: 8,
                          crossAxisSpacing: 8,
                          childAspectRatio: 2
                        )),
                  ))
                ],
              ),
            )

image-20221020194841691

多个SliverView

 CustomScrollView(
              slivers: [
                SliverAppBar(//appBar
                  title: Text("sliverBar"),
                  pinned: true,
                  leading: Icon(Icons.backup),
                  expandedHeight: 100,
                  flexibleSpace: FlexibleSpaceBar(
                    title: Text("hello"),
                  ),
                ),
                SliverGrid(delegate: SliverChildBuilderDelegate(
                    (BuildContext ctx,int index){
                      return Container(
                        width: 168,
                        color: Color.fromARGB(255, Random().nextInt(256),
                            Random().nextInt(256), Random().nextInt(256)),
                      );
                    },
                  childCount: 3,
                ), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 3,
                )),
                SliverList(delegate: SliverChildBuilderDelegate(
                        (BuildContext ctx, int index){
                      return ListTile(
                        leading: Icon(Icons.people),
                        title: Text("联系人$index"),
​
                      );
                    }
                )
​
                ),
              ],
            )

​​

监听滚动---controller方式

controller:可以设置默认offset ;2.监听滚动,也可以监听滚动的位置但是不能监开始滚动
//初始偏移量 在stateFulWiget
ScrollController controller = ScrollController(initialScrollOffset: 100);
void initState() {
    // TODO: implement initState
    super.initState();
    controller.addListener(() {
      print("监听到滚到。。。${controller.offset}");
    }); //监听
  }
ListView.builder(
  controller: controller,///这里就是controller
  itemCount: 20,
  itemBuilder: (BuildContext ctx,int index){
    return ListTile(
      leading: const Icon(Icons.people),
      title: Text("联系人 $index"),
    );
  })
@override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    controller.dispose();//销毁controller
  }

image-20221020224948236

NotificationListener

NotificationListener(//会冒泡
  child:  ListView.builder(
      controller: controller,///这里就是controller
      itemCount: 20,
      itemBuilder: (BuildContext ctx,int index){
        return ListTile(
          leading: const Icon(Icons.people),
          title: Text("联系人 $index"),
        );
      }),
  onNotification: ( ScrollNotification notification){
    print(notification);
    if(notification is ScrollStartNotification){
      print("开始滚动");
    }else  if(notification is ScrollUpdateNotification){
      print("正在滚动,当前滚动位置:${notification.metrics.pixels};总滚动距离:${notification.metrics.maxScrollExtent}");
    }else  if(notification is ScrollEndNotification){
      print("结束滚动");
    }
    return false;//阻止冒泡
  },
)

image-20221020225923111