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

Flutter动态进度条开发:实现带可点击图标的周进度样式

Flutter 实现可交互周进度条组件

1. 定义数据模型

先创建对应后端返回数据的模型类,方便数据解析和使用:

class WeekProgress {
  final int weekNumber;
  final double progress; // 0-1之间的数值,代表进度百分比
  final IconData icon;
  final bool isClickable;

  WeekProgress({
    required this.weekNumber,
    required this.progress,
    required this.icon,
    required this.isClickable,
  });

  // 从后端JSON转模型的方法
  factory WeekProgress.fromJson(Map<String, dynamic> json) {
    return WeekProgress(
      weekNumber: json['weekNumber'],
      progress: json['progress'].toDouble(),
      icon: IconData(json['iconCode'], fontFamily: 'MaterialIcons'),
      isClickable: json['isClickable'],
    );
  }
}

2. 构建可交互进度条组件

核心组件包含每个周的进度块,图标支持点击:

class WeeklyProgressBar extends StatelessWidget {
  final List<WeekProgress> weeklyData;
  final Function(int weekNumber) onIconTap;

  const WeeklyProgressBar({
    super.key,
    required this.weeklyData,
    required this.onIconTap,
  });

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 80,
      child: ListView.separated(
        scrollDirection: Axis.horizontal,
        padding: const EdgeInsets.symmetric(horizontal: 16),
        itemCount: weeklyData.length,
        separatorBuilder: (context, index) => const SizedBox(width: 12),
        itemBuilder: (context, index) {
          final week = weeklyData[index];
          return _WeekProgressItem(
            week: week,
            onTap: week.isClickable ? () => onIconTap(week.weekNumber) : null,
          );
        },
      ),
    );
  }
}

class _WeekProgressItem extends StatelessWidget {
  final WeekProgress week;
  final VoidCallback? onTap;

  const _WeekProgressItem({
    required this.week,
    this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 可点击图标
        GestureDetector(
          onTap: onTap,
          child: Icon(
            week.icon,
            size: 32,
            color: onTap != null ? Colors.blue : Colors.grey,
          ),
        ),
        const SizedBox(height: 8),
        // 进度条容器
        SizedBox(
          width: 40,
          child: Column(
            children: [
              Text('Week ${week.weekNumber}'),
              const SizedBox(height: 4),
              LinearProgressIndicator(
                value: week.progress,
                minHeight: 6,
                borderRadius: BorderRadius.circular(3),
              ),
            ],
          ),
        ),
      ],
    );
  }
}

3. 集成后端数据与使用组件

通过FutureBuilder获取后端数据并渲染组件:

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

  @override
  State<ProgressScreen> createState() => _ProgressScreenState();
}

class _ProgressScreenState extends State<ProgressScreen> {
  Future<List<WeekProgress>> _fetchWeeklyData() async {
    // 替换为你的后端API请求逻辑
    final response = await http.get(Uri.parse('your-backend-api-url'));
    if (response.statusCode == 200) {
      List<dynamic> data = jsonDecode(response.body);
      return data.map((item) => WeekProgress.fromJson(item)).toList();
    } else {
      throw Exception('Failed to load weekly data');
    }
  }

  void _handleIconTap(int weekNumber) {
    // 处理图标点击逻辑,比如跳转详情页、弹出提示等
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('Week $weekNumber icon tapped')),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Weekly Progress')),
      body: FutureBuilder<List<WeekProgress>>(
        future: _fetchWeeklyData(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          } else if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}'));
          } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
            return const Center(child: Text('No data available'));
          } else {
            return Column(
              children: [
                WeeklyProgressBar(
                  weeklyData: snapshot.data!,
                  onIconTap: _handleIconTap,
                ),
                // 其他页面内容
              ],
            );
          }
        },
      ),
    );
  }
}

关键说明

  • 图标交互:通过GestureDetector控制点击事件,只有isClickable为true时才响应点击,同时用颜色区分可点击状态。
  • 进度条适配:使用LinearProgressIndicator实现基础进度条,可根据需求自定义样式(比如颜色、高度)。
  • 后端集成:_fetchWeeklyData方法需替换成实际的API请求,确保返回数据能正确解析为WeekProgress模型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:40:30