Flutter进度条展示插件primer_progress_bar的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter进度条展示插件primer_progress_bar的使用

插件简介

primer_progress_bar 是一个基于 GitHub Primer Design System 的非官方 Flutter 进度条实现。它提供了丰富的自定义选项,可以轻松地在应用程序中创建美观且功能强大的进度条。

版本信息

  • 最新版本: 0.4.0(要求Flutter SDK版本3.16.0或更高)
  • 旧版本: 如果您使用的是较旧的SDK,请使用版本0.3.0或更低版本。

安装

要使用 primer_progress_bar,请将以下内容添加到您的 pubspec.yaml 文件中:

dependencies:
  primer_progress_bar: ^0.4.0

或者,您可以直接通过命令行安装:

flutter pub add primer_progress_bar

使用示例

下面是一个完整的示例代码,展示了如何使用 primer_progress_bar 创建一个包含多个段落的进度条,并允许用户交互调整显示的段落数量、是否限制图例行数等。

示例代码

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:primer_progress_bar/primer_progress_bar.dart';

void main() {
  runApp(const MyApp());
}

final themeMode = ValueNotifier(Brightness.light);

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder(
      valueListenable: themeMode,
      builder: (context, brightness, _) {
        return MaterialApp(
          theme: ThemeData(
            useMaterial3: true,
            brightness: brightness,
          ),
          home: const Home(),
        );
      },
    );
  }
}

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

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final segments = const [
    Segment(
      color: Colors.green,
      value: 24,
      label: Text("Dart"),
      valueLabel: Text("24%"),
    ),
    Segment(
      color: Colors.lime,
      value: 11,
      label: Text("CSS"),
      valueLabel: Text("11%"),
    ),
    Segment(
      color: Colors.purple,
      value: 9,
      label: Text("HTML"),
      valueLabel: Text("9%"),
    ),
    Segment(
      color: Colors.lightBlue,
      value: 6,
      label: Text("Typescript"),
      valueLabel: Text("6%"),
    ),
    Segment(
      color: Colors.orange,
      value: 4,
      label: Text("Javascript"),
      valueLabel: Text("4%"),
    ),
    Segment(
      color: Colors.grey,
      value: 4,
      label: Text("Shell"),
      valueLabel: Text("4%"),
    ),
    Segment(
      color: Colors.indigo,
      value: 4,
      label: Text("Java"),
      valueLabel: Text("4%"),
    ),
    Segment(
      color: Colors.red,
      value: 4,
      label: Text("Objective-C"),
      valueLabel: Text("4%"),
    ),
    Segment(
      color: Colors.teal,
      value: 2,
      label: Text("Rust"),
      valueLabel: Text("2%"),
    ),
    Segment(
      color: Colors.brown,
      value: 2,
      label: Text("Swift"),
      valueLabel: Text("2%"),
    ),
  ];

  late final maxTotalValue = segments.fold(0, (acc, seg) => acc + seg.value);
  late int displaySegmentCount = segments.length ~/ 2;
  late double sliderValue = segments.length / 2;
  bool alwaysFillBar = false;
  bool limitLegendLines = false;

  @override
  Widget build(BuildContext context) {
    final progressBar = PrimerProgressBar(
      segments: segments.take(displaySegmentCount).toList(),
      maxTotalValue: alwaysFillBar ? null : maxTotalValue,
      legendStyle: limitLegendLines
          ? const SegmentedBarLegendStyle(maxLines: 2)
          : const SegmentedBarLegendStyle(maxLines: null),
      legendEllipsisBuilder: (truncatedItemCount) {
        final value = segments
            .skip(displaySegmentCount - truncatedItemCount)
            .take(truncatedItemCount)
            .fold(0, (accValue, segment) => accValue + segment.value);
        return LegendItem(
          segment: Segment(
            value: value,
            color: Colors.grey,
            label: const Text("Other"),
            valueLabel: Text("$value%"),
          ),
        );
      },
    );

    final options = [
      SwitchListTile(
        title: const Text("Dark Theme"),
        value: themeMode.value == Brightness.dark,
        onChanged: (turnedOn) {
          setState(() {
            themeMode.value = turnedOn ? Brightness.dark : Brightness.light;
          });
        },
      ),
      SwitchListTile(
        title: const Text("Always fill the entire bar"),
        value: alwaysFillBar,
        onChanged: (turnedOn) {
          setState(() => alwaysFillBar = turnedOn);
        },
      ),
      SwitchListTile(
        title: const Text("Limit the legend lines"),
        value: limitLegendLines,
        onChanged: (turnedOn) {
          setState(() => limitLegendLines = turnedOn);
        },
      ),
    ];

    final slider = SizedBox(
      height: 56,
      child: Slider(
        value: sliderValue,
        min: 0,
        max: segments.length.toDouble(),
        divisions: segments.length,
        label: "$displaySegmentCount segment(s)",
        onChanged: (value) {
          setState(() {
            sliderValue = value;
            displaySegmentCount = value.round();
          });
        },
      ),
    );

    final body = Padding(
      padding: const EdgeInsets.all(20),
      child: Column(
        children: [
          Expanded(
            child: Center(
              child: progressBar,
            ),
          ),
          ...options,
        ],
      ),
    );

    const minBodyHeight = 400.0;
    final bodyContainer = LayoutBuilder(
      builder: (context, constraints) {
        return SingleChildScrollView(
          child: ConstrainedBox(
            constraints: BoxConstraints(
              minHeight: minBodyHeight,
              maxHeight: max(constraints.maxHeight, minBodyHeight),
            ),
            child: body,
          ),
        );
      },
    );

    return Scaffold(
      appBar: AppBar(),
      extendBodyBehindAppBar: true,
      body: SafeArea(
        top: false,
        bottom: false,
        child: bodyContainer,
      ),
      bottomNavigationBar: BottomAppBar(
        child: slider,
      ),
    );
  }
}

关键特性

段落定义

每个段落由 Segment 类表示,包括颜色、值和标签:

Segment(
  color: Colors.green,
  value: 24,
  label: Text("Dart"),
  valueLabel: Text("24%"),
);

进度条配置

通过 PrimerProgressBar 小部件配置进度条,支持以下参数:

  • segments: 段落列表。
  • maxTotalValue: 总值,用于计算各段的比例,默认为所有段的值之和。
  • legendStyle: 图例样式,可限制图例行数。
  • legendEllipsisBuilder: 当图例超出限制时,生成“其他”项的回调函数。

样式定制

可以通过 SegmentedBarStyle, SegmentedBarLegendStyle, 和 LegendItemStyle 来定制进度条的外观。

总结

primer_progress_bar 提供了一个灵活且易于使用的API来创建复杂的进度条组件。无论是在简单的应用还是复杂的数据可视化场景中,它都能很好地满足需求。希望这个指南能帮助你快速上手并充分利用这个强大的工具!


更多关于Flutter进度条展示插件primer_progress_bar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter进度条展示插件primer_progress_bar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用primer_progress_bar插件来展示进度条的代码示例。

首先,确保你已经在你的pubspec.yaml文件中添加了primer_progress_bar依赖:

dependencies:
  flutter:
    sdk: flutter
  primer_progress_bar: ^最新版本号  # 请替换为当前最新版本号

然后,运行flutter pub get来安装依赖。

接下来,你可以在你的Flutter应用中使用PrimerProgressBar来展示进度条。以下是一个完整的示例,展示如何在一个页面中集成和使用PrimerProgressBar

import 'package:flutter/material.dart';
import 'package:primer_progress_bar/primer_progress_bar.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Primer Progress Bar Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ProgressBarScreen(),
    );
  }
}

class ProgressBarScreen extends StatefulWidget {
  @override
  _ProgressBarScreenState createState() => _ProgressBarScreenState();
}

class _ProgressBarScreenState extends State<ProgressBarScreen> with SingleTickerProviderStateMixin {
  double _progress = 0.0;

  @override
  void initState() {
    super.initState();
    // 模拟进度条更新
    _startProgress();
  }

  void _startProgress() {
    // 使用Timer模拟进度更新
    Timer.periodic(Duration(milliseconds: 100), (timer) {
      setState(() {
        if (_progress < 1.0) {
          _progress += 0.01;
        } else {
          timer.cancel();
        }
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Primer Progress Bar Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            PrimerProgressBar(
              progress: _progress,
              height: 20,
              width: MediaQuery.of(context).size.width * 0.8,
              backgroundColor: Colors.grey[300]!,
              progressColor: Colors.blue,
              borderRadius: BorderRadius.circular(10),
            ),
            SizedBox(height: 20),
            Text(
              'Progress: ${(_progress * 100).toInt()}%',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个Flutter应用,其中包含一个展示进度条的页面。我们使用PrimerProgressBar来显示进度,并通过一个定时器模拟进度条的更新。

  • PrimerProgressBar的参数包括:
    • progress:当前进度值(0.0到1.0之间)。
    • height:进度条的高度。
    • width:进度条的宽度。
    • backgroundColor:进度条的背景颜色。
    • progressColor:进度条的前景色(表示进度的部分)。
    • borderRadius:进度条的圆角半径。

你可以根据需要调整这些参数,以满足你的应用需求。

回到顶部