Want to close a drop down menu in multi_select

24 Views Asked by At
library multiselect;

import 'package:flutter/material.dart';
import 'package:states_rebuilder/states_rebuilder.dart';

class _TheState {}

var _theState = RM.inject(() => _TheState());

class RowWrapper extends InheritedWidget {
  final dynamic data;
  final bool Function() shouldNotify;
  RowWrapper({
    required Widget child,
    this.data,
    required this.shouldNotify,
  }) : super(child: child);

  @override
  bool updateShouldNotify(covariant InheritedWidget oldWidget) {
    return true;
  }
}

class _SelectRow extends StatefulWidget {
  final Function(bool) onChange;
  final bool selected;
  final String text;
  final String price;
  final Color textColor;
  final Function(String) onPriceChanged;
  final void Function(List<String>, String) onSavePressed;


  _SelectRow({
    Key? key,
    required this.onChange,
    required this.selected,
    required this.text,
    required this.price,
    required this.onPriceChanged,
    required this.onSavePressed,
    this.textColor = Colors.blue,
  }) : super(key: key);

  @override
  _SelectRowState createState() => _SelectRowState();
}

class _SelectRowState extends State<_SelectRow> {
  bool isSelected = false;

  @override
  void initState() {
    super.initState();
    isSelected = widget.selected;
  }

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        isSelected = !isSelected;
        widget.onChange(isSelected);
        widget.onPriceChanged(widget.price);
        setState(() {});
      },
      child: Container(
        height: kMinInteractiveDimension,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Checkbox(
              value: isSelected,
              onChanged: (x) {
                isSelected = x!;
                widget.onChange(x);
                widget.onPriceChanged(widget.price);
                setState(() {});
              },
            ),
            Text(
              widget.text,
              style: TextStyle(color: widget.textColor),
            ),
            SizedBox(width: 8), // Add some spacing
            Expanded(
              child: GestureDetector(
                onTap: () {
                  _editPrice(context);
                },
                child: Text(
                  widget.price,
                  style: TextStyle(color: widget.textColor),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
void _editPrice(BuildContext context) {
  showDialog(
    context: context,
    builder: (BuildContext context) {
      String editedPrice = widget.price; // Track the edited price

      return AlertDialog(
        title: Text("Edit Price"),
        content: TextFormField(
          initialValue: widget.price,
          keyboardType: TextInputType.numberWithOptions(decimal: true),
          onChanged: (newPrice) {
            // Update the edited price
            editedPrice = newPrice;
            widget.onPriceChanged(newPrice);
            setState(() {});
          },
        ),
        actions: <Widget>[
          TextButton(
            onPressed: () {
              Navigator.of(context).pop();
            },
            child: Text("Cancel"),
          ),
          TextButton(
            onPressed: () {
              // Call onSavePressed with the edited price and relevant values
              widget.onSavePressed([widget.price], editedPrice);
              Navigator.of(context).pop();
            },
            child: Text("Save"),
          ),
        ],
      );
    },
  );
}

}

class DropDownMultiSelect<T> extends StatefulWidget {
  final List<T> options;
  final List<T> selectedValues;
  final List<String> prices;
  //final Function(List<T>, List<String>) onChanged;
  final Function(List<T>, List<String>) onChanged;
  final bool isDense;
  final bool enabled;
  final InputDecoration? decoration;
  final String? whenEmpty;
  final Widget Function(List<T> selectedValues)? childBuilder;
  final Widget Function(T option)? menuItembuilder;
  final String Function(T? selectedOptions)? validator;
  final bool readOnly;
  final Widget? icon;
  final TextStyle? hintStyle;
  final Widget? hint;
  final TextStyle? selected_values_style;
  final List<String> selectedAmountValues;
  final void Function(List<String>, String) onSavePressed;


  const DropDownMultiSelect({
    Key? key,
    required this.options,
    required this.selectedValues,
    required this.prices,
    required this.onChanged,
    this.whenEmpty,
    this.icon,
    this.hint,
    this.hintStyle,
    this.childBuilder,
    this.selected_values_style,
    this.menuItembuilder,
    this.isDense = true,
    this.enabled = true,
    this.decoration,
    this.validator,
    this.readOnly = false,
    required this.selectedAmountValues,
    required this.onSavePressed,
  }) : super(key: key);

  @override
  _DropDownMultiSelectState createState() => _DropDownMultiSelectState<T>();
}

class _DropDownMultiSelectState<TState>
    extends State<DropDownMultiSelect<TState>> {
  @override

  
  Widget build(BuildContext context) {
    return Container(
      child: Stack(
        alignment: Alignment.centerLeft,
        children: [
          Container(
            child: DropdownButtonFormField<TState>(
           
              hint: widget.hint,
              style: widget.hintStyle,
              icon: widget.icon,
              validator: widget.validator != null ? widget.validator : null,
              decoration: widget.decoration != null
                  ? widget.decoration
                  : InputDecoration(
                      border: OutlineInputBorder(),
                      isDense: true,
                      contentPadding: EdgeInsets.symmetric(
                        vertical: 15,
                        horizontal: 10,
                      ),
                    ),
              isDense: widget.isDense,
              onChanged: widget.enabled ? (x) {} : null,
              isExpanded: false,
              value: widget.selectedValues.length > 0
                  ? widget.selectedValues[0] as TState
                  : null,
              selectedItemBuilder: (context) {
                return widget.options
                    .asMap()
                    .map(
                      (index, x) => MapEntry(
                        index,
                        DropdownMenuItem(
                          child: Container(
                            color: Colors.white,
                          ),
                        ),
                      ),
                    )
                    .values
                    .toList();
              },
              items: widget.options
                  .asMap()
                  .map(
                    (index, x) => MapEntry(
                      index,
                      DropdownMenuItem<TState>(
                         child:
                         _theState.rebuild(() {
                          return widget.menuItembuilder != null
                              ? widget.menuItembuilder!(x)
                              : _SelectRow(
                                  selected: widget.selectedValues.contains(x),
                                  text: x.toString(),
                                  price: widget.prices[index],
                                  onChange: (isSelected) {
                                    var ns = widget.selectedValues;
                                    var sp = widget
                                        .selectedAmountValues; // Update this line

                                    if (isSelected) {
                                      ns.add(x);
                                      sp.add(widget.prices[index]);
                                    } else {
                                      ns.remove(x);
                                      sp.remove(widget.prices[index]);
                                    }

                                    widget.onChanged(ns, sp);
                                  },
                                  onPriceChanged: (newPrice) {
                                    setState(() {
                                      widget.prices[index] = newPrice;
                                    });
                                  },
                                   onSavePressed: (bool , String  ) { 
                                    },
                                );
                        }
                        ),
                        value: x,
                        onTap: !widget.readOnly
                            ? () {
                                if (widget.selectedValues.contains(x)) {
                                  var ns = widget.selectedValues;
                                  var sp = widget
                                      .selectedAmountValues; // Update this line
                                  ns.remove(x);
                                  sp.add(widget.prices[index]);
                                  widget.onChanged(ns, sp);
                                } else {
                                  var ns = widget.selectedValues;
                                  var sp = widget
                                      .selectedAmountValues; // Update this line
                                  ns.add(x);
                                  sp.add(widget.prices[index]);
                                  widget.onChanged(ns, sp);
                                }
                              }
                            : null,
                      ),
                    ),
                  )
                  .values
                  .toList(),
            ),
          ),
          
        ],
      ),
    );
  }
}

in my code whenever i am clicking on the "SAVE" button of the _editPrice dialog the dialog becomes close. I want to close the drop down menu also.At the moment the drop down is cloding when i click otside of the dropdown menu. What code i have to write for that ? Give me the answer as soon as possible .

0

There are 0 best solutions below