點燈坊

失くすものさえない今が強くなるチャンスよ

DropdownButton 使用 map()

Sam Xiao's Avatar 2024-10-17

DropdownButton 可實現進階下拉選單,實務上資料會來自 API 的 List<Map>,可使用 map() 將其轉成 DropdownMenuItem

Version

Flutter 3.24

Flutter

map

  • Android 與 iOS 都成功使用 DropdownButton 顯示
import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  const Home({super.key});

  
  State<Home> createState() {
    return _Home();
  }
}

class _Home extends State<Home> {
  int? _selectedValue = 1;

  var dropdownItems = [
    {'value': 1, 'text': 'One'},
    {'value': 2, 'text': 'Two'},
    {'value': 3, 'text': 'Three'},
  ];

  
  Widget build(BuildContext context) {
    var appBar = AppBar(
      title: const Text('DropdownButton with List<Map>'),
    );

    var dropdownMenuItems = dropdownItems
        .map((item) => DropdownMenuItem<int>(
              value: item['value'] as int,
              child: Text(item['text'] as String),
            ))
        .toList();

    var dropdownButton = DropdownButton<int>(
      value: _selectedValue,
      onChanged: (int? newValue) {
        setState(() {
          _selectedValue = newValue;
        });
      },
      items: dropdownMenuItems,
    );

    var selectedValue = Padding(
      padding: const EdgeInsets.only(left: 16.0),
      child: Text('$_selectedValue'),
    );

    var body = Padding(
      padding: const EdgeInsets.only(left: 16.0),
      child: Row(
        children: [dropdownButton, selectedValue],
      ),
    );

    return Scaffold(
      appBar: appBar,
      body: body,
    );
  }
}

void main() {
  runApp(const MaterialApp(
    home: Home(),
  ));
}

Line 12

class _Home extends State<Home> {
}
  • DropdownButton 必須搭配 StatefulWidget

Line 13

int? _selectedValue = 1;
  • _selectedValue:定義 state 取得目前用戶所選擇的項目

Line 15

var dropdownItems = [
  {'value': 1, 'text': 'One'},
  {'value': 2, 'text': 'Two'},
  {'value': 3, 'text': 'Three'},
];
  • List<Map> 定義 DropdownButton 的資料

Line 34

var dropdownButton = DropdownButton<int>(
  value: _selectedValue,
  onChanged: (int? newValue) {
    setState(() {
      _selectedValue = newValue;
    });
  },
  items: dropdownMenuItems,
)
  • DropdownButton:建立下拉選單,必須使用 泛形 指定用戶所選擇項目的 型別
    • value:目前 DropdownButton 的 ,會綁定到 state
    • onChanged():當用戶改變所選擇項目是觸發事件,將值寫入 state
    • items:設定下拉選單項目

Line 27

var dropdownMenuItems = dropdownItems
  .map((item) => DropdownMenuItem<int>(
    value: item['value'] as int,
    child: Text(item['text'] as String),
  ))
  .toList();
  • map():將 List<Map> 轉成 List<DropdownMenu<int>>,最後要使用 toList() 再轉成 List
  • DropDownMenuItem:建立下拉選單項目
    • value:選單值
    • child:選單文字

Line 44

var selectedValue = Padding(
  padding: const EdgeInsets.only(left: 16.0),
  child: Text('$_selectedValue'),
);
  • Text:顯示目前用戶所選擇項目的值

Conclusion

  • 因為要使用 state 記住目前用戶所選擇的項目,所以必須搭配 StatefulWidget
  • Dart 的 map() 比較嚴格,必須明確寫出轉型的型別