Horizontal divider with text in the middle in Flutter?

User InterfaceDartFlutterMaterial Design

User Interface Problem Overview


Is there a built in widget in Flutter to create a divider with text in the middle? Any guide on how to do it? Like this: (the "OR" text in the middle of horizontal line)

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

User Interface Solutions


Solution 1 - User Interface

You can try to use the Row widget.

Row(
    children: <Widget>[
        Expanded(
            child: Divider()
        ),       
    
        Text("OR"),        
    
        Expanded(
            child: Divider()
        ),
    ]
)

Solution 2 - User Interface

Example Implementation of a divider with Text

To expand on Jerome's answer - Here is an example that shows how to embed it with other content and also has additional edgeinsets for coming closer to the actual picture that you want:

          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 ")],
            ),
          ])

Solution 3 - User Interface

There is no flutter widget that do this, I created on for myself. You can do it like this

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,
            )),
      ),
    ]);
  }
}

The usage will be:

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

Solution 4 - User Interface

I've beatified this a little and the code goes like this

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,
                          ),
                      ),
                ],
),

Solution 5 - User Interface

Best solution is to make a CustomPainter and draw a line

Follow the steps: enter image description here

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;
  }
}

Use this 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))
  ],
 );
}

Solution 6 - User Interface

You can simply use a container to achieve this:

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

If you want a vertical line, change the height for the size of it and control the "thickness" of your line with width.

Invert these logic between width / height if you want to draw an horizontal line.

Use it in a Row with your text in the middle of both of your containers.

Solution 7 - User Interface

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,
      ),
    );
  }
}

This widget can be used for having the same thing you need but with dotted lines. Just wanted to post this so people can use it to customize it to their needs.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDecheView Question on Stackoverflow
Solution 1 - User InterfaceJerome EscalanteView Answer on Stackoverflow
Solution 2 - User InterfaceOswin NoetzelmannView Answer on Stackoverflow
Solution 3 - User InterfaceAnas NaguibView Answer on Stackoverflow
Solution 4 - User InterfaceAMAL MOHAN NView Answer on Stackoverflow
Solution 5 - User InterfaceAtulView Answer on Stackoverflow
Solution 6 - User InterfaceMUKESH BHATIView Answer on Stackoverflow
Solution 7 - User InterfaceAndre HonsbergView Answer on Stackoverflow