Flutter 並沒有提供 DropdownBottomSheet
顯示下方有捲軸選單,必須自行使用 ModalBottomSheet
、 ListView
與 Scrollbar
實現。
Version
Flutter 3.24
Flutter
- Android 與 iOS 都成功使用
DropdownBottomSheet
顯示下方有捲軸選單
DropdownBottomSheet
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
const Home({super.key});
State<Home> createState() => _Home();
}
class _Home extends State<Home> {
var _selectedText = 'Select Option';
var options = [
'Option 1',
'Option 2',
'Option 3',
'Option 4',
'Option 5',
'Option 6',
];
List<Widget> _buildListTiles() {
return options.map(
(option) {
return ListTile(
title: Text(option),
onTap: () {
setState(() => _selectedText = option);
Navigator.pop(context);
},
);
},
).toList();
}
void _showModalBottomSheet(BuildContext context) {
var deviceHeight = MediaQuery.of(context).size.height;
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(16),
),
),
builder: (BuildContext context) {
return SizedBox(
height: deviceHeight * 0.25,
child: Scrollbar(
thumbVisibility: true,
child: ListView(
shrinkWrap: true,
children: _buildListTiles(),
),
),
);
},
);
}
Widget build(BuildContext context) {
var appBar = AppBar(
title: const Text('DropdownBottomSheet'),
);
var dropdownButton = GestureDetector(
onTap: () => _showModalBottomSheet(context),
child: Container(
margin: const EdgeInsets.all(16.0),
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(_selectedText),
const Icon(Icons.arrow_drop_down),
],
),
),
);
return Scaffold(
appBar: appBar,
body: dropdownButton,
);
}
}
Line 12
var options = [
'Option 1',
'Option 2',
'Option 3',
'Option 4',
'Option 5',
'Option 6',
];
options
:定義下拉選單所顯示的資料
Line 36
builder: (BuildContext context) {
return SizedBox(
height: deviceHeight * 0.25,
child: Scrollbar(
thumbVisibility: true,
child: ListView(
shrinkWrap: true,
children: _buildListTiles(),
),
),
);
}
SizedBox
:ListView
本身並沒有height
設定高度,需在外層使用SizeBox
定義 heightheight
:可使用MediaQuery
取得裝置高度動態決定 height 不寫死
Scrollbar
:使 ListView 有捲軸thumbVisibility
:是否永遠顯示捲軸
Line 21
List<Widget> _buildListTiles() {
return options.map(
(option) {
return ListTile(
title: Text(option),
onTap: () {
setState(() => _selectedText = option);
Navigator.pop(context);
},
);
},
).toList();
}
- 由
options
產生ListTile
Conclusion
ListView
本身無法設定高度,必須由外層的SizedBox
設定ListView
本身無法產生捲軸,必須由外層的Scrollbar
產生