Merge pull request 'Callambulance page text and map changes' (#211) from maptype into master
Reviewed-on: https://34.17.182.140/Haroon6138/HMG_Patient_App_New/pulls/211dev_aamir
commit
59fc109454
@ -1,63 +1,263 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hmg_patient_app_new/core/app_export.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
import 'package:huawei_map/huawei_map.dart' ;
|
||||
import 'package:huawei_map/huawei_map.dart';
|
||||
|
||||
class HMSMap extends StatefulWidget{
|
||||
class HMSMap extends StatefulWidget {
|
||||
final CameraPosition currentLocation;
|
||||
final Function(CameraPosition) onCameraMoved;
|
||||
final VoidCallback onCameraIdle;
|
||||
final MapType mapType;
|
||||
final MapType initialMapType;
|
||||
final bool compassEnabled;
|
||||
final bool myLocationEnabled;
|
||||
final bool showCenterMarker;
|
||||
final Completer<HuaweiMapController>? inputController;
|
||||
|
||||
HMSMap({super.key, required this.currentLocation ,required this.onCameraMoved,required this.onCameraIdle,
|
||||
this.mapType = MapType.normal,this.compassEnabled = false,this.showCenterMarker = false,
|
||||
this.myLocationEnabled = true, this.inputController});
|
||||
const HMSMap({
|
||||
super.key,
|
||||
required this.currentLocation,
|
||||
required this.onCameraMoved,
|
||||
required this.onCameraIdle,
|
||||
this.initialMapType = MapType.normal,
|
||||
this.compassEnabled = false,
|
||||
this.showCenterMarker = false,
|
||||
this.myLocationEnabled = true,
|
||||
this.inputController,
|
||||
});
|
||||
|
||||
@override
|
||||
State<HMSMap> createState() => _HMSMapState();
|
||||
}
|
||||
|
||||
class _HMSMapState extends State<HMSMap> {
|
||||
Completer<HuaweiMapController>? controller;
|
||||
Completer<HuaweiMapController>? controller;
|
||||
late MapType _selectedMapType;
|
||||
bool _showMapTypeSelector = false;
|
||||
|
||||
final List<_MapTypeOption> _mapTypeOptions = [
|
||||
_MapTypeOption(type: MapType.normal, label: LocaleKeys.normalMapType.tr(), icon: Icons.map_outlined),
|
||||
_MapTypeOption(type: MapType.terrain, label: LocaleKeys.terrainMapType.tr(), icon: Icons.terrain_outlined),
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
HuaweiMapInitializer.initializeMap();
|
||||
controller = widget.inputController ?? Completer<HuaweiMapController>();
|
||||
super.initState();
|
||||
_selectedMapType = widget.initialMapType;
|
||||
}
|
||||
|
||||
void _onMapTypeSelected(MapType type) {
|
||||
setState(() {
|
||||
_selectedMapType = type;
|
||||
_showMapTypeSelector = false;
|
||||
});
|
||||
}
|
||||
// @override
|
||||
|
||||
void _toggleSelector() =>
|
||||
setState(() => _showMapTypeSelector = !_showMapTypeSelector);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) =>
|
||||
Stack(
|
||||
children: [
|
||||
HuaweiMap(
|
||||
mapType: widget.mapType,
|
||||
zoomControlsEnabled: false,
|
||||
myLocationEnabled: widget.myLocationEnabled,
|
||||
myLocationButtonEnabled: false,
|
||||
compassEnabled: widget.compassEnabled,
|
||||
onCameraIdle:()=> widget.onCameraIdle(),
|
||||
initialCameraPosition: widget.currentLocation,
|
||||
onCameraMove: (value) => widget.onCameraMoved(value),
|
||||
onMapCreated: (HuaweiMapController controller) {
|
||||
this.controller?.complete(controller);
|
||||
},
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
// ── Huawei Map ────────────────────────────────────────────────
|
||||
HuaweiMap(
|
||||
mapType: _selectedMapType,
|
||||
zoomControlsEnabled: false,
|
||||
myLocationEnabled: widget.myLocationEnabled,
|
||||
myLocationButtonEnabled: false,
|
||||
compassEnabled: widget.compassEnabled,
|
||||
onCameraIdle: widget.onCameraIdle,
|
||||
initialCameraPosition: widget.currentLocation,
|
||||
onCameraMove: widget.onCameraMoved,
|
||||
onMapCreated: (HuaweiMapController ctrl) {
|
||||
controller?.complete(ctrl);
|
||||
},
|
||||
),
|
||||
|
||||
// ── Centre pin marker ─────────────────────────────────────────
|
||||
if (widget.showCenterMarker)
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
Icons.location_pin,
|
||||
size: 36.h,
|
||||
color: AppColors.primaryRedColor,
|
||||
).paddingOnly(bottom: 24.h),
|
||||
),
|
||||
|
||||
// ── Map-type toggle + panel ───────────────────────────────────
|
||||
PositionedDirectional(
|
||||
top: 48.h,
|
||||
end: 16.w,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
_MapTypeToggleButton(
|
||||
isActive: _showMapTypeSelector,
|
||||
onTap: _toggleSelector,
|
||||
),
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 220),
|
||||
transitionBuilder: (child, animation) => FadeTransition(
|
||||
opacity: animation,
|
||||
child: SizeTransition(
|
||||
sizeFactor: animation,
|
||||
axisAlignment: -1,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
child: _showMapTypeSelector
|
||||
? _MapTypeSelectorPanel(
|
||||
options: _mapTypeOptions,
|
||||
selected: _selectedMapType,
|
||||
onSelected: _onMapTypeSelected,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
Visibility(
|
||||
visible: widget.showCenterMarker,
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Icon(Icons.location_pin, size: 36.h, color: AppColors.primaryRedColor).paddingOnly(bottom: 24.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Toggle button ─────────────────────────────────────────────────────────────
|
||||
|
||||
class _MapTypeToggleButton extends StatelessWidget {
|
||||
final bool isActive;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const _MapTypeToggleButton({required this.isActive, required this.onTap});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
width: 42.w,
|
||||
height: 42.h,
|
||||
decoration: BoxDecoration(
|
||||
color: isActive ? AppColors.primaryRedColor : AppColors.whiteColor,
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.layers,
|
||||
size: 22.h,
|
||||
color: isActive ? AppColors.whiteColor : AppColors.blackBgColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Selector panel ────────────────────────────────────────────────────────────
|
||||
|
||||
class _MapTypeSelectorPanel extends StatelessWidget {
|
||||
final List<_MapTypeOption> options;
|
||||
final MapType selected;
|
||||
final ValueChanged<MapType> onSelected;
|
||||
|
||||
const _MapTypeSelectorPanel({
|
||||
required this.options,
|
||||
required this.selected,
|
||||
required this.onSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
key: const ValueKey('map_type_panel'),
|
||||
margin: EdgeInsets.only(top: 8.h),
|
||||
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 6.w),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: options
|
||||
.map((opt) => _MapTypeItem(
|
||||
option: opt,
|
||||
isSelected: selected == opt.type,
|
||||
onTap: () => onSelected(opt.type),
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Single row item ───────────────────────────────────────────────────────────
|
||||
|
||||
class _MapTypeItem extends StatelessWidget {
|
||||
final _MapTypeOption option;
|
||||
final bool isSelected;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const _MapTypeItem({
|
||||
required this.option,
|
||||
required this.isSelected,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 180),
|
||||
margin: EdgeInsets.symmetric(vertical: 3.h),
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 8.h),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? AppColors.primaryRedColor.withOpacity(0.1)
|
||||
: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
option.icon,
|
||||
size: 18.h,
|
||||
color: isSelected ? AppColors.primaryRedColor : AppColors.blackBgColor,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
SizedBox(width: 8.w),
|
||||
Text(
|
||||
option.label,
|
||||
style: TextStyle(
|
||||
fontSize: 14.f,
|
||||
fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400,
|
||||
color: isSelected ? AppColors.primaryRedColor :AppColors.blackBgColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Data class ────────────────────────────────────────────────────────────────
|
||||
|
||||
class _MapTypeOption {
|
||||
final MapType type;
|
||||
final String label;
|
||||
final IconData icon;
|
||||
|
||||
const _MapTypeOption({
|
||||
required this.type,
|
||||
required this.label,
|
||||
required this.icon,
|
||||
});
|
||||
}
|
||||
@ -1,54 +1,346 @@
|
||||
// import 'dart:async';
|
||||
//
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
// import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
|
||||
// import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
// import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
//
|
||||
// class GMSMap extends StatelessWidget{
|
||||
// Completer<GoogleMapController>? controller;
|
||||
// final CameraPosition currentLocation;
|
||||
// final Function(CameraPosition) onCameraMoved;
|
||||
// final VoidCallback onCameraIdle;
|
||||
// final MapType mapType;
|
||||
// final bool compassEnabled;
|
||||
// final bool myLocationEnabled;
|
||||
// final bool showCenterMarker;
|
||||
//
|
||||
//
|
||||
// GMSMap({super.key, required this.currentLocation ,required this.onCameraMoved,required this.onCameraIdle,
|
||||
// this.mapType = MapType.normal,this.compassEnabled = false,this.showCenterMarker = false,
|
||||
// this.myLocationEnabled = true,Completer<GoogleMapController>? inputController}){
|
||||
// controller = inputController ?? Completer<GoogleMapController>();
|
||||
// }
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Stack(
|
||||
// children: [
|
||||
// GoogleMap(
|
||||
// mapType: mapType,
|
||||
// zoomControlsEnabled: true,
|
||||
// myLocationEnabled: myLocationEnabled,
|
||||
// myLocationButtonEnabled: false,
|
||||
// compassEnabled: compassEnabled,
|
||||
// initialCameraPosition: currentLocation,
|
||||
// onCameraMove: (value) => onCameraMoved(value),
|
||||
// onCameraIdle: ()=>onCameraIdle(),
|
||||
// // padding: EdgeInsets.only(bottom: 300.h),
|
||||
// onMapCreated: (GoogleMapController controller) {
|
||||
// this.controller?.complete(controller);
|
||||
// },
|
||||
// ),
|
||||
// Visibility(
|
||||
// visible: showCenterMarker,
|
||||
// child: Align(
|
||||
// alignment: Alignment.center,
|
||||
// child: Icon(Icons.location_pin, size: 36.h, color: AppColors.primaryRedColor).paddingOnly(bottom: 24.h),
|
||||
// ),
|
||||
// )
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
|
||||
import 'package:hmg_patient_app_new/extensions/widget_extensions.dart';
|
||||
import 'package:hmg_patient_app_new/generated/locale_keys.g.dart';
|
||||
import 'package:hmg_patient_app_new/theme/colors.dart';
|
||||
|
||||
class GMSMap extends StatelessWidget{
|
||||
Completer<GoogleMapController>? controller;
|
||||
class GMSMap extends StatefulWidget {
|
||||
final CameraPosition currentLocation;
|
||||
final Function(CameraPosition) onCameraMoved;
|
||||
final VoidCallback onCameraIdle;
|
||||
final MapType mapType;
|
||||
final MapType initialMapType;
|
||||
final bool compassEnabled;
|
||||
final bool myLocationEnabled;
|
||||
final bool showCenterMarker;
|
||||
final Completer<GoogleMapController>? inputController;
|
||||
|
||||
const GMSMap({
|
||||
super.key,
|
||||
required this.currentLocation,
|
||||
required this.onCameraMoved,
|
||||
required this.onCameraIdle,
|
||||
this.initialMapType = MapType.normal,
|
||||
this.compassEnabled = false,
|
||||
this.showCenterMarker = false,
|
||||
this.myLocationEnabled = true,
|
||||
this.inputController,
|
||||
});
|
||||
|
||||
@override
|
||||
State<GMSMap> createState() => _GMSMapState();
|
||||
}
|
||||
|
||||
class _GMSMapState extends State<GMSMap> {
|
||||
late Completer<GoogleMapController> _controller;
|
||||
late MapType _selectedMapType;
|
||||
bool _showMapTypeSelector = false;
|
||||
|
||||
/// All supported map types with display labels and icons
|
||||
final List<_MapTypeOption> _mapTypeOptions = [
|
||||
_MapTypeOption(
|
||||
type: MapType.normal,
|
||||
label: LocaleKeys.normalMapType.tr(),
|
||||
icon: Icons.map_outlined,
|
||||
),
|
||||
_MapTypeOption(
|
||||
type: MapType.satellite,
|
||||
label: LocaleKeys.satelliteMapType.tr(),
|
||||
icon: Icons.satellite_alt_outlined,
|
||||
),
|
||||
_MapTypeOption(
|
||||
type: MapType.terrain,
|
||||
label: LocaleKeys.terrainMapType.tr(),
|
||||
icon: Icons.terrain_outlined,
|
||||
),
|
||||
_MapTypeOption(
|
||||
type: MapType.hybrid,
|
||||
label: LocaleKeys.hybridMapType.tr(),
|
||||
icon: Icons.layers_outlined,
|
||||
),
|
||||
];
|
||||
|
||||
GMSMap({super.key, required this.currentLocation ,required this.onCameraMoved,required this.onCameraIdle,
|
||||
this.mapType = MapType.normal,this.compassEnabled = false,this.showCenterMarker = false,
|
||||
this.myLocationEnabled = true,Completer<GoogleMapController>? inputController}){
|
||||
controller = inputController ?? Completer<GoogleMapController>();
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = widget.inputController ?? Completer<GoogleMapController>();
|
||||
_selectedMapType = widget.initialMapType;
|
||||
}
|
||||
|
||||
void _onMapTypeSelected(MapType type) {
|
||||
setState(() {
|
||||
_selectedMapType = type;
|
||||
_showMapTypeSelector = false;
|
||||
});
|
||||
}
|
||||
|
||||
void _toggleMapTypeSelector() {
|
||||
setState(() => _showMapTypeSelector = !_showMapTypeSelector);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
GoogleMap(
|
||||
mapType: mapType,
|
||||
return Stack(
|
||||
children: [
|
||||
// ── Google Map ──────────────────────────────────────────────────
|
||||
GoogleMap(
|
||||
mapType: _selectedMapType,
|
||||
zoomControlsEnabled: true,
|
||||
myLocationEnabled: myLocationEnabled,
|
||||
myLocationEnabled: widget.myLocationEnabled,
|
||||
myLocationButtonEnabled: false,
|
||||
compassEnabled: compassEnabled,
|
||||
initialCameraPosition: currentLocation,
|
||||
onCameraMove: (value) => onCameraMoved(value),
|
||||
onCameraIdle: ()=>onCameraIdle(),
|
||||
// padding: EdgeInsets.only(bottom: 300.h),
|
||||
compassEnabled: widget.compassEnabled,
|
||||
initialCameraPosition: widget.currentLocation,
|
||||
onCameraMove: widget.onCameraMoved,
|
||||
onCameraIdle: widget.onCameraIdle,
|
||||
onMapCreated: (GoogleMapController controller) {
|
||||
this.controller?.complete(controller);
|
||||
_controller.complete(controller);
|
||||
},
|
||||
),
|
||||
Visibility(
|
||||
visible: showCenterMarker,
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Icon(Icons.location_pin, size: 36.h, color: AppColors.primaryRedColor).paddingOnly(bottom: 24.h),
|
||||
),
|
||||
|
||||
// ── Centre pin marker ───────────────────────────────────────────
|
||||
if (widget.showCenterMarker)
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
Icons.location_pin,
|
||||
size: 36.h,
|
||||
color: AppColors.primaryRedColor,
|
||||
).paddingOnly(bottom: 24.h),
|
||||
),
|
||||
)
|
||||
|
||||
// ── Map-type toggle button ──────────────────────────────────────
|
||||
PositionedDirectional(
|
||||
top: 48.h,
|
||||
end: 16.w,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
// Toggle button
|
||||
_MapTypeToggleButton(
|
||||
isActive: _showMapTypeSelector,
|
||||
onTap: _toggleMapTypeSelector,
|
||||
),
|
||||
|
||||
// Expandable selector panel
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 220),
|
||||
transitionBuilder: (child, animation) => FadeTransition(
|
||||
opacity: animation,
|
||||
child: SizeTransition(
|
||||
sizeFactor: animation,
|
||||
axisAlignment: -1,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
child: _showMapTypeSelector
|
||||
? _MapTypeSelectorPanel(
|
||||
options: _mapTypeOptions,
|
||||
selected: _selectedMapType,
|
||||
onSelected: _onMapTypeSelected,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Toggle button ─────────────────────────────────────────────────────────────
|
||||
|
||||
class _MapTypeToggleButton extends StatelessWidget {
|
||||
final bool isActive;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const _MapTypeToggleButton({
|
||||
required this.isActive,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
width: 42.w,
|
||||
height: 42.h,
|
||||
decoration: BoxDecoration(
|
||||
color: isActive ? AppColors.primaryRedColor : AppColors.whiteColor,
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.layers,
|
||||
size: 22.h,
|
||||
color: isActive ? AppColors.whiteColor : AppColors.blackBgColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Selector panel ────────────────────────────────────────────────────────────
|
||||
|
||||
class _MapTypeSelectorPanel extends StatelessWidget {
|
||||
final List<_MapTypeOption> options;
|
||||
final MapType selected;
|
||||
final ValueChanged<MapType> onSelected;
|
||||
|
||||
const _MapTypeSelectorPanel({
|
||||
required this.options,
|
||||
required this.selected,
|
||||
required this.onSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
key: const ValueKey('map_type_panel'),
|
||||
margin: EdgeInsets.only(top: 8.h),
|
||||
padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 6.w),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.whiteColor,
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: options
|
||||
.map(
|
||||
(opt) => _MapTypeItem(
|
||||
option: opt,
|
||||
isSelected: selected == opt.type,
|
||||
onTap: () => onSelected(opt.type),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Single row item ───────────────────────────────────────────────────────────
|
||||
|
||||
class _MapTypeItem extends StatelessWidget {
|
||||
final _MapTypeOption option;
|
||||
final bool isSelected;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const _MapTypeItem({
|
||||
required this.option,
|
||||
required this.isSelected,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 180),
|
||||
margin: EdgeInsets.symmetric(vertical: 3.h),
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 8.h),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? AppColors.primaryRedColor.withOpacity(0.1)
|
||||
: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
option.icon,
|
||||
size: 18.h,
|
||||
color: isSelected ? AppColors.primaryRedColor : Colors.black54,
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
Text(
|
||||
option.label,
|
||||
style: TextStyle(
|
||||
fontSize: 13.f,
|
||||
fontWeight:
|
||||
isSelected ? FontWeight.w600 : FontWeight.w400,
|
||||
color:
|
||||
isSelected ? AppColors.primaryRedColor : AppColors.blackBgColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Data class ────────────────────────────────────────────────────────────────
|
||||
|
||||
class _MapTypeOption {
|
||||
final MapType type;
|
||||
final String label;
|
||||
final IconData icon;
|
||||
|
||||
const _MapTypeOption({
|
||||
required this.type,
|
||||
required this.label,
|
||||
required this.icon,
|
||||
});
|
||||
}
|
||||
Loading…
Reference in New Issue