Flutter控件之文本Text封装

简介: 文本Text比较简单,除了基类BaseWidget所提供的属性之外,又简单的扩展了部分属性,比如图文和富文本,都是系统原生的提供的,做了简单的封装。

上篇文章,我们简单针对Widget做了一个基类封装,拓展出了很多常见又易用的属性,比如宽高,内外边距等等,很方便的为接下来的各个基础组件的封装,提供极大的便利,在上篇文章中,诉说了BaseWidget可以单独使用,也可以让别的组件继承使用,目的就是为了拓展,而本篇文章就是基于上篇,我们拓展一下Text组件。


本篇文章的内容大概如下:

1、实际的效果一览

2、Text相关属性分析

3、源码和具体使用

4、相关总结

一、实际的效果一览


文本Text比较简单,除了基类BaseWidget所提供的属性之外,又简单的扩展了部分属性,比如图文和富文本,都是系统原生的提供的,做了简单的封装。


二、Text相关属性分析


关于文本的属性,为什么要去继承BaseWidget,也就是上篇封装的基类,一个重要的原因就是,拓展文本的点击,内外边距和相关背景等属性,方便在实际的开发中进行调用。


文本所提供的常见属性,如文字的大小,颜色等,我们可以原封不动的抛出去,毕竟这都是基本的属性,我们没必要再一一自己实现,为了更好的符合实际的开发需要,比如富文本,带有Icon等等,我们尽量也拓展一下。


自定义的文本属性相对不是很多,大致如下,这些属性,还是那句话,需要根据实际的需求和业务,我们选择性进行使用。


属性

类型

概述

text

String

文本内容

style

TextStyle

文本样式

leftIcon

String

左边的图片

leftIconWidth

double

左边的图片宽度

leftIconHeight

double

左边的图片高度

iconMarginRight

double

图片距离右边的文字距离

rightIcon

String

右边的图片

rightIconWidth

double

右边的图片宽度

rightIconHeight

double

右边的图片高度

iconMarginLeft

double

图片距离左边的文字距离

topIcon

String

上边的图片

topIconWidth

double

上边的图片宽度

topIconHeight

double

上边的图片高度

iconMarginBottom

double

图片距离下边的文字距离

bottomIcon

String

下边的图片

bottomIconWidth

double

下边的图片宽度

bottomIconHeight

double

下边的图片高度

iconMarginTop

double

图片距离上边的文字距离

mainAxisAlignment

MainAxisAlignment

文字的相对父位置

textOverflow

TextOverflow

文字溢出方式

textAlign

TextAlign

文字位置

maxLines

int

最大行数

richList

List<TextRichBean>

富文本数据

onRichClick

Function(int, TextRichBean)

富文本点击事件


三、源码和具体使用


源码相对比较简单,毕竟都是系统的Api,无非就是做了一个简单的封装,首先是继承了BaseWidget,实现了getWidget方法,这个很重要,因为所有的组件效果,都是从这个方法里进行渲染的。


关于这个Text类,需要注意是,如果你想把基类的属性拓展出去,那么就可以在构造方法里进行super一下,具体需要拓展哪些,完全按实际的业务去走,并不是所有的属性都需要拓展。

相关注释已经标记,大家可以直接使用。


自定义文本源码

import'package:flutter/gestures.dart';
import'package:flutter/material.dart';
import'../../base/base_widget.dart';
import'../../data/bean/text_rich_bean.dart';
///AUTHOR:AbnerMing///DATE:2023/5/19///INTRODUCE:文本控件 TextclassVipTextextendsBaseWidget {
finalStringtext; //文本内容finalTextStyle?style; //文本样式finalString?leftIcon; //左边的图片finaldouble?leftIconWidth; //左边的图片宽度finaldouble?leftIconHeight; //左边的图片高度finaldouble?iconMarginRight; //图片距离右边的文字距离finalString?rightIcon; //右边的图片finaldouble?rightIconWidth; //右边的图片宽度finaldouble?rightIconHeight; //右边的图片高度finaldouble?iconMarginLeft; //图片距离左边的文字距离finalString?topIcon; //上边的图片finaldouble?topIconWidth; //上边的图片宽度finaldouble?topIconHeight; //上边的图片高度finaldouble?iconMarginBottom; //图片距离下边的文字距离finalString?bottomIcon; //下边的图片finaldouble?bottomIconWidth; //下边的图片宽度finaldouble?bottomIconHeight; //下边的图片高度finaldouble?iconMarginTop; //图片距离上边的文字距离finalMainAxisAlignment?mainAxisAlignment; //文字的位置finalTextOverflow?textOverflow; //文字溢出方式finalTextAlign?textAlign;//文字位置finalint?maxLines;//最大行数finalList<TextRichBean>?richList; //富文本数据finalFunction(int, TextRichBean)?onRichClick; //富文本点击事件constVipText(this.text,
      {super.key,
this.style,
this.leftIcon,
this.leftIconWidth=22,
this.leftIconHeight=22,
this.iconMarginRight=0,
this.rightIcon,
this.rightIconWidth=22,
this.rightIconHeight=22,
this.iconMarginLeft=0,
this.topIcon,
this.topIconWidth=22,
this.topIconHeight=22,
this.iconMarginBottom=0,
this.bottomIcon,
this.bottomIconWidth=22,
this.bottomIconHeight=22,
this.iconMarginTop=0,
this.mainAxisAlignment=MainAxisAlignment.center,
this.textOverflow,
this.textAlign,
this.maxLines,
this.richList,
this.onRichClick,
super.width,
super.height,
super.margin,
super.marginLeft,
super.marginTop,
super.marginRight,
super.marginBottom,
super.padding,
super.paddingLeft,
super.paddingTop,
super.paddingRight,
super.paddingBottom,
super.backgroundColor,
super.strokeWidth,
super.strokeColor,
super.solidColor,
super.radius,
super.isCircle,
super.leftTopRadius,
super.rightTopRadius,
super.leftBottomRadius,
super.rightBottomRadius,
super.childWidget,
super.alignment,
super.onClick,
super.onDoubleClick,
super.onLongPress});
/** 返回图片的组件* */WidgetgetImageWidget(Stringicon, doublewidth, doubleheight) {
if (icon.contains("http")) {
returnImage.network(icon, width: width, height: height);
    } else {
returnImage.asset(icon, width: width, height: height);
    }
  }
@overrideWidgetgetWidget(BuildContextcontext) {
List<Widget>widgets= [];
//左边的Iconif (leftIcon!=null) {
widgets.add(getImageWidget(leftIcon!, leftIconWidth!, leftIconHeight!));
    }
//水平中间的文字if (leftIcon!=null||rightIcon!=null) {
widgets.add(Container(
margin: EdgeInsets.only(left: iconMarginRight!, right: iconMarginLeft!),
child: getTextWidget(),
      ));
    }
//右边的Iconif (rightIcon!=null) {
widgets          .add(getImageWidget(rightIcon!, rightIconWidth!, rightIconHeight!));
    }
if (widgets.isNotEmpty) {
returnRow(
mainAxisAlignment: mainAxisAlignment!,
children: widgets,
      );
    }
//上边的iconif (topIcon!=null) {
widgets.add(getImageWidget(topIcon!, topIconWidth!, topIconHeight!));
    }
//垂直中间的文字if (topIcon!=null||bottomIcon!=null) {
widgets.add(Container(
margin: EdgeInsets.only(top: iconMarginBottom!, bottom: iconMarginTop!),
child: getTextWidget(),
      ));
    }
//下面的iconif (bottomIcon!=null) {
widgets.add(
getImageWidget(bottomIcon!, bottomIconWidth!, bottomIconHeight!));
    }
if (widgets.isNotEmpty) {
returnColumn(
mainAxisAlignment: mainAxisAlignment!,
children: widgets,
      );
    }
//富文本if (richList!=null&&richList!.isNotEmpty) {
List<TextSpan>list= [];
for (vara=0; a<richList!.length; a++) {
varrichBean=richList![a];
vartextSpan=TextSpan(
text: richBean.text,
recognizer: TapGestureRecognizer()
              ..onTap= () {
//点击事件if (onRichClick!=null) {
onRichClick!(a, richBean);
                }
              },
style: TextStyle(
fontSize: richBean.textSize, color: richBean.textColor));
list.add(textSpan);
      }
//富文本returnText.rich(TextSpan(children: list));
    }
returngetTextWidget();
  }
WidgetgetTextWidget() {
returnText(
text,
overflow: textOverflow,
textAlign: textAlign,
maxLines: maxLines,
style: style,
    );
  }
}


TextRichBean


用于富文本数据渲染


import'package:flutter/material.dart';
///AUTHOR:AbnerMing///DATE:2023/5/19///INTRODUCE:文本控件之富文本对象classTextRichBean {
String?text; //文字Color?textColor; //文字颜色double?textSize; //文字大小String?link; //文字链接TextRichBean({this.text, this.textColor, this.textSize, this.link});
}

具体使用


简单的就可以如下使用,需要什么属性,直接书写即可,比如内外边距,点击事件等等。


VipText("普通文字", marginTop: 10, onClick: () {
print("普通文字");
 })

所有使用方式案例(可直接复制使用)


import'package:flutter/material.dart';
import'../../data/bean/text_rich_bean.dart';
import'../widget/vip_text.dart';
///AUTHOR:AbnerMing///DATE:2023/5/19///INTRODUCE:文本Text效果classTextPageextendsStatefulWidget {
constTextPage({super.key});
@overrideState<StatefulWidget>createState() =>_TextPageState();
}
class_TextPageStateextendsState<TextPage> {
@overrideWidgetbuild(BuildContextcontext) {
returnColumn(
children: [
VipText("普通文字", marginTop: 10, onClick: () {
print("普通文字");
        }),
VipText("加粗文字",
marginTop: 10,
style: constTextStyle(fontWeight: FontWeight.bold), onClick: () {
print("加粗文字");
        }),
VipText("倾斜文字",
marginTop: 10,
style: constTextStyle(fontStyle: FontStyle.italic), onClick: () {
print("倾斜文字");
        }),
VipText("文字背景颜色", marginTop: 10, backgroundColor: Colors.red,
onClick: () {
print("文字背景颜色");
        }),
VipText("文字圆角背景",
marginTop: 10,
radius: 10,
solidColor: Colors.red,
padding: 3, onClick: () {
print("文字圆角背景");
        }),
VipText("文字圆角框背景",
marginTop: 10,
radius: 10,
strokeColor: Colors.red,
padding: 3, onClick: () {
print("文字圆角框背景");
        }),
VipText("圆",
marginTop: 10,
isCircle: true,
solidColor: Colors.cyan,
padding: 8, onClick: () {
print("圆");
        }),
VipText("下划线文字",
marginTop: 10,
style: constTextStyle(decoration: TextDecoration.underline),
onClick: () {
print("下划线文字");
        }),
VipText("下划波浪线文字",
marginTop: 10,
style: constTextStyle(
decoration: TextDecoration.underline,
decorationStyle: TextDecorationStyle.wavy,
            ), onClick: () {
print("下划波浪线文字");
        }),
VipText("删除线文字",
marginTop: 10,
style: constTextStyle(decoration: TextDecoration.lineThrough),
onClick: () {
print("删除线文字");
        }),
ShaderMask(
shaderCallback: (Rectbounds) {
returnconstLinearGradient(
colors: [Colors.red, Colors.blue],
            ).createShader(Offset.zero&bounds.size);
          },
child: VipText(
'文字设置渐变色',
marginTop: 10,
style: constTextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.bold,
            ),
onClick: () {
print("文字设置渐变色");
            },
          ),
        ),
VipText("改变颜色",
style: constTextStyle(color: Colors.red),
marginTop: 10, onClick: () {
print("改变颜色");
        }),
VipText("左边带有Icon",
marginTop: 10,
//可以是网络图片或assets图片leftIcon: "https://www.vipandroid.cn/ming/image/gan.png",
iconMarginRight: 10, onClick: () {
print("左边带有Icon");
        }),
VipText("右边带有Icon",
marginTop: 10,
//可以是网络图片或assets图片rightIcon: "https://www.vipandroid.cn/ming/image/gan.png",
iconMarginLeft: 10, onClick: () {
print("左边带有Icon");
        }),
VipText("左右边都带有Icon",
marginTop: 10,
//可以是网络图片或assets图片leftIcon: "https://www.vipandroid.cn/ming/image/gan.png",
rightIcon: "https://www.vipandroid.cn/ming/image/gan.png",
iconMarginRight: 10,
iconMarginLeft: 10, onClick: () {
print("左右边都带有Icon");
        }),
VipText("上边带有Icon",
marginTop: 10,
strokeColor: Colors.red,
//可以是网络图片或assets图片topIcon: "https://www.vipandroid.cn/ming/image/gan.png",
onClick: () {
print("上边带有Icon");
        }),
VipText("下边带有Icon",
strokeColor: Colors.red,
marginTop: 10,
//可以是网络图片或assets图片bottomIcon: "https://www.vipandroid.cn/ming/image/gan.png",
onClick: () {
print("下边带有Icon");
        }),
VipText(
"超出的文字展示省略号,不妨我们就简单测试一下,看看是否能实现,再多打些文字看看吧,马上就够了,不着急哈,再输入一点",
textOverflow: TextOverflow.ellipsis,
marginLeft: 10,
marginRight: 10,
maxLines: 2,
marginTop: 10,
onClick: () {
print("超出文字点击");
          },
        ),
VipText("富文本设置", richList: [
TextRichBean(text: "我已经阅读并同意"),
TextRichBean(text: "《用户服务协议》", textColor: Colors.red),
TextRichBean(text: "和"),
TextRichBean(text: "《用户隐私政策》", textColor: Colors.red)
        ], onRichClick: (position, richBean) {
//富文本点击事件print(richBean.text);
        }, marginTop: 10)
      ],
    );
  }
}

四、相关总结

关于子类需要拓展父类的哪些属性,这个需要结合实际的项目和需求而定,而关于自定义组件的命名,也需要根据公司而定,好了老铁们,一个简单的文本组件就介绍到这里,希望可以帮助到大家。

相关文章
|
6月前
Flutter 组件(二)文本 与 输入框组件
Flutter 组件(二)文本 与 输入框组件
430 0
|
缓存 Java 开发工具
Flutter的文本、图片和按钮使用
Flutter的文本、图片和按钮使用
123 0
|
3月前
|
Android开发
Flutter控件的显示与隐藏
Flutter控件的显示与隐藏
151 3
|
17天前
|
存储 缓存 Dart
Flutter&鸿蒙next 封装 Dio 网络请求详解:登录身份验证与免登录缓存
本文详细介绍了如何在 Flutter 中使用 Dio 封装网络请求,实现用户登录身份验证及免登录缓存功能。首先在 `pubspec.yaml` 中添加 Dio 和 `shared_preferences` 依赖,然后创建 `NetworkService` 类封装 Dio 的功能,包括请求拦截、响应拦截、Token 存储和登录请求。最后,通过一个登录界面示例展示了如何在实际应用中使用 `NetworkService` 进行身份验证。希望本文能帮助你在 Flutter 中更好地处理网络请求和用户认证。
132 1
|
17天前
|
Dart UED 开发者
Flutter&鸿蒙next中的按钮封装:自定义样式与交互
在Flutter应用开发中,按钮是用户界面的重要组成部分。Flutter提供了多种内置按钮组件,但有时这些样式无法满足特定设计需求。因此,封装一个自定义按钮组件变得尤为重要。自定义按钮组件可以确保应用中所有按钮的一致性、可维护性和可扩展性,同时提供更高的灵活性,支持自定义颜色、形状和点击事件。本文介绍了如何创建一个名为CustomButton的自定义按钮组件,并详细说明了其样式、形状、颜色和点击事件的处理方法。
67 1
|
17天前
|
开发工具 UED
Flutter&鸿蒙next中封装一个输入框组件
本文介绍了如何创建一个简单的Flutter播客应用。首先,通过`flutter create`命令创建项目;接着,在`lib`目录下封装一个自定义输入框组件`CustomInput`;然后,在主应用文件`main.dart`中使用该输入框组件,实现简单的UI布局和功能;最后,通过`flutter run`启动应用。本文还提供了后续扩展建议,如状态管理、网络请求和UI优化。
94 1
|
18天前
|
存储 缓存 JavaScript
Flutter 学习之封装 WebView
【10月更文挑战第24天】通过以上的探讨,我们可以看出,在 Flutter 中封装 WebView 是非常有必要的,它可以提高代码的复用性、增强可维护性、提供统一接口。在实际应用中,我们需要根据具体的需求和场景,选择合适的封装方法和技术,以实现更好的效果。
|
15天前
|
开发工具
Flutter&鸿蒙next中封装一个列表组件
Flutter&鸿蒙next中封装一个列表组件
30 0
|
17天前
|
Dart 安全 UED
Flutter&鸿蒙next中的表单封装:提升开发效率与用户体验
在移动应用开发中,表单是用户与应用交互的重要界面。本文介绍了如何在Flutter中封装表单,以提升开发效率和用户体验。通过代码复用、集中管理和一致性的优势,封装表单组件可以简化开发流程。文章详细讲解了Flutter表单的基础、封装方法和表单验证技巧,帮助开发者构建健壮且用户友好的应用。
58 0
|
2月前
|
容器
Flutter基本组件Text使用
Flutter基本组件Text使用
49 12