Flutter中带有文本的水平分隔线?

Posted

技术标签:

【中文标题】Flutter中带有文本的水平分隔线?【英文标题】:Horizontal divider with text in the middle in Flutter? 【发布时间】:2019-06-01 03:56:11 【问题描述】:

Flutter 中是否有一个内置的小部件可以在中间创建一个带有文本的分隔线?关于如何做的任何指南?像这样:(水平线中间的“OR”文本)

here's is the screenshot of what I want to achieve

【问题讨论】:

【参考方案1】:

我已经对它进行了一些美化,代码是这样的

Row(
   mainAxisAlignment: MainAxisAlignment.center,
   children: const [
                     Expanded(
                       child: Divider(
                                indent: 20.0,
                                endIndent: 10.0,
                                thickness: 1,
                              ),
                     ),
                     Text(
                          "OR",
                          style: TextStyle(color: Colors.blueGrey),
                     ),
                     Expanded(
                          child: Divider(
                                  indent: 10.0,
                                  endIndent: 20.0,
                                  thickness: 1,
                          ),
                      ),
                ],
),

【讨论】:

【参考方案2】:

没有颤振小部件可以做到这一点,我为自己创建的。 你可以这样做

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class HorizontalOrLine extends StatelessWidget 
  const HorizontalOrLine(
    this.label,
    this.height,
  );

  final String label;
  final double height;

  @override
  Widget build(BuildContext context) 

    return Row(children: <Widget>[
      Expanded(
        child: new Container(
            margin: const EdgeInsets.only(left: 10.0, right: 15.0),
            child: Divider(
              color: Colors.black,
              height: height,
            )),
      ),

      Text(label),

      Expanded(
        child: new Container(
            margin: const EdgeInsets.only(left: 15.0, right: 10.0),
            child: Divider(
              color: Colors.black,
              height: height,
            )),
      ),
    ]);
  

用法如下:

HorizontalOrLine(height: 10,label: "OR")

【讨论】:

很好的解决方案。您可以简单地使用 Divider 本身的 indent 和 endIndent 属性,而不是使用带有边距的 Container。谢谢。【参考方案3】:

您可以简单地使用容器来实现:

new Container(height: 40, width: 1, color: Colors.grey,
                        margin: const EdgeInsets.only(left: 10.0, right: 10.0),),

如果你想要一条垂直线,改变它的高度并用宽度控制你的线的“粗细”。

如果要绘制水平线,请在宽度/高度之间反转这些逻辑。

在一行中使用它,您的文本位于两个容器的中间。

【讨论】:

请试着解释一下你的答案,因为现在我很难理解你想说什么/做什么。 因为它有一个 Divider() 小部件,我们不需要创建一个看起来像它的容器。【参考方案4】:
import 'package:flutter/material.dart';

class HorizontalLineTitle extends StatelessWidget 
  final String title;
  final Color color;
  final double lineHeight;
  final double lineWidth;
  final double paddingTop;
  final double paddingBottom;

  HorizontalLineTitle(
    @required this.title,
    @required this.color,
    this.lineHeight,
    this.lineWidth,
    this.paddingTop,
    this.paddingBottom,
  );

  Widget _line() 
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) 
        final boxWidth = constraints.constrainWidth();
        final dashWidth = lineWidth ?? 10.0;
        final dashHeight = lineHeight ?? 1.0;
        final dashCount = (boxWidth / (2 * dashWidth)).floor();
        return Flex(
          children: List.generate(dashCount, (_) 
            return SizedBox(
              width: dashWidth,
              height: dashHeight,
              child: DecoratedBox(
                decoration: BoxDecoration(color: color),
              ),
            );
          ),
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          direction: Axis.horizontal,
        );
      ,
    );
  

  @override
  Widget build(BuildContext context) 
    var widgets = <Widget>[];
    widgets.add(Expanded(child: _line()));
    if (title != null && title != '') 
      widgets.add(Padding(
        padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
        child: Text(
          title,
          style: Theme.of(context).textTheme.title,
        ),
      ));
     else 
      widgets.add(Container(width: 2.0));
    
    widgets.add(Expanded(child: _line()));
    return Padding(
      padding: EdgeInsets.fromLTRB(
          0.0, paddingTop ?? 0.0, 0.0, paddingBottom ?? 0.0),
      child: Row(
        children: widgets,
      ),
    );
  


此小部件可用于拥有您需要的相同东西,但带有虚线。只是想发布此内容,以便人们可以使用它来根据自己的需要对其进行自定义。

【讨论】:

【参考方案5】:

最好的办法是制作一个CustomPainter并画一条线

按照步骤操作:

自定义画家:

class Drawhorizontalline extends CustomPainter 
      Paint _paint;
      bool reverse;

   Drawhorizontalline(this.reverse) 
     _paint = Paint()
          ..color = PPColors.tertiaryColor
          ..strokeWidth = 1
          ..strokeCap = StrokeCap.round;
   

  @override
  void paint(Canvas canvas, Size size) 
      if (reverse) 
         canvas.drawLine(Offset(-250.0, 0.0), Offset(-10.0, 0.0), _paint);
       else 
         canvas.drawLine(Offset(10.0, 0.0), Offset(250.0, 0.0), _paint);
      
  

  @override
  bool shouldRepaint(CustomPainter oldDelegate) 
     return false;
  

使用这个 CustomPainter

Widget getSeparateDivider() 
return Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    CustomPaint(painter: Drawhorizontalline(true)),
    Text(
      "OR",
      style: TextStyle(
          color: PPColors.primaryColor,
          fontWeight: FontWeight.bold,
          fontSize: PPUIHelper.FontSizeLarge),
    ),
    CustomPaint(painter: Drawhorizontalline(false))
  ],
 );

【讨论】:

最佳解决方案?只是样板【参考方案6】:

扩展 Jerome 的答案 - 这是一个示例,展示了如何将其与其他内容一起嵌入,并且还有额外的边缘插入以更接近您想要的实际图片:

          Column(children: <Widget>[
            Row(
              children: <Widget>[Text("above")],
            ),
            Row(children: <Widget>[
              Expanded(
                child: new Container(
                    margin: const EdgeInsets.only(left: 10.0, right: 20.0),
                    child: Divider(
                      color: Colors.black,
                      height: 36,
                    )),
              ),
              Text("OR"),
              Expanded(
                child: new Container(
                    margin: const EdgeInsets.only(left: 20.0, right: 10.0),
                    child: Divider(
                      color: Colors.black,
                      height: 36,
                    )),
              ),
            ]),
            Row(
              children: <Widget>[Text("below ")],
            ),
          ])

【讨论】:

【参考方案7】:

您可以尝试使用Row 小部件。

Row(
    children: <Widget>[
        Expanded(
            child: Divider()
        ),       

        Text("OR"),        

        Expanded(
            child: Divider()
        ),
    ]
)

【讨论】:

@Deche 如果是答案,请考虑接受问题, @Mahdi-Malv 我如何接受回答?我没有看到任何按钮 投票号下方有一个勾号占位符,如果你问过问题就可以看到。 作为一个魅力!您是否有任何关于我为什么需要添加扩展小部件的信息?我试过没有它,但看不到 Divider 在将Divider 具有的所有可选参数传递到自包含小部件中时,是否有某种方法可以将其移动到可重复使用的小部件中?你是否在保持可选参数的同时传递可选参数?

以上是关于Flutter中带有文本的水平分隔线?的主要内容,如果未能解决你的问题,请参考以下文章

反应创建一个水平分隔线,中间有文本

Flutter BLoC 库中带有验证的文本字段

#yyds干货盘点#Flutter中如何添加垂直分隔线flutter专题35

在winforms中绘制水平分隔线[重复]

Flutter 离线数据方案 Flutter_Data 包

Flutter 离线数据方案 Flutter_Data 包