From 45d4d10604f97ec46debb9e190201da76762c825 Mon Sep 17 00:00:00 2001 From: pc gamer Date: Mon, 24 Nov 2025 11:40:51 +0330 Subject: [PATCH] added decoration for overlay button --- example/lib/main.dart | 106 +--------- lib/dropdown_textfield.dart | 394 +++++++++++++++++------------------- lib/multi_selection.dart | 211 ++++++++++--------- lib/single_selction.dart | 199 +++++++++--------- 4 files changed, 401 insertions(+), 509 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 077cadb..d440bde 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -6,7 +6,7 @@ void main() { } class MyApp extends StatelessWidget { - const MyApp({super.key}); + const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -22,21 +22,21 @@ class MyApp extends StatelessWidget { } class NewPage extends StatelessWidget { - const NewPage({super.key}); + const NewPage({key}); @override Widget build(BuildContext context) { return Scaffold( floatingActionButton: FloatingActionButton(onPressed: () { Navigator.of(context) - .push(MaterialPageRoute(builder: (context) => const TestPage())); + .push(MaterialPageRoute(builder: (context) => TestPage())); }), ); } } class TestPage extends StatefulWidget { - const TestPage({super.key}); + const TestPage({Key? key}) : super(key: key); @override State createState() => _TestPageState(); @@ -92,6 +92,9 @@ class _TestPageState extends State { searchTextStyle: const TextStyle(color: Colors.red), searchDecoration: const InputDecoration( hintText: "enter your custom hint text here"), + overlayDecoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + color: Colors.blue), validator: (value) { if (value == null) { return "Required field"; @@ -174,7 +177,7 @@ class _TestPageState extends State { // initialValue: const ["name1", "name2", "name8", "name3"], // displayCompleteItem: true, checkBoxProperty: CheckBoxProperty( - fillColor: WidgetStateProperty.all(Colors.red)), + fillColor: MaterialStateProperty.all(Colors.red)), dropDownList: const [ DropDownValueModel(name: 'name1', value: "value1"), DropDownValueModel( @@ -236,98 +239,7 @@ class _TestPageState extends State { ), const SizedBox( height: 50, - ), - const Text( - "Single selection dropdown with prefix widget and custom boxDecoration and boxMargin", - style: TextStyle(fontWeight: FontWeight.bold), - ), - const SizedBox( - height: 20, - ), - DropDownTextField( - // initialValue: "name4", - listSpace: 20, - listPadding: ListPadding(top: 20), - enableSearch: true, - validator: (value) { - if (value == null) { - return "Required field"; - } else { - return null; - } - }, - boxDecoration: BoxDecoration( - color: Colors.blue[200], - borderRadius: BorderRadius.circular(16), - ), - boxMargin: - const EdgeInsets.symmetric(horizontal: 8, vertical: 6), - dropDownList: const [ - DropDownValueModel( - name: 'name1', - value: "value1", - prefixWidget: Icon( - Icons.person, - size: 24, - )), - DropDownValueModel( - name: 'name2', - value: "value2", - prefixWidget: Icon( - Icons.person, - size: 24, - )), - DropDownValueModel( - name: 'name3', - value: "value3", - prefixWidget: Icon( - Icons.person, - size: 24, - )), - DropDownValueModel( - name: 'name4', - value: "value4", - prefixWidget: Icon( - Icons.person, - size: 24, - )), - DropDownValueModel( - name: 'name5', - value: "value5", - prefixWidget: Icon( - Icons.person, - size: 24, - )), - DropDownValueModel( - name: 'name6', - value: "value6", - prefixWidget: Icon( - Icons.person, - size: 24, - )), - DropDownValueModel( - name: 'name7', - value: "value7", - prefixWidget: Icon( - Icons.person, - size: 24, - )), - DropDownValueModel( - name: 'name8', - value: "value8", - prefixWidget: Icon( - Icons.person, - size: 24, - )), - ], - listTextStyle: const TextStyle(color: Colors.red), - dropDownItemCount: 8, - - onChanged: (val) {}, - ), - const SizedBox( - height: 50, - ), + ) ], ), ), diff --git a/lib/dropdown_textfield.dart b/lib/dropdown_textfield.dart index a00a803..4b698ee 100644 --- a/lib/dropdown_textfield.dart +++ b/lib/dropdown_textfield.dart @@ -17,14 +17,14 @@ class IconProperty { class CheckBoxProperty { final MouseCursor? mouseCursor; final Color? activeColor; - final WidgetStateProperty? fillColor; + final MaterialStateProperty? fillColor; final Color? checkColor; final bool tristate; final MaterialTapTargetSize? materialTapTargetSize; final VisualDensity? visualDensity; final Color? focusColor; final Color? hoverColor; - final WidgetStateProperty? overlayColor; + final MaterialStateProperty? overlayColor; final double? splashRadius; final FocusNode? focusNode; final bool autofocus; @@ -51,62 +51,9 @@ class CheckBoxProperty { } class DropDownTextField extends StatefulWidget { - const DropDownTextField( - {Key? key, - this.controller, - this.initialValue, - required this.dropDownList, - this.padding, - this.textStyle, - this.onChanged, - this.validator, - this.isEnabled = true, - this.enableSearch = false, - this.readOnly = true, - this.dropdownRadius = 12, - this.textFieldDecoration, - this.dropDownIconProperty, - this.dropDownItemCount = 6, - this.searchTextStyle, - this.searchFocusNode, - this.textFieldFocusNode, - this.searchAutofocus = false, - this.searchDecoration, - this.searchShowCursor, - this.searchKeyboardType, - this.listSpace = 0, - this.clearOption = true, - this.clearIconProperty, - this.listPadding, - this.listTextStyle, - this.keyboardType, - this.autovalidateMode, - this.boxDecoration, - this.boxMargin}) - : assert( - !(initialValue != null && controller != null), - "you cannot add both initialValue and singleController,\nset initial value using controller \n\tEg: SingleValueDropDownController(data:initial value) ", - ), - assert(!(!readOnly && enableSearch), - "readOnly!=true or enableSearch=true both condition does not work"), - assert( - !(controller != null && - !(controller is SingleValueDropDownController)), - "controller must be type of SingleValueDropDownController", - ), - checkBoxProperty = null, - isMultiSelection = false, - singleController = controller, - multiController = null, - displayCompleteItem = false, - submitButtonColor = null, - submitButtonText = null, - submitButtonTextStyle = null, - super(key: key); - const DropDownTextField.multiSelection({ + const DropDownTextField({ Key? key, this.controller, - this.displayCompleteItem = false, this.initialValue, required this.dropDownList, this.padding, @@ -114,25 +61,76 @@ class DropDownTextField extends StatefulWidget { this.onChanged, this.validator, this.isEnabled = true, + this.enableSearch = false, + this.readOnly = true, this.dropdownRadius = 12, - this.dropDownIconProperty, this.textFieldDecoration, + this.dropDownIconProperty, this.dropDownItemCount = 6, + this.searchTextStyle, this.searchFocusNode, this.textFieldFocusNode, + this.searchAutofocus = false, + this.searchDecoration, + this.searchShowCursor, + this.searchKeyboardType, this.listSpace = 0, this.clearOption = true, this.clearIconProperty, - this.submitButtonColor, - this.submitButtonText, - this.submitButtonTextStyle, this.listPadding, this.listTextStyle, - this.checkBoxProperty, + this.keyboardType, this.autovalidateMode, - this.boxDecoration, - this.boxMargin, - }) : assert(initialValue == null || controller == null, + this.overlayDecoration, + }) : assert( + !(initialValue != null && controller != null), + "you cannot add both initialValue and singleController,\nset initial value using controller \n\tEg: SingleValueDropDownController(data:initial value) ", + ), + assert(!(!readOnly && enableSearch), + "readOnly!=true or enableSearch=true both condition does not work"), + assert( + !(controller != null && + !(controller is SingleValueDropDownController)), + "controller must be type of SingleValueDropDownController", + ), + checkBoxProperty = null, + isMultiSelection = false, + singleController = controller, + multiController = null, + displayCompleteItem = false, + submitButtonColor = null, + submitButtonText = null, + submitButtonTextStyle = null, + super(key: key); + const DropDownTextField.multiSelection( + {Key? key, + this.controller, + this.displayCompleteItem = false, + this.initialValue, + required this.dropDownList, + this.padding, + this.textStyle, + this.onChanged, + this.validator, + this.isEnabled = true, + this.dropdownRadius = 12, + this.dropDownIconProperty, + this.textFieldDecoration, + this.dropDownItemCount = 6, + this.searchFocusNode, + this.textFieldFocusNode, + this.listSpace = 0, + this.clearOption = true, + this.clearIconProperty, + this.submitButtonColor, + this.submitButtonText, + this.submitButtonTextStyle, + this.listPadding, + this.listTextStyle, + this.checkBoxProperty, + this.autovalidateMode, + this.overlayDecoration = const BoxDecoration()}) + : assert(initialValue == null || controller == null, "you cannot add both initialValue and multiController\nset initial value using controller\n\tMultiValueDropDownController(data:initial value)"), assert( !(controller != null && @@ -250,13 +248,12 @@ class DropDownTextField extends StatefulWidget { final TextInputType? keyboardType; final AutovalidateMode? autovalidateMode; - final BoxDecoration? boxDecoration; - - final EdgeInsets? boxMargin; - ///customize checkbox property final CheckBoxProperty? checkBoxProperty; + ///customize BackgroundColor on dropdown overlay + final Decoration? overlayDecoration; + @override _DropDownTextFieldState createState() => _DropDownTextFieldState(); } @@ -295,8 +292,6 @@ class _DropDownTextFieldState extends State late TextStyle _listTileTextStyle; late ListPadding _listPadding; late TextDirection _currentDirection; - late BoxDecoration? _boxDecoration; - late EdgeInsets? _boxMargin; GlobalKey overlayKey = GlobalKey(); @override void initState() { @@ -307,8 +302,6 @@ class _DropDownTextFieldState extends State _isOutsideClickOverlay = false; _searchFocusNode = widget.searchFocusNode ?? FocusNode(); _textFieldFocusNode = widget.textFieldFocusNode ?? FocusNode(); - _boxDecoration = widget.boxDecoration; - _boxMargin = widget.boxMargin; _isExpanded = false; _controller = AnimationController( vsync: this, @@ -569,20 +562,19 @@ class _DropDownTextFieldState extends State enabled: widget.isEnabled, readOnly: widget.readOnly, onTapOutside: (event) { - final RenderObject? renderObject = - overlayKey.currentContext?.findRenderObject(); - if (renderObject is RenderBox) { - final overlayPosition = renderObject.localToGlobal(Offset.zero); - final overlaySize = renderObject.size; - bool isOverlayTap = (overlayPosition.dx <= event.position.dx && - event.position.dx <= - overlayPosition.dx + overlaySize.width) && - (overlayPosition.dy <= event.position.dy && - event.position.dy <= - overlayPosition.dy + overlaySize.height); - if (!isOverlayTap) { - _textFieldFocusNode.unfocus(); - } + final RenderBox renderBox = + overlayKey.currentContext?.findRenderObject() as RenderBox; + final overlayPosition = renderBox.localToGlobal(Offset.zero); + final overlaySize = renderBox.size; + bool isOverlayTap = (overlayPosition.dx <= event.position.dx && + event.position.dx <= + overlayPosition.dx + overlaySize.width) && + (overlayPosition.dy <= event.position.dy && + event.position.dy <= + overlayPosition.dy + overlaySize.height); + + if (!isOverlayTap) { + _textFieldFocusNode.unfocus(); } }, onTap: () { @@ -810,116 +802,117 @@ class _DropDownTextFieldState extends State child: Material( key: overlayKey, color: Colors.transparent, - child: Container( - margin: _boxMargin ?? - const EdgeInsets.symmetric(horizontal: 4, vertical: 5), - decoration: _boxDecoration ?? - BoxDecoration( - color: Theme.of(context).cardColor, // Matches theme - borderRadius: BorderRadius.all( - Radius.circular(widget.dropdownRadius), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 5), + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: + BorderRadius.all(Radius.circular(widget.dropdownRadius)), + boxShadow: const [ + BoxShadow( + color: Colors.grey, + blurRadius: 5, ), - boxShadow: [ - BoxShadow( - color: Theme.of(context).shadowColor.withValues(alpha: 0.2), - blurRadius: 5, - ), - ], - ), - child: !widget.isMultiSelection - ? SingleSelection( - mainController: _cnt, - autoSort: !widget.readOnly, - mainFocusNode: _textFieldFocusNode, - searchTextStyle: widget.searchTextStyle, - searchFocusNode: _searchFocusNode, - enableSearch: widget.enableSearch, - height: _height, - listTileHeight: _listTileHeight, - dropDownList: _dropDownList, - listTextStyle: _listTileTextStyle, - onChanged: (item) { - setState(() { - _cnt.text = item.name; + ], + ), + child: !widget.isMultiSelection + ? SingleSelection( + mainController: _cnt, + autoSort: !widget.readOnly, + mainFocusNode: _textFieldFocusNode, + searchTextStyle: widget.searchTextStyle, + searchFocusNode: _searchFocusNode, + enableSearch: widget.enableSearch, + height: _height, + listTileHeight: _listTileHeight, + dropDownList: _dropDownList, + listTextStyle: _listTileTextStyle, + onChanged: (item) { + setState(() { + _cnt.text = item.name; + _isExpanded = !_isExpanded; + }); + if (widget.singleController != null) { + widget.singleController!.setDropDown(item); + } + if (widget.onChanged != null) { + widget.onChanged!(item); + } + // Navigator.pop(context, null); + + hideOverlay(); + }, + searchHeight: _searchWidgetHeight, + searchKeyboardType: widget.searchKeyboardType, + searchAutofocus: _searchAutofocus, + searchDecoration: widget.searchDecoration, + searchShowCursor: widget.searchShowCursor, + listPadding: _listPadding, + // onSearchTap: () { + // double posFromBot = + // MediaQuery.of(context).size.height - _offset.dy; + // if (posFromBot < _keyboardHeight && + // !_isScrollPadding && + // _isPortrait) { + // shiftOverlayEntry1to2(); + // } + // }, + // onSearchSubmit: () { + // if (_isScrollPadding) { + // shiftOverlayEntry2to1(); + // } + // }, + clearIconProperty: widget.clearIconProperty, + overlayDecoration: widget.overlayDecoration, + ) + : MultiSelection( + buttonTextStyle: widget.submitButtonTextStyle, + buttonText: widget.submitButtonText, + buttonColor: widget.submitButtonColor, + height: _height, + listTileHeight: _listTileHeight, + list: _multiSelectionValue, + dropDownList: _dropDownList, + listTextStyle: _listTileTextStyle, + listPadding: _listPadding, + onChanged: (val) { _isExpanded = !_isExpanded; - }); - if (widget.singleController != null) { - widget.singleController!.setDropDown(item); - } - if (widget.onChanged != null) { - widget.onChanged!(item); - } - // Navigator.pop(context, null); - - hideOverlay(); - }, - searchHeight: _searchWidgetHeight, - searchKeyboardType: widget.searchKeyboardType, - searchAutofocus: _searchAutofocus, - searchDecoration: widget.searchDecoration, - searchShowCursor: widget.searchShowCursor, - listPadding: _listPadding, - // onSearchTap: () { - // double posFromBot = - // MediaQuery.of(context).size.height - _offset.dy; - // if (posFromBot < _keyboardHeight && - // !_isScrollPadding && - // _isPortrait) { - // shiftOverlayEntry1to2(); - // } - // }, - // onSearchSubmit: () { - // if (_isScrollPadding) { - // shiftOverlayEntry2to1(); - // } - // }, - clearIconProperty: widget.clearIconProperty, - ) - : MultiSelection( - buttonTextStyle: widget.submitButtonTextStyle, - buttonText: widget.submitButtonText, - buttonColor: widget.submitButtonColor, - height: _height, - listTileHeight: _listTileHeight, - list: _multiSelectionValue, - dropDownList: _dropDownList, - listTextStyle: _listTileTextStyle, - listPadding: _listPadding, - onChanged: (val) { - _isExpanded = !_isExpanded; - _multiSelectionValue = val; - List result = []; - List completeList = []; - for (int i = 0; i < _multiSelectionValue.length; i++) { - if (_multiSelectionValue[i]) { - result.add(_dropDownList[i]); - completeList.add(_dropDownList[i].name); + _multiSelectionValue = val; + List result = []; + List completeList = []; + for (int i = 0; + i < _multiSelectionValue.length; + i++) { + if (_multiSelectionValue[i]) { + result.add(_dropDownList[i]); + completeList.add(_dropDownList[i].name); + } } - } - int count = _multiSelectionValue - .where((element) => element) - .toList() - .length; - - _cnt.text = (count == 0 - ? "" - : widget.displayCompleteItem - ? completeList.join(",") - : "$count item selected"); - if (widget.multiController != null) { - widget.multiController! - .setDropDown(result.isNotEmpty ? result : null); - } - if (widget.onChanged != null) { - widget.onChanged!(result); - } - - hideOverlay(); - - setState(() {}); - }, - checkBoxProperty: widget.checkBoxProperty, - ), + int count = _multiSelectionValue + .where((element) => element) + .toList() + .length; + + _cnt.text = (count == 0 + ? "" + : widget.displayCompleteItem + ? completeList.join(",") + : "$count item selected"); + if (widget.multiController != null) { + widget.multiController! + .setDropDown(result.isNotEmpty ? result : null); + } + if (widget.onChanged != null) { + widget.onChanged!(result); + } + hideOverlay(); + setState(() {}); + }, + checkBoxProperty: widget.checkBoxProperty, + overlayDecoration: widget.overlayDecoration, + ), + ), ), ), ), @@ -931,33 +924,27 @@ class _DropDownTextFieldState extends State class DropDownValueModel extends Equatable { final String name; final dynamic value; - final Widget? prefixWidget; ///as of now only added for multiselection dropdown final String? toolTipMsg; const DropDownValueModel( - {required this.name, - required this.value, - this.prefixWidget, - this.toolTipMsg}); + {required this.name, required this.value, this.toolTipMsg}); factory DropDownValueModel.fromJson(Map json) => DropDownValueModel( name: json["name"], value: json["value"], - prefixWidget: json["prefixWidget"], toolTipMsg: json["toolTipMsg"], ); Map toJson() => { "name": name, "value": value, - "prefixWidget": prefixWidget, "toolTipMsg": toolTipMsg, }; @override - List get props => [name, value, prefixWidget]; + List get props => [name, value]; @override bool operator ==(Object other) => @@ -965,11 +952,10 @@ class DropDownValueModel extends Equatable { other is DropDownValueModel && runtimeType == other.runtimeType && name == other.name && - value == other.value && - prefixWidget == other.prefixWidget; + value == other.value; @override - int get hashCode => name.hashCode ^ value.hashCode ^ prefixWidget.hashCode; + int get hashCode => name.hashCode ^ value.hashCode; } class SingleValueDropDownController extends ChangeNotifier { diff --git a/lib/multi_selection.dart b/lib/multi_selection.dart index 9ef97a3..a660468 100644 --- a/lib/multi_selection.dart +++ b/lib/multi_selection.dart @@ -16,7 +16,8 @@ class MultiSelection extends StatefulWidget { required this.listTileHeight, required this.listPadding, this.listTextStyle, - this.checkBoxProperty}) + this.checkBoxProperty, + this.overlayDecoration}) : super(key: key); final List dropDownList; final ValueSetter onChanged; @@ -29,6 +30,7 @@ class MultiSelection extends StatefulWidget { final TextStyle? listTextStyle; final ListPadding listPadding; final CheckBoxProperty? checkBoxProperty; + final Decoration? overlayDecoration; @override _MultiSelectionState createState() => _MultiSelectionState(); @@ -45,123 +47,118 @@ class _MultiSelectionState extends State { @override Widget build(BuildContext context) { - return Column( - children: [ - SizedBox( - height: widget.height, - child: Scrollbar( - child: ListView.builder( - padding: EdgeInsets.zero, - itemCount: widget.dropDownList.length, - itemBuilder: (BuildContext context, int index) { - return SizedBox( - height: widget.listTileHeight + - widget.listPadding.top + - widget.listPadding.bottom, - child: Padding( - padding: EdgeInsets.only( - bottom: widget.listPadding.bottom, - top: widget.listPadding.top), - child: Row( - children: [ - Expanded( - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 10), - child: Row( - children: [ - Expanded( - child: Row( - children: [ - widget.dropDownList[index] - .prefixWidget ?? - const SizedBox.shrink(), - Text( + return Container( + decoration: widget.overlayDecoration, + child: Column( + children: [ + SizedBox( + height: widget.height, + child: Scrollbar( + child: ListView.builder( + padding: EdgeInsets.zero, + itemCount: widget.dropDownList.length, + itemBuilder: (BuildContext context, int index) { + return SizedBox( + height: widget.listTileHeight, + child: Padding( + padding: EdgeInsets.only( + bottom: widget.listPadding.bottom, + top: widget.listPadding.top), + child: Row( + children: [ + Expanded( + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 10), + child: Row( + children: [ + Expanded( + child: Text( widget.dropDownList[index].name, - style: widget.listTextStyle, - ), - ], + style: widget.listTextStyle), ), - ), - if (widget.dropDownList[index].toolTipMsg != - null) - ToolTipWidget( - msg: widget - .dropDownList[index].toolTipMsg!) - ], + if (widget.dropDownList[index].toolTipMsg != + null) + ToolTipWidget( + msg: widget + .dropDownList[index].toolTipMsg!) + ], + ), ), ), - ), - Checkbox( - value: multiSelectionValue[index], - onChanged: (value) { - if (value != null) { - setState(() { - multiSelectionValue[index] = value; - }); - } - }, - tristate: - widget.checkBoxProperty?.tristate ?? false, - mouseCursor: widget.checkBoxProperty?.mouseCursor, - activeColor: widget.checkBoxProperty?.activeColor, - fillColor: widget.checkBoxProperty?.fillColor, - checkColor: widget.checkBoxProperty?.checkColor, - focusColor: widget.checkBoxProperty?.focusColor, - hoverColor: widget.checkBoxProperty?.hoverColor, - overlayColor: widget.checkBoxProperty?.overlayColor, - splashRadius: widget.checkBoxProperty?.splashRadius, - materialTapTargetSize: - widget.checkBoxProperty?.materialTapTargetSize, - visualDensity: - widget.checkBoxProperty?.visualDensity, - focusNode: widget.checkBoxProperty?.focusNode, - autofocus: - widget.checkBoxProperty?.autofocus ?? false, - shape: widget.checkBoxProperty?.shape, - side: widget.checkBoxProperty?.side, - ), - ], + Checkbox( + value: multiSelectionValue[index], + onChanged: (value) { + if (value != null) { + setState(() { + multiSelectionValue[index] = value; + }); + } + }, + tristate: + widget.checkBoxProperty?.tristate ?? false, + mouseCursor: widget.checkBoxProperty?.mouseCursor, + activeColor: widget.checkBoxProperty?.activeColor, + fillColor: widget.checkBoxProperty?.fillColor, + checkColor: widget.checkBoxProperty?.checkColor, + focusColor: widget.checkBoxProperty?.focusColor, + hoverColor: widget.checkBoxProperty?.hoverColor, + overlayColor: + widget.checkBoxProperty?.overlayColor, + splashRadius: + widget.checkBoxProperty?.splashRadius, + materialTapTargetSize: widget + .checkBoxProperty?.materialTapTargetSize, + visualDensity: + widget.checkBoxProperty?.visualDensity, + focusNode: widget.checkBoxProperty?.focusNode, + autofocus: + widget.checkBoxProperty?.autofocus ?? false, + shape: widget.checkBoxProperty?.shape, + side: widget.checkBoxProperty?.side, + ), + ], + ), ), - ), - ); - }), - ), - ), - Row( - children: [ - const Expanded( - child: SizedBox.shrink(), + ); + }), ), - Padding( - padding: const EdgeInsets.only( - right: 8.0, left: 8.0, top: 15, bottom: 10), - child: InkWell( - onTap: () => widget.onChanged(multiSelectionValue), - child: Container( - height: widget.listTileHeight * 0.9, - padding: - const EdgeInsets.symmetric(vertical: 5.0, horizontal: 12), - decoration: BoxDecoration( - color: widget.buttonColor ?? Colors.green, - borderRadius: - const BorderRadius.all(Radius.circular(12))), - child: Align( - child: FittedBox( - fit: BoxFit.contain, - child: Text( - widget.buttonText ?? "Ok", - style: widget.buttonTextStyle ?? - const TextStyle(fontWeight: FontWeight.bold), + ), + Row( + children: [ + const Expanded( + child: SizedBox.shrink(), + ), + Padding( + padding: const EdgeInsets.only( + right: 8.0, left: 8.0, top: 15, bottom: 10), + child: InkWell( + onTap: () => widget.onChanged(multiSelectionValue), + child: Container( + height: widget.listTileHeight * 0.9, + padding: const EdgeInsets.symmetric( + vertical: 5.0, horizontal: 12), + decoration: BoxDecoration( + color: widget.buttonColor ?? Colors.green, + borderRadius: + const BorderRadius.all(Radius.circular(12))), + child: Align( + child: FittedBox( + fit: BoxFit.contain, + child: Text( + widget.buttonText ?? "Ok", + style: widget.buttonTextStyle ?? + const TextStyle(fontWeight: FontWeight.bold), + ), ), ), ), ), ), - ), - ], - ), - ], + ], + ), + ], + ), ); } } diff --git a/lib/single_selction.dart b/lib/single_selction.dart index c257bba..bf1b973 100644 --- a/lib/single_selction.dart +++ b/lib/single_selction.dart @@ -3,29 +3,30 @@ import 'package:flutter/material.dart'; import 'dropdown_textfield.dart'; class SingleSelection extends StatefulWidget { - const SingleSelection( - {Key? key, - required this.dropDownList, - required this.onChanged, - required this.height, - required this.enableSearch, - required this.searchHeight, - this.searchTextStyle, - required this.searchFocusNode, - required this.mainFocusNode, - this.searchKeyboardType, - required this.searchAutofocus, - this.searchShowCursor, - required this.mainController, - required this.autoSort, - required this.listTileHeight, - this.onSearchTap, - this.onSearchSubmit, - this.listTextStyle, - this.searchDecoration, - required this.listPadding, - this.clearIconProperty}) - : super(key: key); + const SingleSelection({ + Key? key, + required this.dropDownList, + required this.onChanged, + required this.height, + required this.enableSearch, + required this.searchHeight, + this.searchTextStyle, + required this.searchFocusNode, + required this.mainFocusNode, + this.searchKeyboardType, + required this.searchAutofocus, + this.searchShowCursor, + required this.mainController, + required this.autoSort, + required this.listTileHeight, + this.onSearchTap, + this.onSearchSubmit, + this.listTextStyle, + this.searchDecoration, + required this.listPadding, + this.clearIconProperty, + this.overlayDecoration, + }) : super(key: key); final List dropDownList; final ValueSetter onChanged; final double height; @@ -46,6 +47,7 @@ class SingleSelection extends StatefulWidget { final ListPadding listPadding; final InputDecoration? searchDecoration; final IconProperty? clearIconProperty; + final Decoration? overlayDecoration; @override State createState() => _SingleSelectionState(); @@ -98,90 +100,85 @@ class _SingleSelectionState extends State { @override Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (widget.enableSearch) - SizedBox( - height: widget.searchHeight, - child: Padding( - padding: const EdgeInsets.all(12.0), - child: TextField( - style: widget.searchTextStyle, - focusNode: widget.searchFocusNode, - showCursor: widget.searchShowCursor, - keyboardType: widget.searchKeyboardType, - controller: _searchCnt, - onTap: () { - if (widget.onSearchTap != null) { - widget.onSearchTap!(); - } - }, - decoration: _inpDec.copyWith( - hintText: _inpDec.hintText ?? 'Search Here...', - suffixIcon: GestureDetector( - onTap: () { - widget.mainFocusNode.requestFocus(); - _searchCnt.clear(); - onItemChanged(""); - }, - child: widget.searchFocusNode.hasFocus - ? InkWell( - child: Icon( - widget.clearIconProperty?.icon ?? Icons.close, - size: widget.clearIconProperty?.size, - color: widget.clearIconProperty?.color, - ), - ) - : const SizedBox.shrink(), + return Container( + decoration: widget.overlayDecoration, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (widget.enableSearch) + SizedBox( + height: widget.searchHeight, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: TextField( + style: widget.searchTextStyle, + focusNode: widget.searchFocusNode, + showCursor: widget.searchShowCursor, + keyboardType: widget.searchKeyboardType, + controller: _searchCnt, + onTap: () { + if (widget.onSearchTap != null) { + widget.onSearchTap!(); + } + }, + decoration: _inpDec.copyWith( + hintText: _inpDec.hintText ?? 'Search Here...', + suffixIcon: GestureDetector( + onTap: () { + widget.mainFocusNode.requestFocus(); + _searchCnt.clear(); + onItemChanged(""); + }, + child: widget.searchFocusNode.hasFocus + ? InkWell( + child: Icon( + widget.clearIconProperty?.icon ?? Icons.close, + size: widget.clearIconProperty?.size, + color: widget.clearIconProperty?.color, + ), + ) + : const SizedBox.shrink(), + ), ), + onChanged: onItemChanged, + onSubmitted: (val) { + widget.mainFocusNode.requestFocus(); + if (widget.onSearchSubmit != null) { + widget.onSearchSubmit!(); + } + }, ), - onChanged: onItemChanged, - onSubmitted: (val) { - widget.mainFocusNode.requestFocus(); - if (widget.onSearchSubmit != null) { - widget.onSearchSubmit!(); - } - }, ), ), - ), - SizedBox( - height: widget.height, - child: Scrollbar( - child: ListView.builder( - padding: EdgeInsets.zero, - itemCount: newDropDownList.length, - itemBuilder: (BuildContext context, int index) { - return SizedBox( - height: widget.listTileHeight + - widget.listPadding.top + - widget.listPadding.bottom, - child: Padding( - padding: EdgeInsets.only( - right: 10, - left: 10, - bottom: widget.listPadding.bottom, - top: widget.listPadding.top), - child: InkWell( - onTap: () { - widget.onChanged(newDropDownList[index]); - }, - child: Row( - children: [ - newDropDownList[index].prefixWidget ?? - const SizedBox.shrink(), - Text(newDropDownList[index].name, - style: widget.listTextStyle), - ], - )), - ), - ); - }, + SizedBox( + height: widget.height, + child: Scrollbar( + child: ListView.builder( + padding: EdgeInsets.zero, + itemCount: newDropDownList.length, + itemBuilder: (BuildContext context, int index) { + return SizedBox( + height: widget.listTileHeight, + child: Padding( + padding: EdgeInsets.only( + right: 10, + left: 10, + bottom: widget.listPadding.bottom, + top: widget.listPadding.top), + child: InkWell( + onTap: () { + widget.onChanged(newDropDownList[index]); + }, + child: Text(newDropDownList[index].name, + style: widget.listTextStyle)), + ), + ); + }, + ), ), ), - ), - ], + ], + ), ); } }