Basically, I want to do like a progress bar as below.
The recording is taken straight from the code below.
This is my current solution :
two_pagination_progress.dart
BlocBuilder<TwoPaginationProgressCubit, TwoPaginationProgressState>
buildTwoPaginationProgress(double screenWidth) {
return BlocBuilder<TwoPaginationProgressCubit, TwoPaginationProgressState>(
builder: (cubit, context) => TwoPaginationProgress(
screenWidth: screenWidth,
leftSideLength:
cubit.read<TwoPaginationProgressCubit>().state.leftSideLength,
firstCircleLength:
cubit.read<TwoPaginationProgressCubit>().state.firstCircleLength,
firstCircleOpacity:
cubit.read<TwoPaginationProgressCubit>().state.firstCircleOpacity,
firstCircleNumber:
cubit.read<TwoPaginationProgressCubit>().state.firstCircleNumber,
firstCircleNumberSize:
cubit.read<TwoPaginationProgressCubit>().state.firstCircleNumberSize,
secondCircleLength:
cubit.read<TwoPaginationProgressCubit>().state.secondCircleLength,
secondCircleOpacity:
cubit.read<TwoPaginationProgressCubit>().state.secondCircleOpacity,
secondCircleNumber:
cubit.read<TwoPaginationProgressCubit>().state.secondCircleNumber,
secondCircleNumberSize:
cubit.read<TwoPaginationProgressCubit>().state.secondCircleNumberSize,
),
);
}
class TwoPaginationProgress extends StatelessWidget {
const TwoPaginationProgress({
Key? key,
// Others
required this.leftSideLength,
required this.screenWidth,
// First circle attributes
required this.firstCircleLength,
required this.firstCircleOpacity,
required this.firstCircleNumber,
required this.firstCircleNumberSize,
// Second circle attributes
required this.secondCircleOpacity,
required this.secondCircleLength,
required this.secondCircleNumber,
required this.secondCircleNumberSize,
}) : super(key: key);
final double leftSideLength;
final double screenWidth;
final double firstCircleLength;
final double firstCircleOpacity;
final int firstCircleNumber;
final double firstCircleNumberSize;
final double secondCircleLength;
final double secondCircleOpacity;
final int secondCircleNumber;
final double secondCircleNumberSize;
@override
Widget build(BuildContext context) {
return Row(
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 250),
width: leftSideLength,
height: screenWidth * 0.0845,
curve: Curves.easeOutExpo,
),
Row(
children: [
AnimatedOpacity(
opacity: firstCircleOpacity,
duration: const Duration(milliseconds: 250),
curve: Curves.easeOutExpo,
child: Material(
color: kcTertiaryColor,
borderRadius: BorderRadius.circular(100),
child: AnimatedContainer(
duration: const Duration(milliseconds: 250),
curve: Curves.easeOutExpo,
alignment: Alignment.center,
width: firstCircleLength,
height: firstCircleLength,
child: AnimatedDefaultTextStyle(
duration: const Duration(milliseconds: 250),
curve: Curves.easeOutExpo,
style: ktsHeadingParagraph.copyWith(
fontSize: firstCircleNumberSize,
color: Colors.black,
fontWeight: FontWeight.w700),
child: Text('$firstCircleNumber'),
),
),
),
),
horizontalSpaceTiny,
horizontalSpaceTiny,
AnimatedOpacity(
opacity: secondCircleOpacity,
duration: const Duration(milliseconds: 250),
curve: Curves.easeOutExpo,
child: Material(
color: kcTertiaryColor,
borderRadius: BorderRadius.circular(100),
child: AnimatedContainer(
duration: const Duration(milliseconds: 250),
curve: Curves.easeOutExpo,
alignment: Alignment.center,
width: secondCircleLength,
height: secondCircleLength,
child: AnimatedDefaultTextStyle(
duration: const Duration(milliseconds: 250),
curve: Curves.easeOutExpo,
style: ktsHeadingParagraph.copyWith(
fontSize: secondCircleNumberSize,
color: Colors.black,
fontWeight: FontWeight.w700),
child: Text('$secondCircleNumber'),
),
),
),
),
],
),
],
);
}
}
two_pagination_progress_cubit.dart
class TwoPaginationProgressCubit extends Cubit<TwoPaginationProgressState> {
final double screenWidth;
final double screenHeight;
TwoPaginationProgressCubit({
required this.screenHeight,
required this.screenWidth,
}) : super(TwoPaginationProgressState(
currentProgressIndex: 1,
screenHeight: screenHeight,
screenWidth: screenWidth,
halfScreen: screenWidth / 2,
leftSideLength: (screenWidth / 2) - (screenWidth * 0.0845 / 2),
firstCircleLength: screenWidth * 0.0845,
firstCircleOpacity: 1,
firstCircleNumber: 1,
firstCircleNumberSize: 16,
secondCircleLength: screenWidth * 0.0555,
secondCircleOpacity: 0.25,
secondCircleNumber: 2,
secondCircleNumberSize: 8,
));
void triggerFirstPage() {
emit(TwoPaginationProgressState(
currentProgressIndex: 1,
screenHeight: screenHeight,
screenWidth: screenWidth,
halfScreen: screenWidth / 2,
leftSideLength: (screenWidth / 2) - (screenWidth * 0.0845 / 2),
firstCircleLength: screenWidth * 0.0845,
firstCircleOpacity: 1,
firstCircleNumber: 1,
firstCircleNumberSize: 16,
secondCircleLength: screenWidth * 0.0555,
secondCircleOpacity: 0.25,
secondCircleNumber: 2,
secondCircleNumberSize: 8,
));
}
void triggerSecondPage() {
emit(TwoPaginationProgressState(
currentProgressIndex: 2,
screenHeight: screenHeight,
screenWidth: screenWidth,
halfScreen: screenWidth / 2,
leftSideLength: (screenWidth / 2) -
10 -
(screenWidth * 0.0845 / 2) -
(screenWidth * 0.0555),
firstCircleLength: screenWidth * 0.0555,
firstCircleOpacity: 0.25,
firstCircleNumber: 1,
firstCircleNumberSize: 8,
secondCircleLength: screenWidth * 0.0845,
secondCircleOpacity: 1,
secondCircleNumber: 2,
secondCircleNumberSize: 16,
));
}
}
The code works. But it I feel like I'm doing this very inefficiently. Is there a better way to do this?
Thanks in advance!
Edit: Here are some context on the little calculations I did >
Large Circle Length = screenWidth * 0.0845
Small Circle Length = screenWidth * 0.0555
horizontalSpaceTiny = 5 pixels
horizontalSpace10 = 10 pixels
