How to add shadow to the text in flutter?

FlutterDartTextShadow

Flutter Problem Overview


I searched for the shadow option in TextStyle, but I didn't find it. So I ask: how can I add shadow to the text in flutter? Is it possible? Example:

new Text(
"asd"
style: new TextStyle( 
//add shadow?
));

Flutter Solutions


Solution 1 - Flutter

Text shadows are now a property of TextStyle as of [this commit][1]

To enable text shadows, please make sure you are on an up-to-date version of Flutter ($ flutter upgrade) and provide a List<Shadow> to TextStyle.shadows:

import 'dart:ui';

...

Text(
  'Hello, world!',
  style: TextStyle(
    shadows: <Shadow>[
      Shadow(
        offset: Offset(10.0, 10.0),
        blurRadius: 3.0,
        color: Color.fromARGB(255, 0, 0, 0),
      ),
      Shadow(
        offset: Offset(10.0, 10.0),
        blurRadius: 8.0,
        color: Color.fromARGB(125, 0, 0, 255),
      ),
    ],
  ),
),

...

Keep in mind that shadows will be drawn in the order provided.

[1]: https://github.com/flutter/flutter/commit/bdc3dda5f298f50b432faaffe71730c4fe26afda "this commit"

Solution 2 - Flutter

Flutter now provides a way to do this without any work-arounds, as documented in issue 3402 and Gary Qian's answer below.

While this makes its way into the more stable channels, it's possible to fake a shadow using BackdropFilter.

screenshot

import 'dart:ui' as ui;
import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    home: new MyApp(),
  ));
}

class ShadowText extends StatelessWidget {
  ShadowText(this.data, { this.style }) : assert(data != null);

  final String data;
  final TextStyle style;

  Widget build(BuildContext context) {
    return new ClipRect(
      child: new Stack(
        children: [
          new Positioned(
            top: 2.0,
            left: 2.0,
            child: new Text(
              data,
              style: style.copyWith(color: Colors.black.withOpacity(0.5)),
            ),
          ),
          new BackdropFilter(
            filter: new ui.ImageFilter.blur(sigmaX: 2.0, sigmaY: 2.0),
            child: new Text(data, style: style),
          ),
        ],
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Container(
        child: new Center(
          child: new ShadowText(
            'Hello world!',
            style: Theme.of(context).textTheme.display3,
          ),
        ),
      ),
    );
  }
}

Or if you don't care about the blur, just make a Stack with a few some semitransparent Text widgets stacked not quite precisely on top of each other.

Like this:

import 'package:flutter/material.dart';

class ShadowText extends StatelessWidget {

  final String data;
  final TextStyle style;
  final TextAlign textAlign;
  final TextDirection textDirection;
  final bool softWrap;
  final TextOverflow overflow;
  final double textScaleFactor;
  final int maxLines;

  const ShadowText(this.data, {
    Key key,
    this.style,
    this.textAlign,
    this.textDirection,
    this.softWrap,
    this.overflow,
    this.textScaleFactor,
    this.maxLines,
  }) : assert(data != null);

  Widget build(BuildContext context) {
    return new ClipRect(
      child: new Stack(
        children: [
          new Positioned(
            top: 2.0,
            left: 2.0,
            child: new Text(
              data,
              style: style.copyWith(color: Colors.black.withOpacity(0.5)),
              textAlign: textAlign,
              textDirection: textDirection,
              softWrap: softWrap,
              overflow: overflow,
              textScaleFactor: textScaleFactor,
              maxLines: maxLines,
            ),
          ),
          new Text(
            data,
            style: style,
            textAlign: textAlign,
            textDirection: textDirection,
            softWrap: softWrap,
            overflow: overflow,
            textScaleFactor: textScaleFactor,
            maxLines: maxLines,
          ),
        ],
      ),
    );
  }
}

Solution 3 - Flutter

Here is a little playing around with the opacity, offset, and shadow radius:

enter image description here

The full code is here. Try it out yourself.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ShadowDemo(),
      ),
    );
  }
}

class ShadowDemo extends StatefulWidget {
  @override
  _ShadowDemoState createState() => _ShadowDemoState();
}

class _ShadowDemoState extends State<ShadowDemo> {
  var _opacity = 1.0;
  var _xOffset = 0.0;
  var _yOffset = 0.0;
  var _blurRadius = 0.0;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Center(
            child: Text(
          'Flutter',
          style: TextStyle(
            fontSize: 100,
            color: Colors.blue.shade700,
            shadows: [
              Shadow(
                color: Colors.blue.shade900.withOpacity(_opacity),
                offset: Offset(_xOffset, _yOffset),
                blurRadius: _blurRadius,
              ),
            ],
          ),
        )),
        Align(
          alignment: Alignment.bottomCenter,
          child: Padding(
            padding: const EdgeInsets.only(bottom: 80.0),
            child: Column(
              children: <Widget>[
                Spacer(),
                Slider(
                  value: _opacity,
                  min: 0.0,
                  max: 1.0,
                  onChanged: (newValue) =>
                      {setState(() => _opacity = newValue)},
                ),
                Slider(
                  value: _xOffset,
                  min: -100,
                  max: 100,
                  onChanged: (newValue) =>
                      {setState(() => _xOffset = newValue)},
                ),
                Slider(
                  value: _yOffset,
                  min: -100,
                  max: 100,
                  onChanged: (newValue) =>
                      {setState(() => _yOffset = newValue)},
                ),
                Slider(
                  value: _blurRadius,
                  min: 0,
                  max: 100,
                  onChanged: (newValue) =>
                      {setState(() => _blurRadius = newValue)},
                ),
              ],
            ),
          ),
        )
      ],
    );
  }
}

Solution 4 - Flutter

Expanding on Collin Jackson's answer. This will account for the various TextAlign properties.

import 'package:flutter/material.dart';

class ShadowText extends StatelessWidget {
  final String data;
  final TextStyle style;
  final TextAlign textAlign;
  final TextDirection textDirection;
  final bool softWrap;
  final TextOverflow overflow;
  final double textScaleFactor;
  final int maxLines;

  const ShadowText(
    this.data, {
    Key key,
    this.style,
    this.textAlign,
    this.textDirection,
    this.softWrap,
    this.overflow,
    this.textScaleFactor,
    this.maxLines,
  }) : assert(data != null);

  Widget build(BuildContext context) {
    AlignmentDirectional _align;
    switch (textAlign) {
      case TextAlign.justify:
      case TextAlign.center:
        _align = AlignmentDirectional.center;
        break;
      case TextAlign.end:
      case TextAlign.right:
        _align = AlignmentDirectional.centerEnd;
        break;
      case TextAlign.start:
      case TextAlign.left:
        _align = AlignmentDirectional.centerStart;
        break;
      default:
        _align = AlignmentDirectional.center;
    }
    return new ClipRect(
      child: new Stack(
        alignment: _align,
        children: [
          Text(data,
              style: style.copyWith(color: Colors.black.withOpacity(0.5)),
              textAlign: textAlign,
              textDirection: textDirection,
              softWrap: softWrap,
              overflow: overflow,
              textScaleFactor: textScaleFactor + 0.03,
              maxLines: maxLines),
          new Text(
            data,
            style: style,
            textAlign: textAlign,
            textDirection: textDirection,
            softWrap: softWrap,
            overflow: overflow,
            textScaleFactor: textScaleFactor,
            maxLines: maxLines,
          ),
        ],
      ),
    );
  }
}

Then whenever you want to use this just import this file at the top and replace the Text() with ShadowText() widget.

Solution 5 - Flutter

To more sharpness you can use flutter_shine package

Flutter Shine is a library for pretty shadows, dynamic light positions, extremely customizable shadows, no library dependencies, text or box-shadows based on content.

Add the Package

dependencies:
  flutter_shine: ^0.0.5

And easy it is to create a shadow on the text and on a container.

FlutterShine(
    builder: (BuildContext context, ShineShadow shineShadow) {
        return Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
                Text(
                    "Shine",
                    style: TextStyle(
                        fontSize: 100,
                        color: Colors.white,
                        shadows: shineShadow.shadows),
                ),
                Divider(),
                Container(
                    width: 300,
                    height: 300,
                    decoration: BoxDecoration(
                        color: Colors.white, boxShadow: shineShadow.boxShadows),
                )
            ],
        );
    },
),

enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZeroProcessView Question on Stackoverflow
Solution 1 - FlutterGary QianView Answer on Stackoverflow
Solution 2 - FlutterCollin JacksonView Answer on Stackoverflow
Solution 3 - FlutterSuragchView Answer on Stackoverflow
Solution 4 - FlutterRody DavisView Answer on Stackoverflow
Solution 5 - FlutterParesh MangukiyaView Answer on Stackoverflow