Jam*_*mes 7 flutter flutter-layout
我正在尝试在 flutter 中创建一个布局,由一行与两个子小部件组成,第一个与左侧对齐,第二个与右侧对齐,如果容器太窄,它也会包裹小部件。
这类似于这里提出的问题Flutter aligning two items on Extremes - 一个在左边,一个在右边,这可以Wrap
用alignment: WrapAlignment.spaceBetween
. 但是,当小部件使用此方法包装时,包装到新运行的右侧小部件不再右对齐。(截图)
我希望发生的是正确的小部件在包装时保持与右侧对齐。在带有 flexbox 的 css 中,这可以通过右侧小部件上的 flex-grow:1 或 margin-left:auto 实现,如本代码笔所示(调整页面宽度以查看我想要的布局)。
到目前为止,我已经尝试过颤振:
Flexible
部件中以尝试使其在包装时占据剩余的宽度,因此我可以在其中正确对齐,但这会引发错误: Incorrect use of ParentDataWidget.
Flexible widgets must be placed inside Flex widgets.
Run Code Online (Sandbox Code Playgroud)
Align
,但这始终会扩展到全宽并导致环绕,即使屏幕足够宽以让两个小部件位于同一行CustomMultiChildLayout
了MultiChildLayoutDelegate
,它可以创建正确的布局,(截图),然而它似乎并不能够设定根据孩子小部件高度widget的高度,迫使你使用任意的高度值。MultiChildLayoutDelegate的文档说覆盖 getSize 以控制布局的整体大小。布局的大小不能依赖于子项的布局属性。
那么是否有可能创建一个布局,当它必须换行时,正确的小部件保持与右边缘对齐?
感谢 R\xc3\xa9mi Rousselet\ 使用自定义的建议,RenderBox
这里是解决布局问题的基本实现(基于Wrap
小部件RenderBox
实现1 2)
import \'package:flutter/widgets.dart\';\nimport \'package:flutter/rendering.dart\';\nimport \'dart:math\' as math;\n\nclass LeftRightAlign extends MultiChildRenderObjectWidget {\n LeftRightAlign({\n Key key,\n @required Widget left,\n @required Widget right,\n }) : super(key: key, children: [left, right]);\n\n @override\n RenderLeftRightAlign createRenderObject(BuildContext context) {\n return RenderLeftRightAlign();\n }\n}\n\nclass LeftRightAlignParentData extends ContainerBoxParentData<RenderBox> {}\n\nclass RenderLeftRightAlign extends RenderBox\n with\n ContainerRenderObjectMixin<RenderBox, LeftRightAlignParentData>,\n RenderBoxContainerDefaultsMixin<RenderBox, LeftRightAlignParentData> {\n\n RenderLeftRightAlign({\n List<RenderBox> children,\n }) {\n addAll(children);\n }\n\n @override\n void setupParentData(RenderBox child) {\n if (child.parentData is! LeftRightAlignParentData)\n child.parentData = LeftRightAlignParentData();\n }\n\n @override\n void performLayout() {\n final BoxConstraints childConstraints = constraints.loosen();\n\n final RenderBox leftChild = firstChild;\n final RenderBox rightChild = lastChild;\n\n leftChild.layout(childConstraints, parentUsesSize: true);\n rightChild.layout(childConstraints, parentUsesSize: true);\n\n final LeftRightAlignParentData leftParentData = leftChild.parentData;\n final LeftRightAlignParentData rightParentData = rightChild.parentData;\n\n final bool wrapped =\n leftChild.size.width + rightChild.size.width > constraints.maxWidth;\n\n leftParentData.offset = Offset.zero;\n rightParentData.offset = Offset(\n constraints.maxWidth - rightChild.size.width,\n wrapped ? leftChild.size.height : 0);\n\n size = Size(\n constraints.maxWidth,\n wrapped\n ? leftChild.size.height + rightChild.size.height\n : math.max(leftChild.size.height, rightChild.size.height));\n }\n\n @override\n bool hitTestChildren(HitTestResult result, {Offset position}) {\n return defaultHitTestChildren(result, position: position);\n }\n\n @override\n void paint(PaintingContext context, Offset offset) {\n defaultPaint(context, offset);\n }\n}\n\n...\n\nclass HomePageState extends State<HomePage> {\n @override\n Widget build(BuildContext context) {\n return CupertinoPageScaffold(\n navigationBar: CupertinoNavigationBar(middle: Text(\'App\')),\n child: ListView(children: <Widget>[\n Container(\n margin: EdgeInsets.symmetric(horizontal: 32, vertical: 16),\n child: LeftRightAlign(\n left: Text(\n \'Left Widget\',\n style: TextStyle(fontSize: 40),\n ),\n right: Text(\n \'Right Widget\',\n style: TextStyle(fontSize: 40),\n ),\n ),\n ),\n Text(\'Next Line\'),\n ])\n );\n }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
1181 次 |
最近记录: |