How to Style Text in Flutter™ using its Wrap Widget

How to Style Text in Flutter using its Wrap Widget

Flutter lets you put together various widgets to develop complex & customizable designs. Any UI element that is rendered is a widget in Flutter.

In this blog, we will get to know how different widgets can be combined to create a multi-styled text sentence.

For example:

  • I accept Terms of Service & Privacy Policy.
  • Don’t have an account? Sign Up

In the above sentences, the style of some text is different from the rest. There should also be a click event on this.

In Flutter this can be achieved using different approaches. I am going to show you how it can be done using the Wrap widget.

>> Let’s start by creating a new Flutter project. Give it a name & save it somewhere on your system. Open the main.dart file and replace all the code in the main.dart file with the code below:

import ‘package:flutter/material.dart’;
void main() => runApp(MyApp());

Executing this code will give you this error — “The function ‘MyApp’ isn’t defined”. This happens as there is no MyApp class. Ignore this error for now.

>> Create a new file and name it ‘my_app.dart’. Paste the code below in the newly created file:

import 'package:flutter/material.dart';class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    return MaterialApp(      home: HomeScreen(),    );  }}class HomeScreen extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text('Multi-Styled text'),      ),    );  }}

>> Import this file into the main.dart to resolve the error:

import 'my_app.dart';

If we run the app now, we will see the ‘Multi-Styled text’ in the title with a white screen as can be seen below:

>> Create a new file & name it multi_styled_text_model and paste the following code in this file:

import 'package:flutter/cupertino.dart';class StyleModel {  StyleModel({@required this.text, this.style = const TextStyle(fontSize: 18), this.hasAction = false});  final String text;  final TextStyle style;  final bool hasAction;}

This model class will be used to create a different styled text. This model has only text as required, with the other two being optional. If not provided, the default value will be used for these two.

Import this class in your my_app.dart file, where it will be used.

>> In the HomeScreen class, create a new method. This will return the text widget, with the object of the model we created above:

Widget getTextWidget({@required StyleModel  StyleModel}) {  if( StyleModel.hasAction) {    return InkWell(      onTap: () {        print('Actions:- ${StyleModel.text}');      },      child: Text(StyleModel.text,          style: StyleModel.style      ),    );  }  else {    return Text(StyleModel.text,        style: StyleModel.style    );  }}

Now, we will add another method that will create the multi-styled text widget.

>> Copy the code below and paste it inside the HomeScreen class:

Wrap createMultiStyledTextWidget(List<StyleModel> modelList) {  List<Widget> wrapWidgets = [];  for(StyleModel model in modelList) {    wrapWidgets.add(getTextWidget(StyleModel: model));  }  return Wrap(    spacing: 3.0,    direction: Axis.horizontal,    alignment: WrapAlignment.start,    children: wrapWidgets,  );}

The above method has a list of StyleModel objects as a parameter. Each model object will contain text to be displayed, the style for the text, and the information determining the presence of any event for the text.

A Wrap widget is used to combine different widgets with different styles. In this case, the direction is horizontal and the spacing between each is 3.0. This can be customized as per your requirement.

If the widget can’t fit in a particular device, the wrap widget will automatically show the remaining in the other line or row.

All the above methods can be reused to create any multi-styled text in a project. Now we will write a method to create the “I accept Terms of Service & Privacy Policy.” widget.

>> Add the below method in the in HomeScreen class:

Widget createPrivacyPolicyMultiStyledTextWidget () {  List<StyleModel> styledText = [    StyleModel(text: 'I accept'),    StyleModel(text: 'Terms of Service', hasAction: true, style: TextStyle(fontSize: 18, color: Colors.blueAccent, fontWeight: FontWeight.w700)),    StyleModel(text: 'and'),    StyleModel(text: 'Privacy Policy.', hasAction: true, style: TextStyle(fontSize: 18, color: Colors.blueAccent, fontWeight: FontWeight.w700)),  ];  return createMultiStyledTextWidget(styledText);}

In this method, we are creating a list of StyleModel objects. Each of these is initialized with a text property. For special cases, we provide a different style & action property. If the textStyle isn’t provided, the default value for the text style will be set in the model class. We can provide different styles for every model & it will reflect in the end result.

>> Update the build method as below:

@overrideWidget build(BuildContext context) {  return Scaffold(    appBar: AppBar(      title: Text('Multi-Styled text'),    ),    body: Center(      child: Container(        margin: EdgeInsets.all(10),               child: createPrivacyPolicyMultiStyledTextWidget(),      ),    ),  );}

Now if we run the object, the screen will look something like this:

The Terms of Service text & Privacy Policy text is clickable and can be handled accordingly. Using the model & methods we created in the HomeScreen class, we can style any text sentence in various styles as per our need. All we need to do is create a function & create an object for each differently styled text and call createMultiStyledTextWidget.

For e.g., if we have this style — ‘Don’t have an account? Sign Up’, which is a different sentence.

>> Add the createSignUpWidget method in the HomeScreen, with the return type as the Widget. The method should look like this:

Widget createSignUpWiget()
{
List<StyleModel>
styledText = [
StyleModel(text:'Don’t have an account?'), StyleModel(text: 'SignUp', hasAction: true, style:
TextStyle(fontSize: 18, color: Colors.blueAccent, fontWeight: FontWeight.w700))
]; return createMultiStyledTextWidget(styledText);}

To check this, return this as the child of the container in the build method. The result should be like this:

The HomeScreen class after adding all the methods should be like this:

class HomeScreen extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text('Multi-Styled text'),      ),      body: Center(        child: Container(          margin: EdgeInsets.all(10),          child: createPrivacyPolicyMultiStyledTextWidget(),          //child:  createSignUpWiget(),        ),      ),    );  }  Widget createSignUpWiget() {    List<StyleModel> styledText = [      StyleModel(text: 'Don’t have an account?'),      StyleModel(text: 'Sign Up', hasAction: true, style: TextStyle(fontSize: 18, color: Colors.blueAccent, fontWeight: FontWeight.w700))    ];    return createMultiStyledTextWidget(styledText);  }  Widget createPrivacyPolicyMultiStyledTextWidget () {    List<StyleModel> styledText = [      StyleModel(text: 'I accept'),      StyleModel(text: 'Terms of Service', hasAction: true, style: TextStyle(fontSize: 18, color: Colors.blueAccent, fontWeight: FontWeight.w700)),      StyleModel(text: 'and'),      StyleModel(text: 'Privacy Policy.', hasAction: true, style: TextStyle(fontSize: 18, color: Colors.blueAccent, fontWeight: FontWeight.w700)),    ];    return createMultiStyledTextWidget(styledText);  }  Wrap createMultiStyledTextWidget(List<StyleModel> modelList) {    List<Widget> wrapWidgets = [];    for(StyleModel model in modelList) {      wrapWidgets.add(getTextWidget(StyleModel: model));    }    return Wrap(      spacing: 3.0,      direction: Axis.horizontal,      alignment: WrapAlignment.start,      children: wrapWidgets,    );  }  Widget getTextWidget({@required StyleModel  StyleModel}) {    if( StyleModel.hasAction) {      return InkWell(        onTap: () {          print('Actions:- ${StyleModel.text}');        },        child: Text(StyleModel.text,            style: StyleModel.style        ),      );    }    else {      return Text(StyleModel.text,          style: StyleModel.style      );    }  }}

Thanks for reading!

Flutter is a trademark of Google LLC and its use here does not indicate endorsement or affiliation.

Author — Suhail Shabir, DLT Labs

About the Author: Suhail is an enthusiastic mobile application developer who has worked on iOS and Flutter technology. He has contributed to all major mobile applications at DLT Labs.

Disclaimer: This article was originally published on the DLT Labs Blog page:
https://www.dltlabs.com/blog/how-to-style-text-in-flutter-using-its-wrap-widget-435435

DLT Labs logo
DLT Labs logo

DLT Labs is a global leader in Distributed Ledger Technology and Enterprise Products. To know more, head over to: https://www.dltlabs.com/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store