'Unhandled Exception: type '(Currency?) => Null' is not a subtype of type '(dynamic) => dynamic' [duplicate]

I am trying to add a wrapper around DropdownButton, But I am getting the below exception, I tried calling onChanged property directly in the block body as below

 onChanged: (T? newValue) {
   widget.onChanged(newValue!);
}

But, it doesn't seem to make any difference.

Launching lib/main.dart on iPhone 12 Pro in debug mode...
lib/main.dart:1
Xcode build done.                                           28.2s
Connecting to VM Service at ws://127.0.0.1:64267/kXwziwCdk9M=/ws
[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: type '(Currency?) => Null' is not a subtype of type '(dynamic) => dynamic'
#0      _EmDropdownButtonState.build.<anonymous closure>
package:new_app/main.dart:34
#1      _DropdownButtonState._handleTap.<anonymous closure>
package:flutter/…/material/dropdown.dart:1284
#2      _rootRunUnary (dart:async/zone.dart:1434:47)
#3      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
<asynchronous suspension>

Here's the complete code sample

import 'package:flutter/material.dart';

class EmDropdownButton<T> extends StatefulWidget {
  final List<T> items;
  final Function(T?) onChanged;
  final T? value;
  final Widget Function(T) dropdownItem;

  const EmDropdownButton(
      {Key? key,
      required this.items,
      required this.onChanged,
      required this.dropdownItem,
      required this.value})
      : super(key: key);

  @override
  State<EmDropdownButton> createState() => _EmDropdownButtonState();
}

class _EmDropdownButtonState<T> extends State<EmDropdownButton<T>> {
  @override
  Widget build(BuildContext context) {
    return DropdownButton<T>(
      value: widget.value,
      isExpanded: true,
      icon: const Icon(Icons.keyboard_arrow_down_rounded),
      iconSize: 24,
      style: const TextStyle(color: Colors.deepPurple),
      underline: Container(
        height: 2,
        color: Colors.deepPurpleAccent,
      ),
      onChanged: (T? newValue) => widget.onChanged(newValue!),
      menuMaxHeight: 200,
      items: widget.items.map<DropdownMenuItem<T>>((T value) {
        return DropdownMenuItem<T>(
            value: value, child: widget.dropdownItem(value));
      }).toList(),
    );
  }
}

class Currency {
  final String name;
  final String symbol;
  final String code;

  Currency({required this.name, required this.symbol, required this.code});

  Currency.init() : this(name: 'Indian Rupee', symbol: '₹', code: 'INR');

  @override
  bool operator ==(Object other) =>
      other is Currency &&
      other.name == name &&
      other.code == code &&
      other.symbol == symbol;
}

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late Currency currency;
  @override
  void initState() {
    super.initState();
    currency = Currency.init();
  }


List<Currency> currencyList = [
  Currency(code: 'INR', name: 'Indian Rupee', symbol: '₹'),
  Currency(code: 'USD', name: 'US Dollar', symbol: '\$'),
  Currency(code: 'EUR', name: 'Euro', symbol: '€'),
];


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            SizedBox(
              width: 160,
              child: EmDropdownButton<Currency>(
                value: currency,
                dropdownItem: (dynamic x) => Text(x.name),
                items: currencyList,
                onChanged: (Currency? newValue) {
                  setState(() {
                    currency = newValue!;
                  });
                },
              ),
            ),
            Text(
              '_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
    );
  }
}

The second issue is, If I don't specify dynamic here

dropdownItem: (dynamic x) => Text(x.name),

I get the following exception

Exception has occurred.
_TypeError (type '(Currency) => Text' is not a subtype of type '(dynamic) => Widget')


Solution 1:[1]

I was able to fix the issue by specifying the generic Type to createState

@override
State<EmDropdownButton> createState() => _EmDropdownButtonState();

to

@override
State<EmDropdownButton<T>> createState() => _EmDropdownButtonState();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mahesh Jamdade