• Flutter —— Text文字渐变


    Flutter Text 设置文本渐变色

     

    API是使用TextStyle中的foreground 设置文字颜色渐变,如下图:

    https://api.flutter.dev/flutter/painting/TextStyle-class.html

    头文件import 'dart:ui' as ui; 

     

    根据以上代码构造之后结果如下图行1所示,但是如果Text控件居中并缩短字符串长度后就会发现渐变颜色不同的,如下图行2所示。(最后有相关代码)

    通过多次对比发现,渐变色是基于在整个window偏移的,代码中的offset 分别表示Offset from,Offset to 起点与终点偏移量,代码中const Offset(0, 20),const Offset(150, 20),表示从坐标(0,20),到(150,20,修改偏移量为const Offset(100, 20),const Offset(250, 20),结果图行3、4。

    所以行2中Text居中后dx还是从0开始,颜色不是正红色开始,查看Gradient.linear,有一个colorStops属性,具体含义可查看相关注释,如下图

    在偏移量超过其字符串最大dx的时候,设置colorStops,<double>[0.3,0.9],结果如结果图中的行5,通过调整colorStops,可以得到想要的渐变效果。

    注意: 设置渐变色不能同时设置TextStyle的color属性,否则会报错,如下图:

    设置渐变色还有另外一种写法:

    Text(
    
      'Greetings, planet!',
    
      style: TextStyle(
    
          fontSize: 30,
    
          foreground: Paint()
    
            ..shader = LinearGradient(colors: [
    
              Colors.red,
    
              Colors.yellow,
    
            ]).createShader(Rect.fromLTWH(0, 0, 150, 0))),
    
    )
    
    或者
    
    Gradient gradient =  LinearGradient(colors: [
    
      Colors.red,
    
      Colors.yellow,
    
    ]);
    
    Text(
    
      'Greetings, planet!',
    
      style: TextStyle(
    
          fontSize: 30,
    
          foreground: Paint()
    
            ..shader = gradient.createShader(Rect.fromLTWH(0, 0, 100, 0))),
    
    )

     

    createShader中的Rect和上面的偏移量类似,又不完全相同,Rect.fromLTWH(0, 0, 100, 0),  width,表示渐变的宽度范围,结果如图行6。

    这时候只是固定位置text设置渐变色,如果在不确定text坐标的时候如何使用渐变色

    1、 设置Text的key值globalKey,通过globalKey 获取Text控件的size及position

    final RenderBox box = globalKey.currentContext.findRenderObject();

    final size = box.size;

    final topLeftPosition = box.localToGlobal(Offset.zero);

    2、如果设置的比较多可以封装组件widget,根据组件context获取位置大小,具体可查看以下的TextGradientColorWidget

     

    验证相关代码:

    import 'dart:ui' as ui;
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            // This is the theme of your application.
            //
            // Try running your application with "flutter run". You'll see the
            // application has a blue toolbar. Then, without quitting the app, try
            // changing the primarySwatch below to Colors.green and then invoke
            // "hot reload" (press "r" in the console where you ran "flutter run",
            // or simply save your changes to "hot reload" in a Flutter IDE).
            // Notice that the counter didn't reset back to zero; the application
            // is not restarted.
            primarySwatch: Colors.blue,
            // This makes the visual density adapt to the platform that you run
            // the app on. For desktop platforms, the controls will be smaller and
            // closer together (more dense) than on mobile platforms.
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
      }
    
      @override
      void didChangeDependencies() {
        // TODO: implement didChangeDependencies
        super.didChangeDependencies();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              // Here we take the value from the MyHomePage object that was created by
              // the App.build method, and use it to set our appbar title.
              title: Text(widget.title),
            ),
            body: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                    margin: EdgeInsets.only(top: 20, bottom: 20),
                    child: Text(
                      '1.Greetings, planet!',
                      style: TextStyle(
                          fontSize: 30,
                          foreground: Paint()
                            ..shader = ui.Gradient.linear(
                                const Offset(0, 20), const Offset(150, 20), <Color>[
                              Colors.red,
                              Colors.yellow,
                            ])),
                    )),
                Container(
                    margin: EdgeInsets.only(top: 20, bottom: 20),
                    child: Center(
                        child: Text(
                      '2.Greetings!',
                      style: TextStyle(
                          fontSize: 30,
                          foreground: Paint()
                            ..shader = ui.Gradient.linear(
                                const Offset(0, 20), const Offset(150, 20), <Color>[
                              Colors.red,
                              Colors.yellow,
                            ])),
                    ))),
                Container(
                    margin: EdgeInsets.only(top: 20, bottom: 20),
                    child: Text(
                      '3.Greetings, planet!',
                      style: TextStyle(
                          fontSize: 30,
                          foreground: Paint()
                            ..shader = ui.Gradient.linear(const Offset(100, 20),
                                const Offset(250, 20), <Color>[
                              Colors.red,
                              Colors.yellow,
                            ])),
                    )),
                Container(
                  margin: EdgeInsets.only(top: 20, bottom: 20),
                  child: Center(
                      child: Text(
                    '4.Greetings!',
                    style: TextStyle(
                        fontSize: 30,
                        foreground: Paint()
                          ..shader = ui.Gradient.linear(
                              const Offset(100, 20), const Offset(250, 20), <Color>[
                            Colors.red,
                            Colors.yellow,
                          ])),
                  )),
                ),
                Container(
                    margin: EdgeInsets.only(top: 20, bottom: 20),
                    child: Center(
                        child: Text(
                      '5.Greetings!',
                      style: TextStyle(
                          fontSize: 30,
                          foreground: Paint()
                            ..shader = ui.Gradient.linear(const Offset(100, 20),
                                const Offset(250, 20), <Color>[
                              Colors.red,
                              Colors.yellow,
                            ], <double>[
                              0.3,
                              0.9
                            ])),
                    ))),
                Container(
                    margin: EdgeInsets.only(top: 20, bottom: 20),
                    child: Text(
                      '6.Greetings, planet!',
                      style: TextStyle(
                          fontSize: 30,
                          foreground: Paint()
                            ..shader = LinearGradient(colors: [
                              Colors.red,
                              Colors.yellow,
                            ]).createShader(Rect.fromLTWH(0, 0, 150, 0))),
                    )),
                Container(
                  margin: EdgeInsets.only(top: 20, bottom: 20),
                  child: Center(
                    child: TextGradientColorWidget(data: "7.Greetings", colors: [
                      Colors.red,
                      Colors.yellow,
                    ]),
                  ),
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: [
                    Center(
                      child: TextGradientColorWidget(data: "Greetings", colors: [
                        Colors.red,
                        Colors.yellow,
                      ]),
                    ),
                    Center(
                      child: TextGradientColorWidget(data: "Greetings", colors: [
                        Colors.red,
                        Colors.yellow,
                      ]),
                    )
                  ],
                )
              ],
            ) // This trailing comma makes auto-formatting nicer for build methods.
            );
      }
    }
    //根据实际需求设置相关参数
    class TextGradientColorWidget extends StatefulWidget {
      String data;
      TextStyle style;
      List<Color> colors;
    
      TextGradientColorWidget({Key key, this.data, this.colors}) : super(key: key);
    
      @override
      _TextGradientColorState createState() => _TextGradientColorState();
    }
    
    class _TextGradientColorState extends State<TextGradientColorWidget> {
      WidgetsBinding widgetsBinding = WidgetsBinding.instance;
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        if (widget.colors != null) {
          widgetsBinding.addPostFrameCallback((timeStamp) {
            final RenderBox box = context.findRenderObject();
            var left = 0.0;
            var width = 0.0;
            if (box != null) {
              final topLeftPosition = box.localToGlobal(Offset.zero);
              final size = box.size;
              left = topLeftPosition.dx;
              width = size.width;
              setState(() {
                widget.style = TextStyle(
                    fontSize: 30,
                    foreground: Paint()
                      ..shader =
                          LinearGradient(colors: widget.colors, stops: [0.3, 0.8])
                              .createShader(Rect.fromLTWH(left, 0, width, 0)));
              });
    
              //注意 TextStyle中color和foreground 中colors不能同时设置
            }
          });
        }
      }
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return Text(widget.data, style: widget.style);
      }
    }
  • 相关阅读:
    ACL2019对话、问答相关论文整理
    docker for windows添加卷映射
    聊聊多轮任务型对话那些事
    创建用户故事地图(User Story Mapping)的8个步骤
    关于如何做出好的产品
    知识体系整理
    关于如何做好需求的方法
    使用rasa搭建聊天机器人
    【转载】指代消解笔记
    计算机相关会议排名(一)
  • 原文地址:https://www.cnblogs.com/lulushen/p/14169602.html
Copyright © 2020-2023  润新知