如何为flutter包创建新的文本小部件?

问题描述 投票:0回答:4

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

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

flutter flutter-dependencies
4个回答
4
投票

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

您可以制作基于函数的 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(??)运算符检查是否给定值,如果没有给定,则后面将使用默认值。

结论:使用基于类的 Widget,即方法 2 更加稳健,Flutter 官方团队推荐使用基于类的 Widget。它也可以友好地重建并且高性能。

上述代码的输出(M): Output of Code M


0
投票

工作解决方案简单地使用

  • 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)),
    );
  }
}

预期结果:

enter image description here


0
投票

我本来可以很容易地使用小部件

Opacity
,但由于
Flutter document
小部件(
资源
)的Opacity以及孩子
re-rendering
的高昂成本,所以没有必要。 整个问题可以通过
DefaultTextStyle
解决。你只需要关注
handling the context
,也就是下面代码中的
documented

以下代码中可以看到两种模式:

1- 如果您的文本小部件的

TextStyle
not defined
,则它会遵循
DefaultTextStyle.of.(context)
Theme
处的默认颜色,然后还会设置手动不透明度值。

2- 如果您的文本小部件的

TextStyle
defined
,则它遵循定义的颜色,并且还设置其手动不透明度值。

import 'package:flutter/material.dart';

const double OPACITY_VALUE = 0.7;

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomeWidget(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    /// ATTENTION: parent of this context is Material App  .
    return Scaffold(
      body: Center(
        child: Builder(builder: (context2) {
          /// context2 is important because referred to parent , and parent is Scaffold .
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              /// color and textStyle of this text widget referred to current Theme or DefaultTextStyle .
              Text(
                'You have pushed the button this many times:',
                style: DefaultTextStyle.of(context2).style.copyWith(
                    color: DefaultTextStyle.of(context2)
                        .style
                        .color!
                        .withOpacity(OPACITY_VALUE)),
              ),
              const CustomizedTextWidget(color: Colors.purple),
            ],
          );
        }),
      ),
    );
  }
}

class CustomizedTextWidget extends StatelessWidget {
  const CustomizedTextWidget({
    Key? key,
    required this.color,
  }) : super(key: key);
  final Color color;

  @override
  Widget build(BuildContext context) {
    return Text(
      '0',
      style: TextStyle(color: color, fontSize: 32)
          .copyWith(color: color.withOpacity(OPACITY_VALUE)),
    );
  }
}

0
投票

使用 Getx 自定义文本

class CustomText extends StatelessWidget {
  final String text;
  final FontWeight fontWeight;
  final double fontSize;
  final Color color;
  final TextDirection textDirection;
  final TextAlign textAlign;
  final bool softWrap;
  final FontStyle fontStyle;

  CustomText({
    Key? key,
    required this.text,
    this.fontWeight = FontWeight.normal,
    this.fontSize = 14.0,
    this.color = Colors.black,
    this.textDirection = TextDirection.ltr,
    this.textAlign = TextAlign.left,
    this.softWrap = true,
    this.fontStyle = FontStyle.italic,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text(
      text,
      style: TextStyle(
        fontWeight: fontWeight,
        fontSize: fontSize,
        color: color,
        fontStyle: fontStyle,
      ),
      textDirection: textDirection,
      textAlign: textAlign,
      softWrap: softWrap,
    );
  }
}

这样使用:

appBar: CustomAppBar(title: CustomText(text: "Home"),)
© www.soinside.com 2019 - 2024. All rights reserved.