How can I write a paragraph with bullet points using Flutter?

25,836

Solution 1

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

And get the result: Picture of example result

Solution 2

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

Solution 3

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.

enter image description here

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

Solution 4

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

Solution 5

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

enter image description here

Share:
25,836
lesego finger
Author by

lesego finger

Updated on February 22, 2022

Comments

  • lesego finger
    lesego finger over 2 years

    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(''),
    
    • Rémi Rousselet
      Rémi Rousselet almost 6 years
      is a character. Why not just use that inside your Text ?
    • lesego finger
      lesego finger almost 6 years
      Oooh, then use a Column widget to align them.
    • Günter Zöchbauer
      Günter Zöchbauer over 5 years
      the flutter_markdown package might do this
    • vishalknishad
      vishalknishad about 2 years
      Copy and use inside Text. or
  • Kamlesh
    Kamlesh almost 3 years
    It does not align long text message to right side of bullet icon. Any suggestion for long text? Thanks.
  • Kamlesh
    Kamlesh almost 3 years
    It does not align long text message to right side of bullet icon. Any suggestion for long text? Thanks.
  • Kamlesh
    Kamlesh almost 3 years
    It does not align long text message to right side of bullet icon. Any suggestion for long text? Thanks.
  • Andrey Turkovsky
    Andrey Turkovsky almost 3 years
    @Kamlesh if your text contains more than 1 line - I guess, you'd better use Row widget, which contains dot as first child and text as second one
  • Kamlesh
    Kamlesh almost 3 years
    Yes dear, I implemented the same because there was no other in-built solution.
  • Mjaustro
    Mjaustro almost 3 years
    @Kamlesh For aligned long text, see e.g. my answer.
  • vishalknishad
    vishalknishad about 2 years
    ● cleaner version