flutter - 点击 AppBar 中的 IconButton 以显示悬浮在 Scaffold 主体上的 TextField(带有一个小部件,而不是两个)
问题描述
AppBar
有没有办法从身体上方(上方)的小部件中浮动一个盒子Scaffold
?例如,如果我将我的搜索小部件放入Scaffold
正文中,当我的搜索IconButton
被点击时,它TextField
会出现并挂在它下面的内容上:
但是,理想情况下,我希望搜索图标出现在AppBar
(而不是Scaffold
正文)中,然后点击时,我希望输入框浮在Scaffold
正文上。如果我将我的搜索小部件放入 中AppBar
,TextField
则隐藏在Scaffold
正文下方,如下所示:
如果你仔细看,TextField
在我点击图标下方AppBar
但主体上方的小边距后,您实际上可以看到focusedBorder Scaffold
:
因此,您可以看到TextField
隐藏在Scaffold
身体后面。
我从 Flutter 文档中发现,Scaffold
body 将其内容置于 the 之下AppBar
和之后,floatingActionButton
并且drawer
是设计的(https://api.flutter.dev/flutter/material/Scaffold/body.html)。但是,在这个用例中使用 afloatingActionButton
或 adrawer
会有点麻烦。
我想我可以将TextField
放在一个单独的小部件中并位于Scaffold
正文中,并使用Provider
/与被点击的ChangeNotifier
小部件通信。但是,这将组件逻辑分成了两个地方,这看起来很混乱。我希望有人可以用最佳实践启发我或让我朝着正确的方向前进。Scaffold
IconButton
AppBar
那么,有没有一种合适的方法让一个漂浮在身体IconButton
上的AppBar
显示器 a ?(这似乎是一个常见的用例。)TextField
Scaffold
解决方案
您可以使用 aStack
为您的Scaffold > body
:
完整源代码:
import 'dart:math' show Random;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(AppWidget());
}
class AppWidget extends StatelessWidget {
const AppWidget({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => SearchModel(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(primaryColor: Color(0xfffedbd0)),
title: 'Flutter Demo',
home: HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<SearchModel>(
builder: (context, searchModel, child) => Scaffold(
appBar: AppBar(
title: Text('SHRINE'),
actions: [
IconButton(
icon: Icon(Icons.search, semanticLabel: 'search'),
onPressed: () => searchModel.toggleVisibility()),
],
),
body: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Search(),
),
),
);
}
}
class Search extends StatelessWidget {
Search();
@override
Widget build(BuildContext context) {
return Consumer<SearchModel>(builder: (context, searchModel, child) {
return Stack(
children: [
GridView.count(
crossAxisCount: 3,
children: List.generate(
30,
(index) => Container(
color: Color(0xaaaa0000 + 0xffffff ~/ (index + 1)),
),
),
),
Positioned.fill(
child: Align(
alignment: Alignment.center,
child: AnimatedOpacity(
opacity: searchModel.isVisible ? 1.0 : 0.0,
duration: Duration(milliseconds: 500),
child: SizedBox(
width: 190.0,
height: 25.0,
child: TextField(
decoration: InputDecoration(
filled: true,
fillColor: Theme.of(context).primaryColor,
hintText: 'Enter a search term',
contentPadding: const EdgeInsets.symmetric(
horizontal: 8.0, vertical: 4.0),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black),
borderRadius: BorderRadius.circular(25.7),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black),
borderRadius: BorderRadius.circular(25.7),
),
),
onChanged: (text) => searchModel.updateText(text),
),
),
),
),
),
],
);
});
}
}
class SearchModel extends ChangeNotifier {
String text = '';
bool isVisible = false;
updateText(String newText) {
text = newText;
notifyListeners();
}
toggleVisibility() {
isVisible = !isVisible;
notifyListeners();
}
}
推荐阅读
- vb.net - 我的控制台应用程序在启动后关闭,但如果我以正常方式启动,它可以正常工作
- c# - 使用 LINQ to Objects 过滤和返回布尔值的这两个语句之间是否有“正确”的方式?
- java - 在 try-with-resources 中关闭动态数量的 AutoCloseable 对象
- mips - 不明白这个lw在做什么
- python - 我的血糖模型 Scipy 代码错误
- python - 如何在python中替换unicode dicts值并返回unicode格式
- three.js - 绕对象轴 Y 旋转后如何设置对象轴 x 和 z 的方向?
- excel - 过滤公式中的列并更正公式
- html - 为什么 span with height: auto 和 display: inline-block parent of svg 的高度比它的 svg child 大?
- php - 是否可以将压缩文件夹从服务器(php)发送到前端(角度)?还是有其他方法可以做到