Using HTML I can add a bullet points to a paragraph like this:
<ul>
<li> example </li>
<li> example </li>
<li> example </li>
<ul>
How can I write bullet point form in Flutter?
new Text(''),
Using HTML I can add a bullet points to a paragraph like this:
<ul>
<li> example </li>
<li> example </li>
<li> example </li>
<ul>
How can I write bullet point form in Flutter?
new Text(''),
If you don't want to download another library (e.g. flutter_markdown), and one or more of your list items have lengthy text that spans several rows, I'd go with Raegtime's answer. However, since it assumes a string with line breaks, I want to make a version for a list with strings, which is a more common scenario. In the code below, Column
makes the list items come on different rows, and Row
makes the bullet points have empty space below themselves.
import 'package:flutter/material.dart';
class UnorderedList extends StatelessWidget {
UnorderedList(this.texts);
final List<String> texts;
@override
Widget build(BuildContext context) {
var widgetList = <Widget>[];
for (var text in texts) {
// Add list item
widgetList.add(UnorderedListItem(text));
// Add space between items
widgetList.add(SizedBox(height: 5.0));
}
return Column(children: widgetList);
}
}
class UnorderedListItem extends StatelessWidget {
UnorderedListItem(this.text);
final String text;
@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("• "),
Expanded(
child: Text(text),
),
],
);
}
}
We can use it as such:
UnorderedList([
"What conclusions can we draw from the implementation?",
"Are there any changes that need to be introduced permanently?"
])
Using markdown for this is overkill. Using •
character is by far easier.
If you're too lazy to copy paste the character, here's a custom Text
that does it for you:
class Bullet extends Text {
const Bullet(
String data, {
Key key,
TextStyle style,
TextAlign textAlign,
TextDirection textDirection,
Locale locale,
bool softWrap,
TextOverflow overflow,
double textScaleFactor,
int maxLines,
String semanticsLabel,
}) : super(
'• ${data}',
key: key,
style: style,
textAlign: textAlign,
textDirection: textDirection,
locale: locale,
softWrap: softWrap,
overflow: overflow,
textScaleFactor: textScaleFactor,
maxLines: maxLines,
semanticsLabel: semanticsLabel,
);
}
I would better use utf-code. For list I think more comfortably will be something like:
class DottedText extends Text {
const DottedText(String data, {
Key key,
TextStyle style,
TextAlign textAlign,
TextDirection textDirection,
Locale locale,
bool softWrap,
TextOverflow overflow,
double textScaleFactor,
int maxLines,
String semanticsLabel,
}) : super(
'\u2022 $data',
key: key,
style: style,
textAlign: textAlign,
textDirection: textDirection,
locale: locale,
softWrap: softWrap,
overflow: overflow,
textScaleFactor: textScaleFactor,
maxLines: maxLines,
semanticsLabel: semanticsLabel,);
}
I tried using flutter_markdown and it seems to work. And of course you can change it to numbered/ordered or unordered list as you want.
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter/material.dart';
void main() => runApp(Demo());
class Demo extends StatelessWidget {
final testData = ["Example1", "Example2", "Example3", "Example100"];
@override
Widget build(BuildContext context) {
final _markDownData = testData.map((x) => "- $x\n").reduce((x, y) => "$x$y");
return MaterialApp(
home: Scaffold(
body: Container(
margin: EdgeInsets.all(40.0),
child: Markdown(data: _markDownData)),
));
}
}
@Snurrig - Excellent answer. Works great! Thanks a lot!
Modified it to create an ordered/numbered list, as well. See below:
class OrderedList extends StatelessWidget {
OrderedList(this.texts);
final List<dynamic> texts;
@override
Widget build(BuildContext context) {
var widgetList = <Widget>[];
int counter = 0;
for (var text in texts) {
// Add list item
counter++;
widgetList.add(OrderedListItem(counter, text));
// Add space between items
widgetList.add(SizedBox(height: 5.0));
}
return Column(children: widgetList);
}
}
class OrderedListItem extends StatelessWidget {
OrderedListItem(this.counter, this.text);
final int counter;
final String text;
@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("$counter. "),
Expanded(
child: Text(text),
),
],
);
}
}
you can use like this:
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'\u2022',
style: TextStyle(
fontSize: 16,
height: 1.55,
),
),
SizedBox(
width: 5,
),
Expanded(
child: Container(
child: Text(
str,
textAlign: TextAlign.left,
softWrap: true,
style: TextStyle(
fontSize: 16,
color: Colors.black.withOpacity(0.6),
height: 1.55,
),
),
),
),
],
);
You can use LineSplitter
, Row
, Column
, and the ASCII bullet point. All u need is a String with linebreaks.
String myStringWithLinebreaks = "Line 1\nLine 2\nLine 3";
Example in a ListTile
ListTile(
title: Text("Title Text"),
subtitle:
Column(
children: LineSplitter.split(myStringWithLinebreaks).map((o) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("• "),
Expanded(
child: Text(o),
)
],
);
}).toList())),
If you do not require markdowns everywhere, and just want to use them in one or two places, then adding a package or writing that much code for it is not a suitable idea.
You can copy the DOT from websites like emojipedia and paste it in front of your text.
here is an example:
Text("⚈ Provide, operate, and maintain our website"),
This will add bullet. Use it in a row with text.
Container(width: 10, height: 10, decoration:
BoxDecoration(shape: BoxShape.circle, color: Colors.black),),
Row(
children: [
_buildBullet(),
const SizedBox(width: 5),
_buildText(),
],
),
SizedBox _buildBullet() {
return SizedBox(
height: 7,
width: 7,
child: TextButton(
style: TextButton.styleFrom(
backgroundColor: Color(0xFFF8B407),
shape: const CircleBorder(),
),
child: const Text(''),
onPressed: () {},
),
);
}
Text _buildText() {
return const Text(
'Lorem Ipsum is simply dummy text of the printing and typesetting',
style: TextStyle(fontSize: 24, color: Colors.white),
);
}
We can create one widget which will take take and return bullet text. you can use this widget.
class BulletText extends StatelessWidget {
final String text;
const BulletText({
super.key,
required this.text,
});
@override
Widget build(BuildContext context) {
return Text(
"• $text",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.normal,
),
);
}
}
You can Use This anywhere you want like this
BulletText(text: "Scrap cars"),