Flutter:步骤条组件
组件封装
import 'package:flutter/material.dart';class SubscribeStepWidget extends StatelessWidget {final List<Map<String, dynamic>> steps;final int current;final Axis axis;final Color? themeColor;const SubscribeStepWidget({Key? key,required this.steps,required this.current,this.axis = Axis.vertical, // 默认竖向this.themeColor,}) : super(key: key);@overrideWidget build(BuildContext context) {if (axis == Axis.horizontal) {// 横向略return Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: _buildHorizontalSteps(),);}// 竖向return Column(crossAxisAlignment: CrossAxisAlignment.start,children: _buildVerticalSteps(context),);}List<Widget> _buildVerticalSteps(BuildContext context) {final Color mainColor = themeColor ?? Colors.blue;List<Widget> widgets = [];for (int i = 0; i < steps.length; i++) {final step = steps[i];final isActive = i + 1 == current;final isFinished = i + 1 < current;widgets.add(IntrinsicHeight(child: Row(crossAxisAlignment: CrossAxisAlignment.start,children: [// 步骤圆圈和竖线Column(children: [Container(width: 20,height: 20,alignment: Alignment.center,decoration: BoxDecoration(color: isActive? mainColor: isFinished? mainColor.withOpacity(0.3): Colors.white,border: Border.all(color: isActive? mainColor: isFinished? mainColor.withOpacity(0.3): Colors.grey,width: 2,),shape: BoxShape.circle,),child: Center(child: isFinished? Icon(Icons.check, size: 16, color: Colors.white): Text('${step['index']}',style: TextStyle(color: isActive? Colors.white: isFinished? Colors.white: Colors.grey,fontWeight: FontWeight.bold,),),),),// 竖线自适应if (i != steps.length - 1)Expanded(child: Container(width: 2,color: isFinished || isActive? mainColor.withOpacity(0.3): Colors.grey[300],),),],),const SizedBox(width: 12),// 标题和内容Expanded(child: Container(padding: const EdgeInsets.only(bottom: 20),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text(step['title'] ?? '',style: TextStyle(fontSize: 16,fontWeight: isActive ? FontWeight.bold : FontWeight.normal,color: isActive? mainColor: Colors.black87,),),if (step['desc'] != null)Padding(padding: const EdgeInsets.only(top: 4, bottom: 8),child: Text(step['desc'],style: TextStyle(fontSize: 14,color: Colors.grey[600],),maxLines: 2,overflow: TextOverflow.ellipsis,),),if (step['time'] != null)Text(step['time'],style: TextStyle(fontSize: 12,color: Colors.grey[400],),),],),),),],),),);}return widgets;}// 横向略(如需可补充)List<Widget> _buildHorizontalSteps() => [];
}
调用
// 当前周期int current = 2;List<Map<String, dynamic>> timeList = [{'index': 1,'title': '项目预热','desc': '阶段1简介','time': '2025.03.20 22:25:26',},{'index': 2,'title': '开始申购','desc': '阶段2简介','time': '2025.03.20 22:25:26',},{'index': 3,'title': '结束申购','desc': '阶段3简介','time': '2025.03.20 22:25:26',},{'index': 4,'title': '公布结果','desc': '阶段4简介','time': '2025.03.20 22:25:26',},];SubscribeStepWidget(steps: controller.timeList,current: controller.current,axis: Axis.vertical, // 或 Axis.verticalthemeColor: AppTheme.colorGreen,
),