Flutter - 如何在下拉列表和其他 flutter 功能中包含其他值?

Flutter - How to include other values in dropdown and other flutter features?

您好,我想弄清楚这个问题已经很久了,但仍然不确定如何在下拉列表中传递值...

Provider-Category:

import 'package:flutter/foundation.dart';
class Category with ChangeNotifier {
  final String id;
  final String title;
  Category({
    @required this.id,
    @required this.title,
  });
}

Provider-Categories:

import 'package:flutter/material.dart';
import './category.dart';
class Categories with ChangeNotifier {
  List < Category > _items = [
    Category(
      id: 'id1',
      title: 'Default',
    ),
    Category(
      id: 'id2',
      title: 'French Lesson',
    ),
    Category(
      id: 'id3',
      title: 'Spanish Lesson',
    ),
  ];
}

屏幕:

1.I 如果没有其他类别,则需要最初选择默认选项,否则选择列表中的最后一个

2.If drop-down 选定的选项已更改并且按下图标列表它应该传递选定的值(id 和 title)

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/categories.dart';
...
void getDropDownItem(BuildContext ctx) {
  setState(() {
    Navigator.of(ctx).pushNamed(
      CategoryNotesScreen.routeName,
      arguments: { //on this part, i'm not sure how will I get the values of selected option in dropdown (ID and title) onpress of icon?
        'id': catId,
        'title': catTitle
      }
    );
  });
}
@override
Widget build(BuildContext context) {
  ...
  final categoriesData = Provider.of < Categories > (context);
  final categoriesDataItems = categoriesData.items;
  ...
  appBar: AppBar(
    title: const Text("New Note"),
      actions: < Widget > [
        IconButton(
          icon: const Icon(
              Icons.list),
            onPressed: () => getDropDownItem(context),
        ),
      ],
  ),
  ...
  child: DropdownButtonFormField(
    items: categoriesDataItems.map((categoriesDataItemsMap) => DropdownMenuItem(
      child: Text(categoriesDataItemsMap.title),
      value: categoriesDataItemsMap.id,
    ), ).toList(),
    value: selectedCatId,
    onChanged: (newValue) {
      setState(() {
        print(newValue);
        selectedCatId = newValue;
      });
    },
  ),
}

新屏幕:我需要获取选定的类别参数以显示类别标题,并能够在从列表中筛选时使用类别 ID。

import 'package:flutter/material.dart';
class CategoryNotesScreen extends StatelessWidget {
  static
  const routeName = '/category-notes';
  @override
  Widget build(BuildContext context) {
    final routeArgs =
      ModalRoute.of(context).settings.arguments as Map < String, String > ;
    print('cat_notes_screen');
    print(routeArgs);
    final catId = routeArgs['id'];
    final catTitle = routeArgs['title'];
    return Scaffold(
      appBar: AppBar(
        title: Text('catTitle'),
      ),
      body: Center(
        child: Text(
          'The Recipes For The Category!',
        ),
      ),
    );
  }
}

抱歉,我是 flutter 的新手,仍在学习中...

也许使用 FutureBuilder 和 ListView

您可以复制粘贴运行下面的完整代码
您可以在下面看到工作演示
第 1 步:CategoryNotesScreen 得到 arguments

Category routeArgs = ModalRoute.of(context).settings.arguments;

第 2 步:getDropDownItem 通过 selectedCategory

Category selectedCategory;

void getDropDownItem(BuildContext ctx) {
    setState(() {
      Navigator.of(ctx).pushNamed(CategoryNotesScreen.routeName,
          arguments: selectedCategory);
    });
  }

第 3 步:设置默认 selectedCategory,您可以使用 categoriesDataItems.firstlast

  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final categoriesData = Provider.of<Categories>(context, listen: false);
      final categoriesDataItems = categoriesData.items;
      setState(() {
        selectedCategory = categoriesDataItems.first;
      });
    });
    super.initState();
  }

第 4 步:使用 DropdownButtonFormField<Category>

DropdownButtonFormField<Category>(
      items: categoriesDataItems
          .map(
            (categoriesDataItemsMap) => DropdownMenuItem(
              child: Text(categoriesDataItemsMap.title),
              value: categoriesDataItemsMap,
            ),
          )
          .toList(),
      value: selectedCategory,
      onChanged: (newValue) {
        setState(() {
          print(newValue);
          selectedCategory = newValue;
        });
      },
    ),

工作演示

完整代码

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

class Category {
  final String id;
  final String title;
  Category({
    @required this.id,
    @required this.title,
  });
}

class Categories with ChangeNotifier {
  List<Category> items = [
    Category(
      id: 'id1',
      title: 'Default',
    ),
    Category(
      id: 'id2',
      title: 'French Lesson',
    ),
    Category(
      id: 'id3',
      title: 'Spanish Lesson',
    ),
  ];
}

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => Categories(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: '/',
      routes: {
        '/': (context) => MyHomePage(
              title: "test",
            ),
        '/category-notes': (context) => CategoryNotesScreen(),
      },
    );
  }
}

class CategoryNotesScreen extends StatelessWidget {
  static const routeName = '/category-notes';

  @override
  Widget build(BuildContext context) {
    Category routeArgs = ModalRoute.of(context).settings.arguments;
    print('cat_notes_screen');
    print(routeArgs);
    final catId = routeArgs.id;
    final catTitle = routeArgs.title;
    return Scaffold(
      appBar: AppBar(
        title: Text('catTitle $catTitle'),
      ),
      body: Center(
        child: Text(
          '$catId $catTitle The Recipes For The Category!',
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  Category selectedCategory;

  void getDropDownItem(BuildContext ctx) {
    setState(() {
      Navigator.of(ctx).pushNamed(CategoryNotesScreen.routeName,
          arguments: selectedCategory);
    });
  }

  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final categoriesData = Provider.of<Categories>(context, listen: false);
      final categoriesDataItems = categoriesData.items;
      setState(() {
        selectedCategory = categoriesDataItems.first;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final categoriesData = Provider.of<Categories>(context);
    final categoriesDataItems = categoriesData.items;

    return Scaffold(
      appBar: AppBar(
        title: const Text("New Note"),
        actions: <Widget>[
          IconButton(
            icon: const Icon(Icons.list),
            onPressed: () => getDropDownItem(context),
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            DropdownButtonFormField<Category>(
              items: categoriesDataItems
                  .map(
                    (categoriesDataItemsMap) => DropdownMenuItem(
                      child: Text(categoriesDataItemsMap.title),
                      value: categoriesDataItemsMap,
                    ),
                  )
                  .toList(),
              value: selectedCategory,
              onChanged: (newValue) {
                setState(() {
                  print(newValue);
                  selectedCategory = newValue;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}