如何在 Flutter 中设计 DropdownButtonFormField 中的对话框?

how to design dialog box inside DropdownButtonFormField in flutter?

我有 DropdownButtonFormField 当我点击它时应该出现一个带有项目列表的对话框,所以我可以 select 一个项目并且它应该 return DropdownButtonFormField.I 中的 selected 项尝试使用 DropdownMenuItem 但我需要使用 DialogBox 以便它看起来不错。 所以基本上我想用 DialogBox 替换 DropdownMenuItem。而且我不知道该怎么做,我是新手,请帮助我。下面我会附上我想要得到的图片

 import 'package:flutter/material.dart';
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Dialog Box and return value',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
    
      @override
      State<StatefulWidget> createState() {
        return MyHomePageState();
      }
    }
    
    class MyHomePageState extends State<MyHomePage> {
      String  selectedLanguage =" ";
      var javascript ="java";
      var c = "C";
      var cpp = "C++";
      var python = "Python";
    
      @override
      Widget build(BuildContext context) {
        return Scaffold (
            appBar: AppBar(
                title: Text("Flutter SimpleDialog Example")
            ),
            body: Container(
              color: Colors.grey,
              child: Center (
                  child: Column (
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Container(
                          color: Colors.white,
                          height: 50,
                          width: 150,
                          child: DropdownButtonFormField(
                            items: [],
                            hint: Text("Select"),
                          ),
                        ),
                      ]
                  )
              ),
            )
        );
      }
    
      showMyAlertDialog(BuildContext context) {
    
        // Create SimpleDialog
        SimpleDialog dialog = SimpleDialog(
          title: const Text('Select a Language:'),
          children: <Widget>[
            SimpleDialogOption(
                onPressed: () {
                  // Close and return value
                  Navigator.pop(context, javascript);
                },
                child: Text(javascript)
            ),
            SimpleDialogOption(
              onPressed: () {
                // Close and return value
                Navigator.pop(context, c);
              },
              child:  Text(c),
            ),
            SimpleDialogOption(
              onPressed: () {
                // Close and return value
                Navigator.pop(context, cpp);
              },
              child:  Text(cpp),
            ),
            SimpleDialogOption(
              onPressed: () {
                // Close and return value
                Navigator.pop(context, python);
              },
              child:  Text(python),
            )
          ],
        );
    
        // Call showDialog function to show dialog.
        Future futureValue = showDialog(
            context: context,
            builder: (BuildContext context) {
              return dialog;
            }
        );
    
        futureValue.then( (language) => {
          this.setState(() {
            this.selectedLanguage = language;
          })
        });
      }
    
    }

我添加了一些评论,可以帮助您理解我应用的概念。

void main() => runApp(
      const MaterialApp(
        home: MyApp(),
      ),
    );

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dialog Box and return value',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<StatefulWidget> createState() {
    return MyHomePageState();
  }
}

class MyHomePageState extends State<MyHomePage> {
  String? selectedLanguage;

  List<String> languages = ["java", "C", "C++", "Python"];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Flutter SimpleDialog Example")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Container(
              color: Colors.white,
              height: 50,
              width: 150,
              child: InkWell(
                  onTap: () async {
                    showMyAlertDialog(context);
                  },
                  child: Container(
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text("${selectedLanguage ?? 'Select'}   "),
                        const Icon(
                          Icons.arrow_drop_down,
                        ),
                      ],
                    ),
                  )
                  //  DropdownButtonFormField(
                  //   items: [],
                  //   hint: Text("Select"),
                  // ),
                  ),
            ),
          ],
        ),
      ),
    );
  }

  showMyAlertDialog(BuildContext context) {
    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          content: StatefulBuilder(
            //* dialog is on different widget Tree. check dev-tools
            builder: (context, setStateD) {
              return Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text("Language"),
                  const SizedBox(width: 12),
                  Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      ...List.generate(
                        languages.length,
                        (index) => item(
                          text: languages[index], //sent String
                          isSelected: languages[index] ==
                              selectedLanguage, //check it is selected or not
                          ontap: () {
                            /// for inner dialog changes
                            setStateD(() {
                              selectedLanguage = languages[index];
                            });
                            Navigator.of(context)
                                .pop(); // if you wish to close the dilog on Select

                            setState(() {
                              //* for class state changes
                              selectedLanguage = languages[index];
                            });
                            print(selectedLanguage);
                          },
                        ),
                      )
                    ],
                  )
                ],
              );
            },
          ),
        );
      },
    );
  }

  Widget item(
      {required String text,
      required bool isSelected,
      required Function ontap}) {
    return Padding(
      padding: const EdgeInsets.only(
        bottom: 4,
      ),
      child: InkWell(
        onTap: () => ontap(),
        child: Row(
          children: [
            Text(text),
            const SizedBox(
              width: 10,
            ),
            if (isSelected)
              const Icon(Icons
                  .check), // show only check while it is selected, or you can use the same logic on Main row item
          ],
        ),
      ),
    );
  }
}