- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个脚手架屏幕 (ListsScreen)。其中有一个按钮 (AddNewListButton),可打开模态 Bottom Sheet 单 (ListScreenBottomSheetWidget)。Bottom Sheet 有 TextField (ListTitleInputTextFieldWidget)。
当我点击 TextField 打开键盘时,父屏幕会自行重建,因此当然也会重建其所有子窗口小部件。
为什么会这样?我的印象是,状态变化只会重建他们自己或他们的 child ,而不是他们的 parent 。而且我还在几乎所有地方添加了 const 构造函数以避免重建,但这种情况仍在发生。
父列表屏幕:
class ListsScreen extends StatelessWidget {
const ListsScreen();
static const routeName = '/lists-screen';
@override
Widget build(BuildContext context) {
final user = Provider.of<AuthProvider>(context, listen: false).getUser;
print('stateless rebuilding');
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text(
'${user['name']}\'s Lists',
style: TextStyle(
color: Theme.of(context).primaryColorLight,
),
),
actions: <Widget>[
const SignOutButton(),
],
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
SizeConfig.smallDevice
? const SizedBox(
height: 30,
)
: const SizedBox(
height: 40,
),
SizeConfig.smallDevice
? Text(
'Welcome to TODOS',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
color: Colors.grey[700],
),
)
: Text(
'Welcome to TODOS',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25,
color: Colors.grey[700],
),
),
SizeConfig.smallDevice
? const SizedBox(
height: 30,
)
: const SizedBox(
height: 40,
),
const AddNewListButton(),
SizeConfig.smallDevice
? const SizedBox(
height: 30,
)
: const SizedBox(
height: 40,
),
const UserListsListViewWidget(),
],
),
),
),
);
}
}
class SignOutButton extends StatelessWidget {
const SignOutButton();
Future<void> _submitRequest(BuildContext context) async {
_showLoadingAlert(context);
try {
await Provider.of<AuthProvider>(context, listen: false)
.submitLogOutRequest();
Navigator.of(context).pop();
Navigator.of(context).pushReplacementNamed(LoginScreen.routeName);
} on HttpExceptions catch (error) {
Navigator.of(context).pop();
_showErrorDialogue(error.getErrorList, context);
}
}
void _showErrorDialogue(List<dynamic> errorMessages, BuildContext context) {
showDialog(
context: context,
builder: (ctx) => Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: ErrorListWidget(errorMessages: errorMessages),
),
);
}
void _showLoadingAlert(BuildContext context) {
showDialog(
context: context,
builder: (ctx) => const LoadingWidget(),
);
}
@override
Widget build(BuildContext context) {
return FlatButton(
onPressed: () => _submitRequest(context),
child: Row(
children: <Widget>[
Text(
'Sign Out',
style: TextStyle(
color: Theme.of(context).primaryColorLight,
),
),
Icon(
Icons.exit_to_app,
color: Theme.of(context).primaryColorLight,
),
],
),
);
}
}
class AddNewListButton extends StatelessWidget {
const AddNewListButton();
void _modalBottomSheetMenu(BuildContext context) {
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
isScrollControlled: true,
builder: (builder) {
return const ListScreenBottomSheetWidget();
},
);
}
@override
Widget build(BuildContext context) {
return RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
elevation: 10,
color: Theme.of(context).primaryColor,
onPressed: () => _modalBottomSheetMenu(context),
child: Text(
'+ Add List',
style: TextStyle(
color: Colors.white,
fontSize: SizeConfig.smallDevice ? 10 : 15,
),
),
);
}
}
模态 Bottom Sheet :
import 'package:flutter/material.dart';
import 'package:todo_spicotech/helpers/size_config.dart';
class ListScreenBottomSheetWidget extends StatelessWidget {
const ListScreenBottomSheetWidget();
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
currentFocus.unfocus();
},
child: Container(
margin: const EdgeInsets.all(20.0),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Material(
borderRadius: BorderRadius.all(Radius.circular(15)),
elevation: 10,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizeConfig.smallDevice
? Text(
'Create a new List',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
color: Colors.grey[700],
),
)
: Text(
'Create a new List',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25,
color: Colors.grey[700],
),
),
SizeConfig.smallDevice
? const SizedBox(
height: 20,
)
: const SizedBox(
height: 30,
),
const ListTitleInputTextFieldWidget(),
SizeConfig.smallDevice
? const SizedBox(
height: 20,
)
: const SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
InkWell(
borderRadius: BorderRadius.circular(5),
onTap: () {
Navigator.of(context).pop();
},
child: Ink(
padding: EdgeInsets.all(10),
child: const Text('CANCEL'),
),
),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
elevation: 10,
color: Theme.of(context).primaryColor,
onPressed: () {},
child: Text(
'Create',
style: TextStyle(
color: Colors.white,
fontSize: SizeConfig.smallDevice ? 10 : 15,
),
),
),
],
),
],
),
),
),
),
);
}
}
class ListTitleInputTextFieldWidget extends StatefulWidget {
const ListTitleInputTextFieldWidget();
@override
_ListTitleInputTextFieldWidgetState createState() => _ListTitleInputTextFieldWidgetState();
}
class _ListTitleInputTextFieldWidgetState extends State<ListTitleInputTextFieldWidget> {
@override
Widget build(BuildContext context) {
return TextFormField(
decoration: const InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.lightBlue,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.lightBlue,
),
),
labelText: 'List Title',
contentPadding: EdgeInsets.all(10),
),
);
}
}
最佳答案
当你调用 showModalBottomSheet
时,它实际上在里面使用了 Navigator
return Navigator.of(context, rootNavigator: useRootNavigator).push(_ModalBottomSheetRoute<T>(
builder: builder,
showModalBottomSheet
的源代码 https://github.com/flutter/flutter/blob/17079f26b54c8517678699a0cefe5f7bfec67b3f/packages/flutter/lib/src/material/bottom_sheet.dart#L635
Flutter 团队对问题的回复推送新页面时导航器堆栈上的页面重建
https://github.com/flutter/flutter/issues/11655#issuecomment-348287396
这是按预期工作的。一般来说,您应该假设所有小部件都可以随时重建,而它们不会重建主要只是一种优化。
特别是,路由将重建,因为它们的导航器状态已更改,因此它们可能需要更新它们如何拉回按钮等。
关于flutter - 为什么子 Bottom Sheet 状态的变化会触发父窗口小部件的重建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61043422/
我是第一次尝试设计网站。我正在尝试在右侧设置一种导航栏,但我无法正确定位它。当我使用边距或填充时,只有边距和填充适用于顶部、右侧和左侧。当我尝试使用 padding-bottom 或 margin-b
这个问题在这里已经有了答案: How can I position my div at the bottom of its container? (25 个答案) 关闭 4 年前。
我有一个垂直的 LinearLayout,它有一个 ListView ,一个 ImageView 在底部,一个在顶部, ListView 填满了留下的空间。 看起来像这样:
https://imgur.com/gallery/xntpREw 有没有人遇到这个问题,或者我做错了什么 更新:我在android 8和9版本上测试了同一个应用程序,但没有出现此故障,因此,这可能特
我将 relativelayout 作为 bottomsheet 行为。在 relativelayout 中,我有 imageview,下面是 recyclerview。现在我想防止用户在 recyc
我在 mi 页面的末尾有这个 navbar-fixed-bottom。 我为 HTML 添加边距底部 html { margin-bottom: 100px } .. 避免页
如何让绝对定位的元素到达页面底部? 我想在我的页面上创建一个“封面”。为了让它覆盖整个页面,我使用了“position: absolute”,四个方向都设置为0。但是,当页面内容的高度大于客户端窗口的
我有一个应该显示日历的 HTML 页面。 有一张图像要显示在日历上方和下方。但是 below(id=bottomCell) 显示不正确(在右边,不在下面)。 你能告诉我如何让底部图片处于正确的位置吗?
对我来说,同时指定 bottom 和 margin-bottom 似乎是矛盾的。因为两者都是指定元素与周围元素/容器之间缩进的方法。也就是说,bottom 应该从边框开始测量,否则它的缩进量是从缩进量
这jsFiddle说明这个问题指的是什么(下面的完整代码)。请注意,即使 #outer-div 应该有 0 个 padding,而 #inner-div 应该有 0 个 margin-bottom,看
我正在尝试完成像 instagram 帖子这样的示例:https://www.instagram.com/p/BXgsKFLBczA/?taken-by=claymicro列表扩展但不会将页脚向下推在
我正在编写一个使用二维数组的程序。用户选择一行和一列;如果至少有一个直接与 N S E 或 W 匹配的元素,则它变为 '.'我一直遇到段错误,因为经过各种测试和解决问题后,我相当确定它陷入了 if t
我正在做一个我第一次使用 scss 的元素。我们有一个主文件,@imports 所有其他文件;这可能还会导入一些其他文件。 编译需要很长时间。人们说这是使用 Sass 时的正常方法。但我怀疑采用相反的
我使用 windbg 在我的 Windows 10 机器上运行一个程序,并让它在初始断点处中断。我获取堆栈的物理底部地址(TEB 的 stackBase),并减去 ntdll!LdrInitializ
我有一个 Bottom Sheet ,我正在加载弹出窗口,但它没有显示在 Bottom Sheet 中。该弹出窗口显示在 Bottom Sheet 格的后面 CustomTextView te
我有一个带有垂直堆栈 View 的 UIScrollView,它有一个标签和一个按钮,我希望按钮停留在屏幕底部,一旦标签的文本增加并到达按钮,按钮将保留在标签下方,并且它们一起滚动。 我在想: let
我在 Android 中创建了一个 View ,我需要从下到上对其进行动画处理,反之亦然。当我单击 ImageView 时,我需要从下到上为完整的 RelativeLayout 设置动画,并且它成功了
我在react native 应用程序中使用react-native-raw-bottom-sheet,打开 Bottom Sheet 时黑色透明 View 。 最佳答案 关于react-nativ
My blog的弹出帖子设置为底部:0;但是当 div 实际上位于底部时,div 中的内容不会移动......有什么想法吗? 最佳答案 看起来你在 javascript 中设置了顶部位置,它覆盖了你的
我在 Google 和此处进行了一些搜索,但找不到适合我的问题的解决方案。我已经完成了网站设计,但忘记包含社交媒体链接。为了解决这个问题,我决定将图标放在页面底部。问题是当内容没有填满整个页面时,图标
我是一名优秀的程序员,十分优秀!