flutter_smart_select icon indicating copy to clipboard operation
flutter_smart_select copied to clipboard

Error in null safe version

Open SeriousMonk opened this issue 5 years ago • 5 comments

I can't figure out whether I'm doing something wrong or there is a problem with this null-safe version. I'm getting the following error:

E/flutter (13256): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: type '(List<String?>?) => Future<List<S2Choice<String?>>?>' is not a subtype of type '((List<String>?) => Future<List<S2Choice<String>>?>)?' of 'defaultResolver'
E/flutter (13256): #0      S2MultiState.resolveSelected (package:smart_select/src/widget.dart:1964:11)
E/flutter (13256): #1      S2State.initState (package:smart_select/src/widget.dart:1669:5)

My code is the following:

class SmartMultiSelectBuilder extends FormField<List<String>>{
  final FormFieldValidator<List<String>>? validator;
  final List<Map<String, String>> choiceItems;
  final String title;
  final String? placeholder;
  final List<String>? initialValue;
  final bool isGrouped;
  final IconData icon;
  final Function(List<String>?) onChanged;

  SmartMultiSelectBuilder({
    this.validator,
    required this.choiceItems,
    required this.title,
    this.placeholder,
    this.initialValue,
    this.isGrouped = false,
    required this.icon,
    required this.onChanged,
  }) : super(
      initialValue: initialValue,
      validator: validator,
      builder: (FormFieldState<List<String>> state){
        print(initialValue);
        return Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            SmartSelect.multiple(
              title: title,
              placeholder: 'placeholder',
              selectedValue: initialValue,

              modalConfig: S2ModalConfig(
                type: S2ModalType.bottomSheet,
                headerStyle: S2ModalHeaderStyle(
                  textStyle: smallTitleStyle,
                  elevation: 3,
                ),
                style: S2ModalStyle(
                  backgroundColor: Colors.white,
                  clipBehavior: Clip.antiAlias,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(kBorderRadius),
                      topRight: Radius.circular(kBorderRadius)
                    )
                  )
                ),
              ),

              choiceGrouped: isGrouped,
              groupConfig: S2GroupConfig(
                useCounter: true,
                headerStyle: S2GroupHeaderStyle(
                    backgroundColor: themeOrangeColor,
                    textStyle: regularTextStyle.copyWith(color: Colors.white)
                )
              ),

              choiceConfig: S2ChoiceConfig(
                  useDivider: true,
                  style: S2ChoiceStyle(
                    padding: EdgeInsets.symmetric(horizontal: 5),
                    accentColor: themeOrangeColor, //fill color of checkbox
                    color: Colors.black12, //outline of checkbox
                  )
              ),
              choiceItems: S2Choice.listFrom<String, Map>(
                source: choiceItems,
                value: (index, item) => item['value']!,
                title: (index, item) => item['title']!,
                group: (index, item) => item['group']!,
              ),

              onChange: (selectState){
                onChanged(selectState!.value as List<String>?);
                state.didChange(selectState.value as List<String>?);
              },

              choiceBuilder: (context, state, choice){
                return ListTile(
                  onTap: () => choice.select!(!choice.selected),
                  title: Text(choice.title!, style: thinTextStyle),
                  tileColor: Colors.white,
                  contentPadding: EdgeInsets.symmetric(horizontal: 15),
                  trailing: Checkbox(
                    checkColor: Colors.white,
                    activeColor: themeOrangeColor,
                    value: choice.selected,
                    onChanged: (value) => choice.select!(!choice.selected),
                  ),
                );
              },
              choiceDividerBuilder: (context, index){
                return Container(
                  color: Colors.white,
                  padding: EdgeInsets.symmetric(horizontal: 6),
                  child: Divider(
                    color: Colors.black26,
                    height: 1,
                    thickness: 0.3,
                  ),
                );
              },
              tileBuilder: (context, selectState) {
                return Column(
                  children: [
                    Container(
                      alignment: Alignment.centerLeft,
                      decoration: kBoxDecorationStyle.copyWith(
                        border: Border.all(
                          color: state.hasError ? Colors.red : Colors.transparent
                        )
                      ),
                      height: 60.0,
                      child: ListTile(
                        contentPadding: EdgeInsets.symmetric(horizontal: 13.5),
                        leading: FaIcon(icon, color: themeOrangeColor),
                        title: Transform(
                          transform: Matrix4.translationValues(-20, 0.0, 0.0),
                          child: selectState.selected.toString() == 'placeholder' ? //se nessun elemento è selezionato valueDisplay restituisce il placeholder
                          Text(placeholder!, style: hintTextStyle) :
                          Text(
                            selectState.selected.toString(),
                            style: textFieldStyle,
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                        trailing: FaIcon(
                            FontAwesomeIcons.angleRight,
                            color: Colors.black26,
                            size: 18
                        ),
                        onTap: () => selectState.showModal(),
                      ),
                    ),
                  ],
                );
              },
            ),
            state.hasError?
            Padding(
              padding: EdgeInsets.fromLTRB(20, 3, 0, 0),
              child: Text(
                state.errorText!,
                style: thinTextStyle.copyWith(color: Colors.red)
              ),
            ) :
            Container()
          ],
        );
      }
  );
}

Originally posted by @FRANIAZA in https://github.com/davigmacode/flutter_smart_select/issues/76#issuecomment-820548315

SeriousMonk avatar Apr 16 '21 15:04 SeriousMonk

I think it's the same as #86

simonkimi avatar Apr 28 '21 13:04 simonkimi

@simonkimi that solution produces:

DON'T import implementation files from another package.

https://dart-lang.github.io/linter/lints/implementation_imports.html

RicardoRB avatar May 19 '21 14:05 RicardoRB

@simonkimi that solution produces:

DON'T import implementation files from another package.

https://dart-lang.github.io/linter/lints/implementation_imports.html

But is there any other solution?

simonkimi avatar May 19 '21 14:05 simonkimi

@simonkimi that solution produces: DON'T import implementation files from another package. https://dart-lang.github.io/linter/lints/implementation_imports.html

But is there any other solution?

Good question as the package was developed, it must be refactored and changed somehow to not use this kind of structure.

RicardoRB avatar May 19 '21 16:05 RicardoRB

I released https://pub.dev/packages/flutter_awesome_select with fixed null safety. Could you check that everything works for you?

vasilich6107 avatar Nov 12 '21 23:11 vasilich6107

Hi everyone,

I'm really sorry for not maintaining the smart_select package in a long time. It's been a great project, but it's become too difficult for me to maintain, especially since I've been going through a tough time for the past few years.

In its place, I've released a new package called choice. The combination to smart_select and chips_choice with cleaner, more flexible, and composable API for creating inline or prompted choice widgets with single or multiple selection.

I hope you'll check out choice. I think you'll find it to be a great replacement for smart_select.

Thanks for your understanding.

davigmacode avatar Aug 26 '23 10:08 davigmacode