You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:如何在含SliverList的CustomScrollView中添加CupertinoActivityIndicator

实现Cupertino风格的加载态与列表切换

我来帮你把这个功能补全,让加载指示器和列表内容能在CupertinoSliverNavigationBar下方正确切换显示。首先得注意几个关键点:用状态类管理加载状态、在异步请求完成后更新UI、适配CustomScrollView的sliver组件结构。

完整实现代码

import 'package:flutter/cupertino.dart';

class Trade {
  // 这里定义你的Trade模型字段,比如id、name等
  final String id;
  final String name;

  Trade({required this.id, required this.name});
}

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

  @override
  State<TradeListPage> createState() => _TradeListPageState();
}

class _TradeListPageState extends State<TradeListPage> {
  List<Trade> trades = [];
  bool _isLoading = true; // 单独维护加载状态,比只靠列表长度更严谨

  @override
  void initState() {
    super.initState();
    // 初始化时触发数据加载
    _fetchTrades();
  }

  // 模拟异步数据请求
  Future<void> _fetchTrades() async {
    try {
      // 这里替换成你的真实API请求逻辑
      await Future.delayed(const Duration(seconds: 2));
      // 模拟获取到的数据
      setState(() {
        trades = [
          Trade(id: '1', name: '交易1'),
          Trade(id: '2', name: '交易2'),
          Trade(id: '3', name: '交易3'),
        ];
        _isLoading = false;
      });
    } catch (e) {
      // 处理请求失败的情况
      setState(() {
        _isLoading = false;
      });
      // 可以在这里显示错误提示
      showCupertinoDialog(
        context: context,
        builder: (context) => CupertinoAlertDialog(
          title: const Text('加载失败'),
          content: const Text('无法获取交易数据,请稍后重试'),
          actions: [
            CupertinoDialogAction(
              child: const Text('确定'),
              onPressed: () => Navigator.pop(context),
            )
          ],
        ),
      );
    }
  }

  // 构建加载指示器的sliver组件
  Widget _getProgressDialog() {
    return const SliverFillRemaining(
      child: Center(
        child: CupertinoActivityIndicator(radius: 16),
      ),
    );
  }

  // 构建交易列表的sliver组件
  Widget _getTradeItemList() {
    return SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) {
          final trade = trades[index];
          return CupertinoListTile(
            title: Text(trade.name),
            subtitle: Text('ID: ${trade.id}'),
            trailing: const CupertinoListTileChevron(),
          );
        },
        childCount: trades.length,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      child: CustomScrollView(
        slivers: [
          // 顶部导航栏
          const CupertinoSliverNavigationBar(
            largeTitle: Text('交易列表'),
          ),
          // 根据加载状态切换显示内容
          _isLoading ? _getProgressDialog() : _getTradeItemList(),
        ],
      ),
    );
  }
}

关键说明

  • 状态管理:用_isLoading布尔值单独控制加载状态,避免因列表为空(比如请求失败)导致一直显示加载指示器的问题。
  • 异步加载:在initState里触发数据请求,请求完成后通过setState更新UI,触发组件重建。
  • Sliver组件适配:加载指示器用SliverFillRemaining包裹,确保在列表为空时能居中显示;列表用SliverList,和CupertinoSliverNavigationBar一起放在CustomScrollView的slivers数组中,保持Cupertino风格的滚动连贯性。
  • 错误处理:添加了请求失败的弹窗提示,提升用户体验。

你可以根据自己的实际需求,替换_fetchTrades里的模拟请求为真实的API调用,调整Trade模型和列表项的UI样式。

内容的提问来源于stack exchange,提问作者Simon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:56:37