You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudsolutions-atoms/lib/common_widgets/stapper_widget/custom_stepper.dart

290 lines
9.4 KiB
Dart

library easy_stepper;
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'components/base_step.dart';
import 'components/custom_line.dart';
class CustomStepper extends StatefulWidget {
final List<StepModel> steps;
final OnStepReached onStepReached;
final Color unreachedStepBackgroundColor;
final Color unreachedStepTextColor;
final Color unreachedStepIconColor;
final Color unreachedStepBorderColor;
final BorderType unreachedStepBorderType;
final Color activeStepBackgroundColor;
final Color activeStepTextColor;
final Color activeStepIconColor;
final Color activeStepBorderColor;
final BorderType activeStepBorderType;
final Color finishedStepBackgroundColor;
final Color finishedStepBorderColor;
final Color finishedStepTextColor;
final Color finishedStepIconColor;
final BorderType finishedStepBorderType;
final double stepRadius;
final int activeStep;
final int maxReachedStep;
final Set<int> reachedSteps;
final AlignmentGeometry alignment;
final double internalPadding;
final EdgeInsetsGeometry padding;
final bool titlesAreLargerThanSteps;
final Curve stepAnimationCurve;
final Duration stepAnimationDuration;
final double borderThickness;
final StepShape stepShape;
final double stepBorderRadius;
final bool showStepBorder;
final bool showScrollbar;
final bool fitWidth;
final LineStyle lineStyle;
const CustomStepper({
Key key,
@required this.activeStep,
@required this.steps,
this.reachedSteps,
this.maxReachedStep,
this.onStepReached,
this.unreachedStepBackgroundColor,
this.unreachedStepTextColor,
this.unreachedStepIconColor,
this.unreachedStepBorderColor,
this.activeStepTextColor,
this.activeStepIconColor=AppColor.primary10,
this.activeStepBackgroundColor=AppColor.primary10,
this.activeStepBorderColor=AppColor.primary10,
this.finishedStepBackgroundColor=AppColor.primary10,
this.finishedStepBorderColor,
this.finishedStepIconColor,
this.stepRadius = 20,
this.alignment = Alignment.center,
this.fitWidth = true,
this.showScrollbar = false,
this.padding=EdgeInsetsDirectional.zero,
this.titlesAreLargerThanSteps = false,
this.internalPadding = 8,
this.stepAnimationCurve = Curves.linear,
this.stepAnimationDuration = const Duration(seconds: 1),
this.borderThickness = 1,
this.stepShape = StepShape.circle,
this.stepBorderRadius,
this.unreachedStepBorderType,
this.activeStepBorderType,
this.finishedStepBorderType,
this.showStepBorder = false,
this.lineStyle, this.finishedStepTextColor,
}) : assert(maxReachedStep == null || reachedSteps == null,
'only "maxReachedStep" or "reachedSteps" allowed'),
super(key: key);
@override
State<CustomStepper> createState() => _CustomStepperState();
}
class _CustomStepperState extends State<CustomStepper> {
ScrollController _scrollController;
int _selectedIndex;
LineStyle lineStyle;
EdgeInsetsGeometry _padding;
@override
void initState() {
lineStyle = widget.lineStyle ?? const LineStyle();
_selectedIndex = widget.activeStep;
_scrollController = ScrollController();
_padding = const EdgeInsetsDirectional.all(10);
if (widget.steps.any((element) => element.topTitle)) {
_padding = _padding.add(const EdgeInsetsDirectional.only(top: 45));
}
if (widget.titlesAreLargerThanSteps) {
_padding = _padding.add(EdgeInsetsDirectional.symmetric(
horizontal: lineStyle.lineLength / 2));
}
if (widget.padding != null) {
_padding.add(widget.padding);
}
super.initState();
}
@override
void didUpdateWidget(CustomStepper oldWidget) {
super.didUpdateWidget(oldWidget);
// Verify that the active step falls within a valid range.
if (widget.activeStep >= 0 && widget.activeStep < widget.steps.length) {
_selectedIndex = widget.activeStep;
}
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
/// Controls the step scrolling.
void _afterLayout(_) {
for (int i = 0; i < widget.steps.length; i++) {
_scrollController.animateTo(
i *
((widget.stepRadius * 2) +
widget.internalPadding +
lineStyle.lineLength),
duration: widget.stepAnimationDuration,
curve: widget.stepAnimationCurve,
);
if (_selectedIndex == i) break;
}
}
@override
Widget build(BuildContext context) {
lineStyle = widget.lineStyle ?? const LineStyle();
return Align(
alignment: widget.alignment,
child: NotificationListener<OverscrollIndicatorNotification>(
onNotification: (OverscrollIndicatorNotification overscroll) {
overscroll.disallowIndicator();
return false;
},
child: FittedBox(
fit: widget.fitWidth ? BoxFit.fitWidth : BoxFit.none,
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: _buildEasySteps(),
),
)
),
);
}
List<Widget> _buildEasySteps() {
return List.generate(widget.steps.length, (index) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_buildStep(index),
_buildLine(index, Axis.horizontal),
],
);
});
}
BaseStep _buildStep(int index) {
final step = widget.steps[index];
return BaseStep(
step: step,
radius: widget.stepRadius,
isActive: index == widget.activeStep,
isFinished: widget.reachedSteps != null
? index < widget.activeStep && widget.reachedSteps.contains(index)
: index < widget.activeStep,
isUnreached: index > widget.activeStep,
isAlreadyReached: widget.reachedSteps != null
? widget.reachedSteps.contains(index)
: widget.maxReachedStep != null
? index <= widget.maxReachedStep
: false,
activeStepBackgroundColor: widget.activeStepBackgroundColor,
activeStepBorderColor: widget.activeStepBorderColor,
activeTextColor: widget.activeStepTextColor,
activeIconColor: widget.activeStepIconColor,
unreachedBackgroundColor: widget.unreachedStepBackgroundColor,
unreachedBorderColor: widget.unreachedStepBorderColor,
unreachedTextColor: widget.unreachedStepTextColor,
unreachedIconColor: widget.unreachedStepIconColor,
padding: max(widget.internalPadding, 0),
stepRadius: widget.stepBorderRadius,
showStepBorder: widget.showStepBorder,
lineLength: lineStyle.lineLength,
enabled: widget.steps[index].enabled,
);
}
// BorderType _handleBorderType(int index) {
// if (index == widget.activeStep) {
// //Active Step
// return widget.activeStepBorderType ?? widget.defaultStepBorderType;
// } else if (index > widget.activeStep) {
// //Unreached Step
// return widget.unreachedStepBorderType ?? widget.defaultStepBorderType;
// } else if (index < widget.activeStep) {
// //Finished Step
// return widget.finishedStepBorderType ?? widget.defaultStepBorderType;
// } else {
// return widget.defaultStepBorderType;
// }
// }
Color _getLineColor(int index) {
Color preferredColor;
if (index == widget.activeStep) {
//Active Step
preferredColor = lineStyle.activeLineColor;
} else if (index > widget.activeStep) {
//Unreached Step
preferredColor = lineStyle.unreachedLineColor;
} else if (index < widget.activeStep) {
//Finished Step
preferredColor = lineStyle.finishedLineColor;
}
return preferredColor ??
lineStyle.defaultLineColor ??
Theme.of(context).colorScheme.primary;
}
Widget _buildLine(int index, Axis axis) {
return index < widget.steps.length - 1
? Column(
children: [
Padding(
padding: EdgeInsets.only(
top: axis == Axis.horizontal
? (widget.stepRadius - lineStyle.lineThickness)
: 0,
),
child: _buildBaseLine(index, axis),
),
if (axis == Axis.horizontal &&
widget.steps[index].lineText != null) ...[
const SizedBox(height: 5),
SizedBox(
width: lineStyle.lineLength,
child: widget.steps[index].customLineWidget ??
Text(
widget.steps[index].lineText,
maxLines: 3,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.labelSmall,
),
),
],
],
)
: const Offstage();
}
EasyLine _buildBaseLine(int index, Axis axis) {
return EasyLine(
length: lineStyle.lineLength,
color: _getLineColor(index),
thickness: lineStyle.lineThickness,
spacing: lineStyle.lineSpace,
width: lineStyle.lineWidth,
axis: axis,
lineType:
index > widget.activeStep - 1 && lineStyle.unreachedLineType != null
? lineStyle.unreachedLineType
: lineStyle.lineType,
);
}
}