【问题标题】:Base align text and dashed line in FlutterFlutter中的基本对齐文本和虚线
【发布时间】:2019-10-03 20:43:01
【问题描述】:

我正在尝试为我的 Flutter 应用创建类似的东西:

现在我已经成功地获得了一行文字、一条虚线和更大的文字。我似乎无法解决的最后一个问题是消除不同大小文本中的可变大小差距。

[编辑] 我的具体意思是让所有东西都在同一条红线上对齐:

看着this answer,我想我可以做同样的事情并将所有文本放置在定位堆栈中。然而,这打破了我的布局,给了我这个错误:

I/flutter (26439): The following assertion was thrown during performLayout():
I/flutter (26439): RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I/flutter (26439): When a column is in a parent that does not provide a finite height constraint, for example if it is
I/flutter (26439): in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
I/flutter (26439): flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
I/flutter (26439): space in the vertical direction.
I/flutter (26439): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
I/flutter (26439): cannot simultaneously expand to fit its parent.
I/flutter (26439): Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
I/flutter (26439): children (using Flexible rather than Expanded). This will allow the flexible children to size
I/flutter (26439): themselves to less than the infinite remaining space they would otherwise be forced to take, and
I/flutter (26439): then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
I/flutter (26439): constraints provided by the parent.
I/flutter (26439): The affected RenderFlex is:
I/flutter (26439):   RenderFlex#c7fb1 relayoutBoundary=up8 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (26439): The creator information is set to:
I/flutter (26439):   Column ← Expanded ← Row ← Column ← Padding ← RepaintBoundary-[<0>] ← IndexedSemantics ←
I/flutter (26439):   NotificationListener<KeepAliveNotification> ← KeepAlive ← AutomaticKeepAlive ← SliverList ←
I/flutter (26439):   MediaQuery ← ⋯
I/flutter (26439): See also: https://flutter.dev/layout/

这是我的相关代码:

Row(
  crossAxisAlignment: CrossAxisAlignment.end,
  children: <Widget>[
    Text('Salary Cap'),
    // Stack( // Will cause error
    //   fit: StackFit.expand,
    //   children: <Widget>[
    //     Positioned(
    //       top: 0,
    //       left: 0,
    //       width: 200,
    //       child: Text('Salary Cap'),
    //     ),
    //   ],
    // ),
    Expanded(
      child: Container(
        width: double.infinity,
        child: CustomPaint(painter: LineDashedPainter()),
      ),
    ),
    RichText(
      text: TextSpan(
        children: <TextSpan>[
          TextSpan(text: '\$'),
          TextSpan(
            text:
                '${oCcy.format(salaryLimit)}',
            style: Theme.of(context).textTheme.display1,
          ),
        ],
      ),
    ),
  ],
),

有什么建议吗?

【问题讨论】:

  • 尝试将您的Row 放入具有固定宽度的Container
  • 你想用堆栈实现什么? “摆脱不同大小文本中的可变大小差距”是什么意思?如果您的意思是基线未对齐,请查看 CrossAxisAlignment.baseline 显示例如here.
  • 只是调整大文本的位置,也许可以尝试使用Transform.translate,这里是一个示例docs.flutter.io/flutter/widgets/Transform/…
  • @siega 对不起,Siega,但这对我没有任何帮助。 @Edman 我认为这就是我想要的。我添加了两个属性crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, 并且字符都在排队,但现在我无法将虚线拉下来。 See here。如果这是第二个问题,那很好——只是想我可以在这里问。哦,从这个SO answer
  • @Edman 我从你的建议中得到了它。我只需要在行中添加一个intrinsicHeight 并将Container 包装在Align 小部件(Alignment.bottomCenter)中。从那里开始,虚线与文本基线有点偏离,所以我只是在 Container 的十个中添加了一个底部边距,现在看起来不错。如果您发布一个,我可以标记您的答案。这是gist of my of my code

标签: layout flutter styling


【解决方案1】:

这两行你可以

crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.ideographic,

【讨论】:

    【解决方案2】:

    我已经为你创建了一个示例,你可以自定义字体颜色等等。

    class MoneyRow extends StatelessWidget {
      final String name;
      final String ammout;
    
      const MoneyRow({Key key, this.name, this.ammout}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Row(
          children: <Widget>[
            Text(name),
            Expanded(child: DashedLine()),
            _price(context)
          ],
        );
      }
    
      Widget _price(BuildContext context) {
        return RichText(
            text: TextSpan(
                text: "\$",
                style: Theme.of(context)
                    .textTheme
                    .subhead
                    .copyWith(color: Colors.grey),
                children: [
              TextSpan(
                  text: ammout,
                  style: Theme.of(context)
                      .textTheme
                      .headline
                      .copyWith(color: Colors.black))
            ]));
      }
    }
    
    class DashedLine extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return LayoutBuilder(
          builder: (context, constraints) {
            final boxWidth = constraints.constrainWidth();
            final dashWidth = 10.0;
            final dashCount = (boxWidth / (2 * dashWidth)).floor();
            return Row(
              children: List.generate(dashCount, (_) {
                return Text(".");
              }),
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
            );
          },
        );
      }
    }
    

    用法

    @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: new AppBar(
              title: new Text("My Flutter App"),
              backgroundColor: Colors.red,
            ),
            body: Column(
              children: <Widget>[
                MoneyRow(
                  name: "Cash",
                  ammout: "300.3",
                ),
                MoneyRow(
                  name: "Cash",
                  ammout: "300.3",
                ),
                MoneyRow(
                  name: "Cash",
                  ammout: "300.3",
                )
              ],
            ));
      }
    

    @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: new AppBar(
              title: new Text("My Flutter App"),
              backgroundColor: Colors.red,
            ),
            body: ListView.builder(
                itemCount: 10,
                itemBuilder: (context, index) {
                  return MoneyRow(name: "Money $index", ammout: "${index * 10}");
                }));
      }
    

    值得一提的是,虚线的灵感来自this SO post

    【讨论】:

    • 非常感谢您的帮助。我不认为这是适合我的。如果我碰巧更改了尾随文本amount 的文本大小(就像我想在我的那样做),我最终会遇到同样的问题。 See here
    猜你喜欢
    • 2020-10-03
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    • 2021-11-01
    • 2011-03-07
    • 2017-08-11
    • 1970-01-01
    相关资源
    最近更新 更多