Search code examples
flutterflutter-widgetflutter-theme

Set Color to Text Widget in App universally in flutter without mentioning the theme inside the Widget everytime


I am new to flutter and trying out things.

I replaced the Scaffold Widget with a Center Widget (Just messing around). All text had a Yellow underline, to overcome this I used TextDecoration

Text(
    friend.name,
    style: TextStyle(
        decoration: TextDecoration.none
    ),
));

But this was required for all Text widget hence I tried to set it universally for all Text widgets by setting Theme data in the root MaterialApp.

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp( 
      title: 'Friends List',
      theme: ThemeData(
        primaryColor: Colors.black,
        primarySwatch: Colors.teal,
        primaryTextTheme: TextTheme(
          headline1: TextStyle(color: Colors.green, decoration: TextDecoration.none),
         headline2: TextStyle(color: Colors.green, decoration: TextDecoration.none),
         headline3: TextStyle(color: Colors.green, decoration: TextDecoration.none),
         headline4: TextStyle(color: Colors.green, decoration: TextDecoration.none),
         headline5: TextStyle(color: Colors.green, decoration: TextDecoration.none),
         headline6: TextStyle(color: Colors.green, decoration: TextDecoration.none),
         bodyText1: TextStyle(color: Colors.green, decoration: TextDecoration.none),
         bodyText2: TextStyle(color: Colors.green, decoration: TextDecoration.none),
        ),
        textTheme: TextTheme(
         headline1: TextStyle(decoration: TextDecoration.none),
         headline2: TextStyle(decoration: TextDecoration.none),
         headline3: TextStyle(decoration: TextDecoration.none),
         headline4: TextStyle(decoration: TextDecoration.none),
         headline5: TextStyle(decoration: TextDecoration.none),
         headline6: TextStyle(decoration: TextDecoration.none),
         bodyText1: TextStyle(decoration: TextDecoration.none),
         bodyText2: TextStyle(decoration: TextDecoration.none)
        ),
        ),
      home: MyHomePage(title: 'Friends list'),
    );
  }
}

But the Text widget still as the underline. What I'm trying is similar to setting a style to a tag in css not having to set it every time.

p
{
    universal style here
}

Am I doing anything wrong? Is there a similar support in flutter. Please correct me if I'm wring


Solution

  • Don't use static constants for global styling. Do it in the flutter way by using InheritedWidgets. That way you can easily override the Default style for a particular branch of the tree if needed.

    Well then, what to use for styling text widgets globally?

    You need to define TextTheme for the ThemeData to style Text widgets globally. Additionally, use can use the DefaultTextStyle widget to theme a portion of the widget tree.

    As per documentation,

    The text style to apply to descendant Text widgets without explicit style.

    Place it on the root of your widget tree.

    Example:

    DefaultTextStyle(
              style: TextStyle(fontSize: 36, color: Colors.blue),
             // child: other widgets
       )
    

    Here is a complete working example that illustrate the following

    1. Defines a default text style for all Text widgets
    2. Override the default text style on a particular branch of the tree.

        import 'package:flutter/material.dart';
      
        void main() {
        runApp(MyApp());
      }
      
      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: Colors.white),
            debugShowCheckedModeBanner: false,
            home: Scaffold(
              ///This style will be applied to all the TextWidgets below.
              body: DefaultTextStyle(
                style:
                    Theme.of(context).textTheme.headline6.copyWith(color: Colors.red),
                child: Center(
                  child: MyWidget(),
                ),
              ),
            ),
          );
        }
      }
      
      class MyWidget extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return Column(
            children: <Widget>[
              ///This text will be in red color
              Text('Hello, World!'),
              DefaultTextStyle(
                style:
                    DefaultTextStyle.of(context).style.copyWith(color: Colors.blue),
      
                ///We don't need to place Text widget as direct child of
                ///DefaultTextStyle. This is the proof.
                child: Container(
                  ///Just another widget
                  child: Container(
                    ///This text will be in blue color
                    child: Text('Hello, World!'),
                  ),
                ),
              ),
              DefaultTextStyle(
                style:
                    DefaultTextStyle.of(context).style.copyWith(color: Colors.green),
      
                ///This text will be in green color
      
                child: Text('Hello, World!'),
              ),
            ],
          );
        }
      }
      

    See the live demo here.


    You can find a detailed answer here about colors and Theme.