How to add shadow to the text in flutter?

后端 未结 4 1926
鱼传尺愫
鱼传尺愫 2021-01-30 21:47

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(
\         


        
相关标签:
4条回答
  • 2021-01-30 22:16

    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.

    0 讨论(0)
  • 2021-01-30 22:20

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

    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)},
                    ),
                  ],
                ),
              ),
            )
          ],
        );
      }
    }
    
    0 讨论(0)
  • 2021-01-30 22:26

    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.

    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,
              ),
            ],
          ),
        );
      }
    }
    
    0 讨论(0)
  • 2021-01-30 22:34

    Text shadows are now a property of TextStyle as of this commit

    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.

    0 讨论(0)
提交回复
热议问题