【问题标题】:how to create new text widget for flutter package?如何为 flutter 包创建新的文本小部件?
【发布时间】:2023-01-25 17:56:11
【问题描述】:

我需要在 Flutter 中创建一个自定义文本小部件。我必须更改它在不透明度为 0.7 的样式中接受的任何颜色。如果它没有样式,我必须显示默认样式的颜色,不透明度为 0.7 。

我的问题是使用我描述的功能创建一个新的文本小部件。

【问题讨论】:

  • 默认样式到底是什么意思? -> “我必须显示默认样式的颜色,不透明度为 0.7”。您是否已定义默认样式或 Material App 中的默认主题?

标签: flutter flutter-dependencies


【解决方案1】:

有多种方法可以解决此问题:

您可以创建基于函数的 Widget 或基于类的 Widget:

基于功能的小部件:

Widget myCustomText({required String data, Color? customColor}) {
    return Opacity(
      opacity: 0.7,
      child: Text(
        data,
        style: TextStyle(
          color: customColor ?? Colors.black,
        ),
      ),
    );
  }

另一种方法是制作基于类的小部件:

class MyCustomText extends StatelessWidget {
  final String data;
  final Color? customColor;
  const MyCustomText({Key? key, required this.data, this.customColor})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Opacity(
      opacity: 0.7,
      child: Text(
        data,
        style: TextStyle(color: customColor ?? Colors.black),
      ),
    );
  }
}

以下是您可以根据需要实施自定义文本的方法: //代码M:

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [

          //Widget based Implementation
          myCustomTextWidget(data: "Hello world"),
          myCustomTextWidget(data: "Hello Peter", customColor: Colors.amber),

          //Class based implementation
          MyCustomTextClassWidget(data: "Hello Spidey"),
          MyCustomTextClassWidget(data: "Hello 007", customColor: Colors.orange,)
        ],
      ),
    );
  }
}

说明:Null(??) 运算符检查是否给定了值,如果没有给定,则在其后使用默认值。

结论:使用基于类的小部件,即方法 2 更健壮,Flutter 官方团队推荐使用基于类的小部件。它还可以友好地重建并且具有高性能。

上述代码的输出(M):

【讨论】:

  • 始终建议对颜色本身应用不透明度而不是使用不透明度小部件,因为后者要慢得多。
  • 使用扩展是一种矫枉过正,TextStyle.copyWith 就足够了
  • 使用不透明度小部件很昂贵,不推荐使用。请参阅关于不透明度的 flutter 文档 - 小部件:使其子部分透明的小部件。此类将其子对象绘制到中间缓冲区中,然后将子对象混合回场景中。 api.flutter.dev/flutter/widgets/Opacity-class.html
【解决方案2】:

工作解决方案只是使用

  • ThemeData.primaryColor为默认文字颜色配置;
  • 如果没有TextStyle传递给CustomTextWidget,则使用默认文本颜色,不透明度为0.7;
  • 如果确实有 TextStyle 传递给 CustomTextWidget,则使用不透明度为 0.7 的 textStyle。

代码在这里:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: const HomeWidget(title: _title),
      theme: ThemeData.light().copyWith(
        // default text color
        primaryColor: Colors.pink,
        colorScheme: ColorScheme.fromSwatch().copyWith(
          // change the appbar color
          primary: Colors.green[800],
        ),
      ),
    );
  }
}

class HomeWidget extends StatelessWidget {
  const HomeWidget({
    Key? key,
    required String title,
  })  : _title = title,
        super(key: key);

  final String _title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_title),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: const [
          CustomTextWidget(text: 'text does not have a style'),
          CustomTextWidget(
            text: 'text with passed black color style and fontSize 24',
            textStyle: TextStyle(
              fontSize: 24,
              color: Colors.black
            ),
          ),
          CustomTextWidget(
            text: 'text with passed blue color style',
            textStyle: TextStyle(
                color: Colors.blue
            ),
          ),
        ],
      ),
    );
  }
}

class CustomTextWidget extends StatelessWidget {
  final String text;
  final TextStyle? textStyle;

  const CustomTextWidget({Key? key, required this.text, this.textStyle}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final TextStyle finalTextStyle = textStyle ?? const TextStyle();
    final Color? finalColor = textStyle != null && textStyle!.color != null
        ? textStyle!.color
        : Theme.of(context).primaryColor;

    return Text(
      text,
      // it accepts in the style with an opacity of 0.7.
      style: finalTextStyle.copyWith(color: finalColor!.withOpacity(0.7)),
    );
  }
}

预期结果:

【讨论】:

    【解决方案3】:

    使用Opacity小部件

    Opacity(
          opacity: 0.8,
          child: Text(
           "Your Text",
            style: TextStyle(color:  Colors.black),
          )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-09
      • 1970-01-01
      • 2020-12-11
      • 1970-01-01
      • 2020-12-06
      • 1970-01-01
      • 2011-01-31
      相关资源
      最近更新 更多