0
点赞
收藏
分享

微信扫一扫

Flutter之ListView使用【二】

CustomScrollView 解决多 ListView 嵌套问题

Flutter 通过 CustomScrollView 解决多 ListView 嵌套时滑动效果不一致的问题。CustomScrollView 将多个独立的可滚动 Widget(称为 Sliver)统一管理,确保滚动状态一致。

  • SliverList 替代 ListViewSliverAppBar 替代 AppBar,所有 Sliver 的滚动状态由 CustomScrollView 统一协调。
  • CustomScrollViewslivers 参数接收一个 Sliver 列表,按顺序处理它们的布局和滚动逻辑。

实现视差滚动效果

视差滚动通过 SliverAppBarSliverList 联动实现,背景和列表以不同速度滚动。

CustomScrollView(
  slivers: <Widget>[
    SliverAppBar(
      title: Text('视差滚动示例'),
      floating: true,
      flexibleSpace: Image.network("https://xx.jpg", fit: BoxFit.cover),
      expandedHeight: 300,
    ),
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) => ListTile(title: Text('条目 $index')),
        childCount: 100,
      ),
    ),
  ],
);

使用 ScrollController 控制滚动

ScrollController 用于监听滚动位置和控制滚动行为,例如返回列表顶部。

class MyAppState extends State<MyApp> {
  ScrollController _controller;
  bool showTopButton = false;

  @override
  void initState() {
    _controller = ScrollController();
    _controller.addListener(() {
      setState(() {
        showTopButton = _controller.offset > 1000;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          ElevatedButton(
            onPressed: showTopButton
                ? () => _controller.animateTo(0, duration: Duration(milliseconds: 200), curve: Curves.ease)
                : null,
            child: Text('返回顶部'),
          ),
          Expanded(
            child: ListView.builder(
              controller: _controller,
              itemCount: 100,
              itemBuilder: (context, index) => ListTile(title: Text('索引: $index')),
            ),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

监听滚动事件

通过 NotificationListener 监听滚动开始、更新和结束事件。

NotificationListener<ScrollNotification>(
  onNotification: (notification) {
    if (notification is ScrollStartNotification) {
      print('滚动开始');
    } else if (notification is ScrollUpdateNotification) {
      print('滚动更新');
    } else if (notification is ScrollEndNotification) {
      print('滚动结束');
    }
    return true;
  },
  child: ListView.builder(
    itemCount: 100,
    itemBuilder: (context, index) => ListTile(title: Text('条目 $index')),
  ),
);

关键点总结

  • 统一管理滚动状态CustomScrollView 确保多个 Sliver 的滚动效果同步。
  • 视差滚动实现SliverAppBarSliverList 联动,通过 flexibleSpace 设置背景图。
  • 精确滚动控制ScrollController 用于监听位置和触发滚动动画。
  • 事件通知机制NotificationListener 捕获滚动事件,实现更复杂的交互逻辑。
举报

相关推荐

0 条评论