Flutter:列表布局摘要

1.ListView实现列表布局(类似RecyclerView水平/垂直模式):

(1)实现列表布局:

方式1(推荐,适用大量item,动态创建item):

ListView.builder( //列表布局
  scrollDirection: Axis.vertical,  //(默认)vertical垂直排列,horizontal水平排列
  itemCount: 总个数,               //item总个数
  itemExtent: 高度值,             //item高度(vertical)或宽度(horizontal)
  itemBuilder: (BuildContext context, int index) { //列表滚动到index位置时,才构建此item
    return item布局;
  }
)

方式2(效果同方式2,item间添加分割线):

ListView.separated( //列表布局
  ... //省略其他相同属性
  itemCount: 总个数,               //item总个数
  itemBuilder: (BuildContext context, int index) { //列表滚动到index位置时,才构建此item
    return item布局;
  }
  separatorBuilder: (BuildContext context, int index) { //分割器构造器
    return Divider(color: Colors.black);  //Divider为分割线
  }
}

方式3(适用少量item):

ListView( //列表布局
  scrollDirection: Axis.vertical,  //(默认)vertical垂直排列,horizontal水平排列
  itemExtent: 高度值,              //item高度(vertical)或宽度(horizontal)
//prototypeItem: 高度值,           //效果等同itemExtent,与itemExtent互斥
  shrinkWrap: false,               //true时累加item总长度并设置ListView长度,(默认)false占用最大空间
  children: <Widget>[              //item布局列表,提前将所有item构建好
    ...
  ]
)

(2)监听滚动事件、滚动到指定位置:

//定义到State类全局变量
ScrollController scrollController = ScrollController();
...
//在initState方法中监听滚动事件
scrollController.addListener(() {
  //...处理滚动事件
});
...
//动画滚动到指定位置
scrollController.animateTo(指定位置, duration: Duration(milliseconds: 动画时长), curve: Curves.ease);  //curve为动画曲线
//跳转到指定位置
scrollController.jumpTo(指定位置);
...
//在dispose方法中释放,避免内存泄露
scrollController.dispose();

(3)监听滚动通知:

NotificationListener<ScrollNotification>(
    onNotification: (ScrollNotification notification) {
      double progress = notification.metrics.pixels / notification.metrics.maxScrollExtent;
      int rate = (progress * 100).toInt();  //实际进度值0-100
      return false;  //返回false
    },
    child: ListView.builder( //child内得有ListView
        ...
    )
)

2.AnimatedList实现列表布局(类似ListView,支持添加/删除):

(1)实现列表布局:

final listKey = GlobalKey<AnimatedListState>();  //定义全局状态
...
AnimatedList( //列表布局
  key: listKey,           //传入全局状态变量,添加/删除时用到
  initialItemCount: 总个数,
  itemBuilder: (          //构建item布局
    BuildContext context,
    int index,
    Animation<double> animation,
  ) {
//  return item布局;       //直接返回item布局,在添加时没有动效
    return FadeTransition( //使用动画类(此处为渐隐)包装item布局,在添加时有动效
      opacity: animation,
      child: ...,   //省略item布局
    );
  },
)

(2)添加/删除item:

//新增item
listKey.currentState!.insertItem(
        item的index,
        duration: Duration(milliseconds: 500)); //动画持续时间
...
//删除item
listKey.currentState!.removeItem(
  item的index,
  (context, animation) {   //删除动画实现
//  return item布局;       //直接返回item布局,在删除时没有动效
    return FadeTransition( //使用动画类(此处为渐隐+缩小)包装item布局,在删除时有动效
      opacity: animation,
      child: SizeTransition( //缩小删除item的高度
        sizeFactor: animation,
        axisAlignment: 0.0,
        child: item布局,
      ),
    );
  },
  duration: Duration(milliseconds: 500), //动画持续时间
);

3.GridView实现网格布局(类似Android的GridView)

(1)实现列表布局:

方式1(推荐,适用大量item,动态构建item):

GridView.builder(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 4,     //水平方向子元素个数
    childAspectRatio: 1.0, //子元素宽高比
  ),
  itemCount: 元素总个数,
  itemBuilder: (context, index) { //构建item布局,列表滚动到index位置时,才构建此item
    return item布局;
  }
)

方式2(指定子元素个数,适用少量item):

GridView(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      mainAxisSpacing: 10.0,   //垂直方向子元素的间距
      crossAxisSpacing: 10.0,  //水平方向子元素的间距
      crossAxisCount: 4,       //水平方向子元素个数
      childAspectRatio: 1.0    //子元素宽高比
  ),
  children: <Widget>[          //item布局列表,提前将所有item构建好
    ...
  ]
);

方式3(指定子元素个数,适用少量item):

GridView.count( 
  crossAxisCount: 4,       //水平方向子元素个数
  childAspectRatio: 1.0    //子元素宽高比
  children: <Widget>[      //item布局列表,提前将所有item构建好
    ...
  ]
);

方式4(指定子元素最大长度,适用少量item):

GridView(
  gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
      mainAxisSpacing: 10.0,    //垂直方向子元素的间距
      crossAxisSpacing: 10.0,   //水平方向子元素的间距
      maxCrossAxisExtent: 100.0,//子元素在水平方向最大长度
      childAspectRatio: 1.0     //子元素宽高比
  ),
  children: <Widget>[           //item布局列表,提前将所有item构建好
    ...
  ]
)

方式5(指定子元素最大长度,适用少量item):

GridView.extent(
  maxCrossAxisExtent: 100.0, //子元素在水平方向最大长度
  childAspectRatio: 1.0      //子元素宽高比
  children: <Widget>[        //item布局列表,提前将所有item构建好
    ...
  ]
)

4.CustomScrollView嵌套多个Sliver组件(滚动事件不冲突):

说明:

常见的非列表Sliver组件:
SliverAppBar(AppBar)、SliverToBoxAdapter、SliverPersistentHeader(滑动到顶部固定)

常见的列表Sliver组件:
SliverList(ListView)、
SliverFixedExtentList(ListView item高度固定)、SliverAnimatedList(添加/删除item时有动画)、SliverGrid、
SliverPrototypeExtentList(ListView指定prototypeItem)、SliverFillViewport(PageView)
CustomScrollView(
  slivers: [  //Sliver组件列表
    ...,  //Sliver组件1
    ...,  //Sliver组件2
  ]
)


5.NestedScrollView嵌套两个可滚动Widget(滚动事件不冲突):

NestedScrollView(
  headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
    return <Widget>[ //sliver组件列表,
      sliver组件(...)  //例如SliverAppBar
    ];
  },
  body: 列表组件,  //列表Widget,例如ListView
);

猜你喜欢

转载自blog.csdn.net/a526001650a/article/details/127391917