CustomDropdown.dart
class CustomDropDownScreen extends StatefulWidget {
final bool showAppBar;
const CustomDropDownScreen({super.key, this.showAppBar = false});
@override
State<CustomDropDownScreen> createState() => _CustomDropDownScreenState();
}
class _CustomDropDownScreenState extends State<CustomDropDownScreen> {
ThemeController themeController = Get.find();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
appBar: widget.showAppBar
? AppBar(
title: const Text(
"Custom DropDown Theme",
),
)
: null,
body: Center(
child: Container(
constraints: const BoxConstraints(
maxWidth: 1000,
),
alignment: Alignment.topCenter,
padding: const EdgeInsets.all(16),
child: Stack(
alignment: Alignment.topCenter,
children: [
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: ResponsiveBuilder.isSmallTablet(context) ||
ResponsiveBuilder.isMobile(context)
? 230
: 125,),
_buildCommonContainer(
child: ThemeColorSelector(controller: themeController,),
title: "Theme Color",
description: "Select the theme mode you prefer.",
),
const SizedBox(height: 20,),
Obx(
() => CustomContainer(
title: 'Dropdown Container color',
description: 'Background color',
child: ThemePopupMenu3(
schemeIndex:
themeController.customDropDownContainerColorIndex.value,
onChanged:
themeController.setCustomDropDownContainerColorIndex),
),
),
const SizedBox(height: 20,),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Obx(
() => Flexible(
child: _buildCommonContainer(
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
overlayShape: SliderComponentShape.noOverlay,
),
child: SizedBox(
width: 1000,
child: Slider(
value: themeController
.customDropDownContainerRadius.value,
min: -1,
max: 40,
divisions: 20,
inactiveColor: Colors.transparent,
onChanged: (double value) {
themeController
.setCustomDropDownContainerRadius(value);
if (kDebugMode) {
print(value);
}
},
),
),
),
title: 'Dropdown Container Radius',
description:
'Adjust the dropdown container radius to your preference.',
),
),
),
Padding(
padding: const EdgeInsets.only(left: 10.0, top: 28),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text('Radius'),
Obx(
() {
final borderRadius = themeController
.customDropDownContainerRadius.value;
final integerPart =
double.parse(borderRadius.toStringAsFixed(0))
.toInt();
return SizedBox(
width: 55,
child: Text(
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
themeController
.customDropDownContainerRadius.value ==
-1
? 'default stadium'
: integerPart.toString(),
style: TextStyles.titleSmall
.copyWith(fontSize: 12),
),
);
},
)
],
),
)
],
),
const SizedBox(height: 20,),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Obx(
() => Flexible(
child: _buildCommonContainer(
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
overlayShape: SliderComponentShape.noOverlay,
),
child: SizedBox(
width: 1000,
child: Slider(
value: themeController
.customDropDownContainerColorOpacity.value,
min: 0,
max: 100,
divisions: 25,
inactiveColor: Colors.transparent,
onChanged: (double value) {
themeController
.setCustomDropDownContainerColorOpacity(value);
if (kDebugMode) {
print(value);
}
},
),
),
),
title: 'Dropdown Container Color Opacity',
description:
'Adjust the dropdown container color opacity to your preference.',
),
),
),
Padding(
padding: const EdgeInsets.only(left: 10.0, top: 28),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text('Opacity'),
Obx(
() {
final borderRadius = themeController
.customDropDownContainerColorOpacity.value;
final integerPart =
double.parse(borderRadius.toStringAsFixed(0))
.toInt();
return SizedBox(
width: 55,
child: Text(
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
themeController
.customDropDownContainerColorOpacity.value ==
-1
? 'default opacity'
: integerPart.toString(),
style: TextStyles.titleSmall
.copyWith(fontSize: 12),
),
);
},
)
],
),
)
],
),
const SizedBox(height: 20,),
const Divider(),
const ListTileReveal(
title: Text('Custom Dropdown Button'),
subtitleDense: true,
subtitle: Text('Material 3, replacement for ToggleButtons. '
'Custom Dropdown Button may work better when using only icons and it is '
'similarly styled by FCS sub themes. Custom Dropdown Button '
'is better if you also have text, and optionally also want.\n'),
),
Obx(
() => CustomContainer(
title: 'Dropdown Button color',
description: 'Background color',
child: ThemePopupMenu3(
schemeIndex:
themeController.customDropDownButtonColorIndex.value,
onChanged:
themeController.setCustomDropDownButtonColorIndex),
),
),
const SizedBox(height: 20,),
Obx(
() => CustomContainer(
title: 'Dropdown Button color',
description: 'Foreground color',
child: ThemePopupMenu3(
schemeIndex:
themeController.customDropDownForegroundColorIndex.value,
onChanged:
themeController.setCustomDropDownForegroundColorIndex),
),
),
const SizedBox(height: 20,),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Obx(
() => Flexible(
child: _buildCommonContainer(
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
overlayShape: SliderComponentShape.noOverlay,
),
child: SizedBox(
width: 1000,
child: Slider(
value: themeController
.customDropDownButtonRadius.value,
min: -1,
max: 40,
divisions: 20,
inactiveColor: Colors.transparent,
onChanged: (double value) {
themeController
.setCustomDropDownButtonRadius(value);
if (kDebugMode) {
print(value);
}
},
),
),
),
title: 'Dropdown Button Radius',
description:
'Adjust the dropdown button radius to your preference.',
),
),
),
Padding(
padding: const EdgeInsets.only(left: 10.0, top: 28),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text('Radius'),
Obx(
() {
final borderRadius = themeController
.customDropDownButtonRadius.value;
final integerPart =
double.parse(borderRadius.toStringAsFixed(0))
.toInt();
return SizedBox(
width: 55,
child: Text(
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
themeController
.customDropDownButtonRadius.value ==
-1
? 'default stadium'
: integerPart.toString(),
style: TextStyles.titleSmall
.copyWith(fontSize: 12),
),
);
},
)
],
),
)
],
),
const SizedBox(height: 20,),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Obx(
() => Flexible(
child: _buildCommonContainer(
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
overlayShape: SliderComponentShape.noOverlay,
),
child: SizedBox(
width: 1000,
child: Slider(
value: themeController
.customDropDownButtonColorOpacity.value,
min: 0,
max: 100,
divisions: 25,
inactiveColor: Colors.transparent,
onChanged: (double value) {
themeController
.setCustomDropDownButtonColorOpacity(value);
if (kDebugMode) {
print(value);
}
},
),
),
),
title: 'Dropdown Button Color Opacity',
description:
'Adjust the dropdown button color opacity to your preference.',
),
),
),
Padding(
padding: const EdgeInsets.only(left: 10.0, top: 28),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text('Opacity'),
Obx(
() {
final borderRadius = themeController
.customDropDownButtonColorOpacity.value;
final integerPart =
double.parse(borderRadius.toStringAsFixed(0))
.toInt();
return SizedBox(
width: 55,
child: Text(
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
themeController
.customDropDownButtonColorOpacity.value ==
-1
? 'default opacity'
: integerPart.toString(),
style: TextStyles.titleSmall
.copyWith(fontSize: 12),
),
);
},
)
],
),
)
],
),
const SizedBox(height: 20,),
const Divider(),
const ListTileReveal(
title: Text('Custom Dropdown items'),
subtitleDense: true,
subtitle: Text('Material 3, replacement for Custom Dropdown items. '
'Custom Dropdown items may work better when using only icons and it is '
'similarly styled by FCS sub themes. Custom Dropdown items'
'is better if you also have text, and optionally also want.\n'),
),
Obx(
() => CustomContainer(
title: 'Dropdown Items color',
description: 'Background color',
child: ThemePopupMenu3(
schemeIndex:
themeController.customDropDownItemsColorIndex.value,
onChanged:
themeController.setCustomDropDownItemsColorIndex),
),
),
],
),
),
Container(
height: ResponsiveBuilder.isSmallTablet(context) ||
ResponsiveBuilder.isMobile(context)
? 220
: 115,
width: double.infinity,
color: Theme.of(context).colorScheme.background,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ResponsiveBuilder.isSmallTablet(context) ||
ResponsiveBuilder.isMobile(context)
? Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CustomContainer(
title: 'DropDown Button',
child: ThemePopupMenu3(
schemeIndex: 1,
onChanged: (color, index) {},
),
),
const SizedBox(height: 10,),
CustomContainer(
title: 'DropDown Button Without Search Bar',
child: ThemePopupMenu3(
schemeIndex: 1,
searchable: false,
onChanged: (color, index) {},
),
),
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: CustomContainer(
title: 'DropDown Button',
child: ThemePopupMenu3(
widthFactor: 0.5,
schemeIndex: 1,
onChanged: (color, index) {},
),
),
),
const SizedBox(
width: 10,
),
Flexible(
child: CustomContainer(
title: 'DropDown Button Without Search Bar',
child: ThemePopupMenu3(
widthFactor: 0.5,
schemeIndex: 1,
searchable: false,
onChanged: (color, index) {},
),
),
),
],
),
const Divider()
],
),
),
],
),
),
),
);
}
Widget _buildCommonContainer(
{required Widget child, required String title, String? description,}) {
return Column(
children: [
Container(
padding: const EdgeInsets.only(left: 16),
alignment: Alignment.centerLeft,
child: Text(
title,
style: TextStyles.titleSmall,
),
),
const SizedBox(height: 5),
Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
borderRadius: BorderRadius.circular(10),
boxShadow: [containerShadow(context)],
),
child: child,
),
if (description != null) const SizedBox(height: 5),
if (description != null)
Container(
padding: const EdgeInsets.only(left: 16),
alignment: Alignment.centerLeft,
child: Text(
description,
style: TextStyles.bodyMedium,
),
),
],
);
}
}