Flutter | CircularProgressIndicator 与 LinearProgressIndicator

CircularProgressIndicator 是什么?

CircularProgressIndicator 是 Flutter 提供的一个圆形进度指示器组件,用于显示加载状态或任务进度。它有两种模式:

  1. 不确定模式(Indeterminate):持续旋转的圆圈,表示正在加载但不知道具体进度
  2. 确定模式(Determinate):显示具体进度百分比的圆圈

基本用法

// 1. 不确定模式 - 持续旋转
CircularProgressIndicator()

// 2. 确定模式 - 显示具体进度(0.0 到 1.0)
CircularProgressIndicator(
  value: 0.5,  // 50% 进度
)

// 3. 自定义样式
CircularProgressIndicator(
  value: 0.7,
  backgroundColor: Colors.grey[200],  // 背景色
  valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),  // 进度条颜色
  strokeWidth: 6.0,  // 线条粗细
)

在你的项目中的应用场景

看了你的代码,我发现你的项目目前使用的是 LinearProgressIndicator(线性进度条)来显示页面加载进度。让我展示几个可以使用 CircularProgressIndicator 的场景:

场景 1:在 WebView 加载时显示居中的圆形加载指示器

// 在 browser_screen.dart 中
Expanded(
  child: Stack(
    children: [
      WebViewWidget(controller: _controller),
      
      // 添加圆形加载指示器
      Consumer<BrowserProvider>(
        builder: (context, provider, child) {
          return provider.isLoading
              ? Center(
                  child: CircularProgressIndicator(
                    value: provider.progress,  // 显示具体进度
                    backgroundColor: Colors.grey[200],
                    strokeWidth: 4.0,
                  ),
                )
              : const SizedBox.shrink();
        },
      ),
    ],
  ),
),

场景 2:在历史记录或书签加载时显示

// 在 history_screen.dart 或 bookmarks_screen.dart 中
Consumer<BrowserProvider>(
  builder: (context, provider, child) {
    if (provider.history.isEmpty) {
      return Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CircularProgressIndicator(),  // 加载中
            SizedBox(height: 16),
            Text('加载历史记录...'),
          ],
        ),
      );
    }
    
    return ListView.builder(
      itemCount: provider.history.length,
      itemBuilder: (context, index) {
        // 显示历史记录项
      },
    );
  },
)

场景 3:创建一个带进度百分比的自定义加载组件

// 可以在 lib/widgets/ 下创建一个新的组件
class CircularLoadingIndicator extends StatelessWidget {
  final double progress;
  final bool showPercentage;

  const CircularLoadingIndicator({
    super.key,
    required this.progress,
    this.showPercentage = true,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withValues(alpha: 0.1),
            blurRadius: 10,
          ),
        ],
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          SizedBox(
            width: 60,
            height: 60,
            child: Stack(
              alignment: Alignment.center,
              children: [
                CircularProgressIndicator(
                  value: progress,
                  strokeWidth: 6,
                  backgroundColor: Colors.grey[200],
                  valueColor: AlwaysStoppedAnimation<Color>(
                    Theme.of(context).primaryColor,
                  ),
                ),
                if (showPercentage)
                  Text(
                    '${(progress * 100).toInt()}%',
                    style: TextStyle(
                      fontSize: 14,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
              ],
            ),
          ),
          const SizedBox(height: 12),
          Text(
            '加载中...',
            style: TextStyle(
              fontSize: 12,
              color: Colors.grey[600],
            ),
          ),
        ],
      ),
    );
  }
}

对比:LinearProgressIndicator vs CircularProgressIndicator

你的项目目前使用的是 LinearProgressIndicator

// 当前代码(browser_screen.dart)
LinearProgressIndicator(
  value: provider.progress,
  minHeight: 2,
)

两者的区别:

特性 LinearProgressIndicator CircularProgressIndicator
形状 水平线条 圆形
占用空间 宽度占满,高度很小 固定尺寸的正方形区域
适用场景 页面顶部进度条 页面中央加载提示
视觉效果 不干扰内容,轻量 更明显,适合等待场景

常用属性总结

CircularProgressIndicator(
  value: 0.5,                    // 进度值(null 为不确定模式)
  backgroundColor: Colors.grey,   // 背景圆圈颜色
  valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),  // 进度颜色
  strokeWidth: 4.0,              // 线条粗细
  semanticsLabel: '加载中',       // 无障碍标签
  semanticsValue: '50%',         // 无障碍进度值
)

建议

对于你的浏览器项目:

  1. 保留顶部的 LinearProgressIndicator - 它很适合显示页面加载进度,不会遮挡内容
  2. 在首次加载或网络慢时添加 CircularProgressIndicator - 在 WebView 中央显示,给用户更明确的加载反馈
  3. 在历史记录/书签页面使用 - 如果数据加载需要时间,可以显示圆形加载指示器

需要我帮你在项目中实现某个具体的场景吗?

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容