Horizontal divider with text in the middle in Flutter?
User InterfaceDartFlutterMaterial DesignUser 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)
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
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
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.