Scaffold
有個 bottomSheet
特性,被設定的元件會自動隨底部可用空間滑動,通常會用來設定輸入欄位之類的元件,在鍵盤出現時,輸入欄位始終在鍵盤上面。例如:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Openhome.cc'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: Image.network('https://openhome.cc/Gossip/images/caterpillar.jpg')
)
],
),
bottomSheet: TextField(
decoration: InputDecoration(
labelText: '搜尋',
hintText: '搜尋文件',
prefixIcon: Icon(Icons.search),
),
),
)
)
);
執行結果如下:
比較一下跟底下範例有何不同:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Openhome.cc'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: Image.network('https://openhome.cc/Gossip/images/caterpillar.jpg')
),
TextField(
decoration: InputDecoration(
labelText: '搜尋',
hintText: '搜尋文件',
prefixIcon: Icon(Icons.search),
),
),
],
)
)
)
);
執行結果如下:
喔喔!可以看到輸入欄位並沒有隨著鍵盤往上滑,而由於空間不足以繪製完全部的元件,還會有超出範圍的警示黃線出現。
Scaffold
的 bottomSheet
特性是設定固定元件用的,如果想要動態地呈現滑動底盤,可以使用 showBottomSheet
,例如:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Openhome.cc'),
),
body: Body()
)
)
);
class Body extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Center(
child: GestureDetector(
child: Image.network('https://openhome.cc/Gossip/images/caterpillar.jpg'),
onTap: () {
// 顯示滑動底盤
showBottomSheet(
context: context,
builder: (context) {
// 子元件
return Container(
height: 200,
color: Colors.lightGreen,
child: Center(
child: RaisedButton(
child: Text('關閉滑動底盤'),
// 彈出路由
onPressed: () => Navigator.pop(context),
),
),
);
}
);
},
)
),
]
);
}
}
從程式碼中可以看到,因為會使用路由堆疊來管理滑動底盤,要關閉底盤時必須彈出路由,另外也可以用拖曳的方式關閉底盤:
另外還有個 showModalBottomSheet
,顧名思義就是獨佔式的滑動底盤,將上例中的 showBottomSheet
改為 showModalBottomSheet
,就會有以下效果: