110 lines
3.5 KiB
Dart
110 lines
3.5 KiB
Dart
|
import 'package:flutter/material.dart';
|
||
|
import 'package:intl/intl.dart';
|
||
|
|
||
|
class QuestionSliderWidget extends StatefulWidget {
|
||
|
final DateTime date;
|
||
|
final String questionText;
|
||
|
final double initialSliderValue;
|
||
|
final bool isSliderEnabled;
|
||
|
final ValueChanged<double> onSliderChanged;
|
||
|
|
||
|
QuestionSliderWidget({
|
||
|
Key? key,
|
||
|
required this.date,
|
||
|
required this.questionText,
|
||
|
required this.initialSliderValue,
|
||
|
required this.isSliderEnabled,
|
||
|
required this.onSliderChanged,
|
||
|
}) : super(key: key);
|
||
|
|
||
|
@override
|
||
|
_QuestionSliderWidgetState createState() => _QuestionSliderWidgetState();
|
||
|
}
|
||
|
|
||
|
class _QuestionSliderWidgetState extends State<QuestionSliderWidget> {
|
||
|
late double _sliderValue;
|
||
|
bool _sliderChanged = false;
|
||
|
|
||
|
@override
|
||
|
void initState() {
|
||
|
super.initState();
|
||
|
_sliderValue = widget.initialSliderValue;
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return Padding(
|
||
|
padding: const EdgeInsets.fromLTRB(25, 175, 25, 25),
|
||
|
child: Column(
|
||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||
|
children: <Widget>[
|
||
|
// Date
|
||
|
Text(
|
||
|
DateFormat('dd MM yyyy').format(widget.date),
|
||
|
style: TextStyle(fontSize: 18),
|
||
|
),
|
||
|
SizedBox(height: 10),
|
||
|
// Text prompt
|
||
|
Text(
|
||
|
widget.questionText,
|
||
|
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
|
||
|
),
|
||
|
SizedBox(height: 32),
|
||
|
// Slider and label
|
||
|
SliderTheme(
|
||
|
data: SliderTheme.of(context).copyWith(
|
||
|
disabledThumbColor: Colors.amber,
|
||
|
activeTrackColor: Colors.black,
|
||
|
trackShape: RectangularSliderTrackShape(),
|
||
|
inactiveTickMarkColor: Colors.red,
|
||
|
inactiveTrackColor: Colors.transparent,
|
||
|
valueIndicatorColor: Colors.purple,
|
||
|
overlayColor: Colors.transparent,
|
||
|
activeTickMarkColor: Colors.red,
|
||
|
showValueIndicator: ShowValueIndicator.always,
|
||
|
trackHeight: 2,
|
||
|
thumbColor: Colors.transparent,
|
||
|
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 0.0),
|
||
|
rangeThumbShape: RoundRangeSliderThumbShape(
|
||
|
disabledThumbRadius: 0, enabledThumbRadius: 0, elevation: 22),
|
||
|
),
|
||
|
child: Stack(
|
||
|
alignment: Alignment.centerLeft,
|
||
|
children: [
|
||
|
Slider(
|
||
|
min: 0.0,
|
||
|
max: 100.0,
|
||
|
value: _sliderValue,
|
||
|
onChanged: widget.isSliderEnabled
|
||
|
? (value) {
|
||
|
setState(() {
|
||
|
_sliderValue = value;
|
||
|
_sliderChanged = true;
|
||
|
});
|
||
|
widget.onSliderChanged(value);
|
||
|
}
|
||
|
: null,
|
||
|
),
|
||
|
Positioned(
|
||
|
left: _calculateSliderPosition(context, _sliderValue),
|
||
|
child: Text(
|
||
|
"${_sliderValue.toStringAsFixed(0)}%",
|
||
|
style: TextStyle(fontSize: 20), // Size increased by 2
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
double _calculateSliderPosition(BuildContext context, double value) {
|
||
|
double sliderWidth =
|
||
|
MediaQuery.of(context).size.width - 50; // Width minus padding
|
||
|
double thumbWidth = 48; // Estimate of the thumb width
|
||
|
return (sliderWidth - thumbWidth) * value / 100.0 + thumbWidth / 2;
|
||
|
}
|
||
|
}
|