|
@@ -38,60 +38,68 @@ class _ToolsPageState extends State<ToolsPage> {
|
|
|
Widget build(BuildContext context) {
|
|
Widget build(BuildContext context) {
|
|
|
final items = kTools.where((t) => t.matches(_q)).toList();
|
|
final items = kTools.where((t) => t.matches(_q)).toList();
|
|
|
|
|
|
|
|
- return Column(
|
|
|
|
|
- children: [
|
|
|
|
|
- Padding(
|
|
|
|
|
- padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
|
|
|
|
|
- child: TextField(
|
|
|
|
|
- controller: _search,
|
|
|
|
|
- decoration: InputDecoration(
|
|
|
|
|
- isDense: true,
|
|
|
|
|
- hintText: '搜索工具(支持拼音首字母)',
|
|
|
|
|
- prefixIcon: const Icon(Icons.search),
|
|
|
|
|
- suffixIcon: _q.isEmpty
|
|
|
|
|
- ? null
|
|
|
|
|
- : IconButton(
|
|
|
|
|
- icon: const Icon(Icons.clear),
|
|
|
|
|
- onPressed: () {
|
|
|
|
|
- _search.clear();
|
|
|
|
|
- setState(() => _q = '');
|
|
|
|
|
- },
|
|
|
|
|
- ),
|
|
|
|
|
- border: const OutlineInputBorder(),
|
|
|
|
|
|
|
+ // 这一页是唯一没有自己的 Scaffold/AppBar 的 tab(另外两个都有),
|
|
|
|
|
+ // 所以得自己让开状态栏 —— 否则搜索框会顶到状态栏上,和时钟叠在一起。
|
|
|
|
|
+ // bottom 不用让:下面紧挨着的就是 Shell 的 NavigationBar,它已经把
|
|
|
|
|
+ // 底部安全区吃掉了。
|
|
|
|
|
+ return SafeArea(
|
|
|
|
|
+ bottom: false,
|
|
|
|
|
+ child: Column(
|
|
|
|
|
+ children: [
|
|
|
|
|
+ Padding(
|
|
|
|
|
+ padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
|
|
|
|
|
+ child: TextField(
|
|
|
|
|
+ controller: _search,
|
|
|
|
|
+ decoration: InputDecoration(
|
|
|
|
|
+ isDense: true,
|
|
|
|
|
+ hintText: '搜索工具(支持拼音首字母)',
|
|
|
|
|
+ prefixIcon: const Icon(Icons.search),
|
|
|
|
|
+ suffixIcon: _q.isEmpty
|
|
|
|
|
+ ? null
|
|
|
|
|
+ : IconButton(
|
|
|
|
|
+ icon: const Icon(Icons.clear),
|
|
|
|
|
+ onPressed: () {
|
|
|
|
|
+ _search.clear();
|
|
|
|
|
+ setState(() => _q = '');
|
|
|
|
|
+ },
|
|
|
|
|
+ ),
|
|
|
|
|
+ border: const OutlineInputBorder(),
|
|
|
|
|
+ ),
|
|
|
|
|
+ onChanged: (v) => setState(() => _q = v),
|
|
|
),
|
|
),
|
|
|
- onChanged: (v) => setState(() => _q = v),
|
|
|
|
|
),
|
|
),
|
|
|
- ),
|
|
|
|
|
- Expanded(
|
|
|
|
|
- child: items.isEmpty
|
|
|
|
|
- ? const Center(child: Text('没有匹配的工具'))
|
|
|
|
|
- : GridView.builder(
|
|
|
|
|
- padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
|
|
|
|
- gridDelegate:
|
|
|
|
|
- const SliverGridDelegateWithFixedCrossAxisCount(
|
|
|
|
|
- crossAxisCount: 2,
|
|
|
|
|
- mainAxisSpacing: 12,
|
|
|
|
|
- crossAxisSpacing: 12,
|
|
|
|
|
- childAspectRatio: 1.5,
|
|
|
|
|
- ),
|
|
|
|
|
- itemCount: items.length,
|
|
|
|
|
- itemBuilder: (_, i) {
|
|
|
|
|
- final t = items[i];
|
|
|
|
|
- final color = _palette[kTools.indexOf(t) % _palette.length];
|
|
|
|
|
- return _ToolCard(
|
|
|
|
|
- plugin: t,
|
|
|
|
|
- color: color,
|
|
|
|
|
- onTap: () => Navigator.of(context).push(
|
|
|
|
|
- MaterialPageRoute<void>(
|
|
|
|
|
- builder: (_) => t.build(),
|
|
|
|
|
- settings: RouteSettings(name: t.name),
|
|
|
|
|
|
|
+ Expanded(
|
|
|
|
|
+ child: items.isEmpty
|
|
|
|
|
+ ? const Center(child: Text('没有匹配的工具'))
|
|
|
|
|
+ : GridView.builder(
|
|
|
|
|
+ padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
|
|
|
|
+ gridDelegate:
|
|
|
|
|
+ const SliverGridDelegateWithFixedCrossAxisCount(
|
|
|
|
|
+ crossAxisCount: 2,
|
|
|
|
|
+ mainAxisSpacing: 12,
|
|
|
|
|
+ crossAxisSpacing: 12,
|
|
|
|
|
+ childAspectRatio: 1.5,
|
|
|
),
|
|
),
|
|
|
- ),
|
|
|
|
|
- );
|
|
|
|
|
- },
|
|
|
|
|
- ),
|
|
|
|
|
- ),
|
|
|
|
|
- ],
|
|
|
|
|
|
|
+ itemCount: items.length,
|
|
|
|
|
+ itemBuilder: (_, i) {
|
|
|
|
|
+ final t = items[i];
|
|
|
|
|
+ final color =
|
|
|
|
|
+ _palette[kTools.indexOf(t) % _palette.length];
|
|
|
|
|
+ return _ToolCard(
|
|
|
|
|
+ plugin: t,
|
|
|
|
|
+ color: color,
|
|
|
|
|
+ onTap: () => Navigator.of(context).push(
|
|
|
|
|
+ MaterialPageRoute<void>(
|
|
|
|
|
+ builder: (_) => t.build(),
|
|
|
|
|
+ settings: RouteSettings(name: t.name),
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
|
|
+ );
|
|
|
|
|
+ },
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|