在 void 函数中使用 setState 并得到 void function(dynamic) cannot be assigned to the parameter type 'void Function()' 的警告

Using setState in void function and get a warning that the void function(dynamic) cannot be assigned to the parameter type 'void Function()'

我收到一条警告,指出参数类型 'void Function(dynamic)' 无法分配给参数类型 'void Function()',它位于字符串对话框文本的正下方。我使用此函数将数据从子小部件 TopAppBar 传递到父小部件 MyApp。在子小部件 TopAppBar 中,我使用 TextFormField 键入单词以在提交时更改文本。

我看了其他代码都没有问题,所以我不知道如何解决这个问题。

请帮帮我!谢谢!

class MyApp extends StatefulWidget {
  MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int count = 0;
  var nameList = ['one','two','three','four'];
  String dialogText = "Hello!";

  void _changeDialogText(value){
    setState((value){
      dialogText = value;
    });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
            appBar: TopAppBar(state: _changeDialogText,),
            body: Column(
              children: [
                Container(
                  height: 400,
                  child: (
                    ListView(
    children: List.generate(
        nameList.length, (index) => CustomListTile(title: nameList[index])),
                    )
                  )
                ),
                Container(
                  height: 20, child: Text(count.toString())
                ),
                Container(
                    height: 20, child: Text(dialogText)
                ),
              ],
            ),
          floatingActionButton: FloatingActionButton(
            child: Text('Button'),
            onPressed: (){
              print('a');
              setState(
                  (){
                    count++;
                  }
              );
            },
          ),
          bottomNavigationBar: BottomBar(),
            floatingActionButtonLocation: FloatingActionButtonLocation.endDocked
        );

  }
}
class TopAppBar extends StatefulWidget  with PreferredSizeWidget{
  const TopAppBar({Key? key, required this.state(value)}) : super(key: key);
  final Function(String value) state;

  @override
  Size get preferredSize => Size.fromHeight(kToolbarHeight);
  State<TopAppBar> createState() => _TopAppBarState();
}


class _TopAppBarState extends State<TopAppBar> {
  final TopAppBarData _topAppBarData = TopAppBarData();
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  @override

  Widget build(BuildContext context) {
    return Form(
      child:
        AppBar(
            flexibleSpace: Container(
              decoration: BoxDecoration(
                  gradient: LinearGradient(
                      begin: Alignment.centerLeft,
                      end: Alignment.centerRight,
                      colors: <Color>[Color.fromRGBO(180, 44, 77, 1) , Color.fromRGBO(242, 114, 59, 1)]
                  )
              ),
            ),
          elevation: 0.0,
          centerTitle: false,
          title: Row(
            children: [
              Text(
                'SSG',
                style: TextStyle(
                  color: Colors.white,
                ),
              ),
              Icon(
                Icons.expand_more,
                color: Colors.black,
              )
            ],
          ),
          actions: [
            Padding(
                padding: EdgeInsets.only(right: 30.0),
                child: IconButton(
                  icon: Icon(Icons.search),
                    color: Colors.black,
                  onPressed: (){
                    showDialog(context: context, builder: (context){
                      return AlertDialog(
                        title: Text('Search'),
                        content: TextFormField(
                          onChanged: (value) {
                            widget.state(value);
                          },
                          decoration: InputDecoration(hintText: "Text Field in Dialog"),
                        ),
                        actions: <Widget>[
                          ElevatedButton(
                            child: Text('CANCEL'),
                            onPressed: () {
                              setState(() {
                                Navigator.pop(context);
                              });
                            },
                          ),
                          ElevatedButton(
                            child: Text('OK'),
                            onPressed: () {
                              setState(() {
                                Navigator.pop(context);
                              });
                            },
                          ),
                        ],
                      );
                    });
                  },
                )
            ),
            Padding(
                padding: EdgeInsets.only(right: 30.0),
                child: GestureDetector(
                  onTap: () {},
                  child: Icon(
                    Icons.menu,
                    color: Colors.black,
                  ),
                )
            ),
            Padding(
                padding: EdgeInsets.only(right: 30.0),
                child: GestureDetector(
                  onTap: () {},
                  child: Icon(
                    Icons.notification_add,
                    color: Colors.black,
                  ),
                )
            ),
          ],
        ),
    );
  }
}

改变这个

void _changeDialogText(value){
    setState((value){
      dialogText = value;
    });
  }

void _changeDialogText(String value){
        setState((value){
          dialogText = value;
        });
      }

如果省略类型,编译器会假定为 dynamic。不要那样做。打开你的 linter(它应该默认打开),它会警告你。

final /* --> */ void /* <-- */  Function(String value) state;

void _changeDialogText( /* --> */ String /* <-- */ value){

现在,签名匹配了。

setState() 函数不向回调传递任何参数。代码应如下所示:

setState(() {
    dialogText = value;
});

您的问题源于您设置状态的方式。 setState 函数采用 void Function() 参数,如下所示:

package:flutter/src/widgets/framework.dart 
void setState(void Function() fn)  
Containing class: State  Type: void Function(void Function())

但是,您添加了 dynamic 类型的不必要参数 value。 改变

 void _changeDialogText(value){
     setState((value){
         dialogText = value;
     });
 }

 void _changeDialogText(String value){
     setState((){
         dialogText = value;
    });
 }

将消除该警告。但是您可能需要考虑使用显式类型并通过添加 implicit-dynamic to your analysis options file.

来强制使用

此外,在构造函数中初始化 final Function(String value) state; 变量时,您使用:

const TopAppBar({Key? key, required this.state(value)}) : super(key: key);

但是,这是不必要的,并且缺少“值”参数的类型。所以你可以改用这个:

const TopAppBar({Key? key, required this.state}) : super(key: key);