现在位置: 首页 > Flutter 教程 > 正文

Flutter ListView 与滚动

ListView 是 Flutter 中最常用的滚动列表 Widget,用于显示可滚动的内容列表。


ListView 基本用法

实例:ListView 基本用法

// 方式1:children 参数(适用于少量项目)
ListView(
  children: [
    ListTile(title: Text('第一项')),
    ListTile(title: Text('第二项')),
    ListTile(title: Text('第三项')),
  ],
)

// 方式2:ListView.builder(适用于大量或无限列表)
ListView.builder(
  itemCount: 100,
  itemBuilder: (context, index) {
    return ListTile(title: Text('第 ${index + 1} 项'));
  },
)

// 方式3:ListView.separated(带分隔符)
ListView.separated(
  itemCount: 10,
  separatorBuilder: (context, index) => const Divider(),  // 分隔线
  itemBuilder: (context, index) {
    return ListTile(title: Text('第 ${index + 1} 项'));
  },
)

ListView 常用属性

属性说明
scrollDirection滚动方向,默认为 Axis.vertical(垂直)
reverse是否反向滚动
padding列表内边距
itemExtent固定项目高度,可提升性能
prototypeItem原型项目,用于计算高度

实例:横向 ListView

// 横向滚动列表
SizedBox(
  height: 120,  // 必须设置高度
  child: ListView.builder(
    scrollDirection: Axis.horizontal,  // 横向滚动
    itemCount: 20,
    itemBuilder: (context, index) {
      return Container(
        width: 100,
        margin: const EdgeInsets.symmetric(horizontal: 8),
        color: Colors.blue[100],
        child: Center(
          child: Text('项 $index'),
        ),
      );
    },
  ),
)

GridView - 网格布局

GridView 用于创建二维网格列表。

实例:GridView 用法

// GridView.count - 固定列数
GridView.count(
  crossAxisCount: 3,  // 3 列
  children: List.generate(20, (index) {
    return Container(
      margin: const EdgeInsets.all(4),
      color: Colors.blue[100],
      child: Center(child: Text('${index + 1}')),
    );
  }),
)

// GridView.builder - 动态构建
GridView.builder(
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 4,  // 4 列
    mainAxisSpacing: 8,  // 垂直间距
    crossAxisSpacing: 8,  // 水平间距
    childAspectRatio: 1,  // 宽高比
  ),
  itemCount: 50,
  itemBuilder: (context, index) {
    return Container(
      color: Colors.green[100],
      child: Center(child: Text('${index + 1}')),
    );
  },
)

// GridView.extent - 自适应列数
GridView.extent(
  maxCrossAxisExtent: 150,  // 最大列宽
  children: List.generate(20, (index) {
    return Container(
      margin: const EdgeInsets.all(4),
      color: Colors.orange[100],
      child: Center(child: Text('${index + 1}')),
    );
  }),
)

滚动控制

使用 ScrollController 可以控制滚动位置。

实例:滚动控制

class ScrollExample extends StatefulWidget {
  const ScrollExample({super.key});

  @override
  State<ScrollExample> createState() => _ScrollExampleState();
}

class _ScrollExampleState extends State<ScrollExample> {
  // 创建滚动控制器
  late ScrollController _controller;

  @override
  void initState() {
    super.initState();
    _controller = ScrollController();
    // 监听滚动事件
    _controller.addListener(() {
      print('滚动位置: ${_controller.offset}');
    });
  }

  @override
  void dispose() {
    // 销毁控制器
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 滚动到顶部按钮
        ElevatedButton(
          onPressed: () {
            // 滚动到顶部
            _controller.animateTo(
              0,
              duration: const Duration(milliseconds: 500),
              curve: Curves.easeInOut,
            );
          },
          child: const Text('滚动到顶部'),
        ),
        // 列表
        Expanded(
          child: ListView.builder(
            controller: _controller,  // 绑定控制器
            itemCount: 100,
            itemBuilder: (context, index) {
              return ListTile(title: Text('第 ${index + 1} 项'));
            },
          ),
        ),
      ],
    );
  }
}

Slivers 高级滚动

CustomScrollView 配合 Slivers 可以实现更复杂的滚动效果。

实例:Slivers 实现折叠效果

// 带折叠应用栏的滚动视图
CustomScrollView(
  slivers: [
    // 折叠应用栏
    SliverAppBar(
      expandedHeight: 200,  // 展开高度
      pinned: true,  // 固定在顶部
      flexibleSpace: FlexibleSpaceBar(
        title: const Text('折叠标题'),
        background: Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: [Colors.blue, Colors.purple],
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
            ),
          ),
        ),
      ),
    ),
    // 列表内容
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) => ListTile(title: Text('第 ${index + 1} 项')),
        childCount: 30,
      ),
    ),
  ],
)

// 网格 Sliver
CustomScrollView(
  slivers: [
    const SliverAppBar(
      title: Text('图片网格'),
      pinned: true,
    ),
    SliverGrid(
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      delegate: SliverChildBuilderDelegate(
        (context, index) => Card(
          child: Image.network('https://picsum.photos/200?$index'),
        ),
        childCount: 20,
      ),
    ),
  ],
)

Slivers 提供了一种高效的方式来处理大量滚动项目,它们只渲染可见区域的项目,从而提供良好的性能。