Flutter控件之文本Text封装

news2024/9/29 15:30:45

Flutter控件之基类Widget封装

上篇文章,我们简单针对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:文本控件 Text

class VipText extends BaseWidget {
  final String text; //文本内容
  final TextStyle? style; //文本样式
  final String? leftIcon; //左边的图片
  final double? leftIconWidth; //左边的图片宽度
  final double? leftIconHeight; //左边的图片高度
  final double? iconMarginRight; //图片距离右边的文字距离
  final String? rightIcon; //右边的图片
  final double? rightIconWidth; //右边的图片宽度
  final double? rightIconHeight; //右边的图片高度
  final double? iconMarginLeft; //图片距离左边的文字距离
  final String? topIcon; //上边的图片
  final double? topIconWidth; //上边的图片宽度
  final double? topIconHeight; //上边的图片高度
  final double? iconMarginBottom; //图片距离下边的文字距离
  final String? bottomIcon; //下边的图片
  final double? bottomIconWidth; //下边的图片宽度
  final double? bottomIconHeight; //下边的图片高度
  final double? iconMarginTop; //图片距离上边的文字距离
  final MainAxisAlignment? mainAxisAlignment; //文字的位置
  final TextOverflow? textOverflow; //文字溢出方式
  final TextAlign? textAlign;//文字位置
  final int? maxLines;//最大行数
  final List<TextRichBean>? richList; //富文本数据
  final Function(int, TextRichBean)? onRichClick; //富文本点击事件

  const VipText(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});

  /*
  * 返回图片的组件
  * */
  Widget getImageWidget(String icon, double width, double height) {
    if (icon.contains("http")) {
      return Image.network(icon, width: width, height: height);
    } else {
      return Image.asset(icon, width: width, height: height);
    }
  }

  @override
  Widget getWidget(BuildContext context) {
    List<Widget> widgets = [];
    //左边的Icon
    if (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(),
      ));
    }

    //右边的Icon
    if (rightIcon != null) {
      widgets
          .add(getImageWidget(rightIcon!, rightIconWidth!, rightIconHeight!));
    }

    if (widgets.isNotEmpty) {
      return Row(
        mainAxisAlignment: mainAxisAlignment!,
        children: widgets,
      );
    }

    //上边的icon
    if (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(),
      ));
    }
    //下面的icon
    if (bottomIcon != null) {
      widgets.add(
          getImageWidget(bottomIcon!, bottomIconWidth!, bottomIconHeight!));
    }
    if (widgets.isNotEmpty) {
      return Column(
        mainAxisAlignment: mainAxisAlignment!,
        children: widgets,
      );
    }

    //富文本
    if (richList != null && richList!.isNotEmpty) {
      List<TextSpan> list = [];
      for (var a = 0; a < richList!.length; a++) {
        var richBean = richList![a];
        var textSpan = TextSpan(
            text: richBean.text,
            recognizer: TapGestureRecognizer()
              ..onTap = () {
                //点击事件
                if (onRichClick != null) {
                  onRichClick!(a, richBean);
                }
              },
            style: TextStyle(
                fontSize: richBean.textSize, color: richBean.textColor));
        list.add(textSpan);
      }
      //富文本
      return Text.rich(TextSpan(children: list));
    }
    return getTextWidget();
  }

  Widget getTextWidget() {
    return Text(
      text,
      overflow: textOverflow,
      textAlign: textAlign,
      maxLines: maxLines,
      style: style,
    );
  }
}

TextRichBean

用于富文本数据渲染

import 'package:flutter/material.dart';

///AUTHOR:AbnerMing
///DATE:2023/5/19
///INTRODUCE:文本控件之富文本对象

class TextRichBean {
  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效果

class TextPage extends StatefulWidget {
  const TextPage({super.key});

  @override
  State<StatefulWidget> createState() => _TextPageState();
}

class _TextPageState extends State<TextPage> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        VipText("普通文字", marginTop: 10, onClick: () {
          print("普通文字");
        }),
        VipText("加粗文字",
            marginTop: 10,
            style: const TextStyle(fontWeight: FontWeight.bold), onClick: () {
          print("加粗文字");
        }),
        VipText("倾斜文字",
            marginTop: 10,
            style: const TextStyle(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: const TextStyle(decoration: TextDecoration.underline),
            onClick: () {
          print("下划线文字");
        }),
        VipText("下划波浪线文字",
            marginTop: 10,
            style: const TextStyle(
              decoration: TextDecoration.underline,
              decorationStyle: TextDecorationStyle.wavy,
            ), onClick: () {
          print("下划波浪线文字");
        }),
        VipText("删除线文字",
            marginTop: 10,
            style: const TextStyle(decoration: TextDecoration.lineThrough),
            onClick: () {
          print("删除线文字");
        }),
        ShaderMask(
          shaderCallback: (Rect bounds) {
            return const LinearGradient(
              colors: [Colors.red, Colors.blue],
            ).createShader(Offset.zero & bounds.size);
          },
          child: VipText(
            '文字设置渐变色',
            marginTop: 10,
            style: const TextStyle(
              fontSize: 16,
              color: Colors.white,
              fontWeight: FontWeight.bold,
            ),
            onClick: () {
              print("文字设置渐变色");
            },
          ),
        ),
        VipText("改变颜色",
            style: const TextStyle(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)
      ],
    );
  }
}

四、相关总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/545675.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚拟机启动时出现“已启用侧通道缓解”的解决方法

系列文章目录 Hypervisor launch failed centos7配置ssh免密登陆完成&#xff0c;进行ssh登陆时出现”代理承认未能使用密钥签名“ 解决pip更新的代码 文章目录 系列文章目录 一、问题描述 二、启用了侧通道缓解的虚拟机可能会出现性能下降 &#xff08;79832&#xff0…

Linux系统vim查看文件中文乱码

Linux系统查看文件-cat中文正常显示 vim中文乱码 1、背景2、环境3、目的4、原因5、操作步骤5.1、修改vim编码配置 6、验证 1、背景 服务器部署业务过程中查看文件内容&#xff0c;使用cat 命令查看中文正常显示&#xff0c;使用vim命令查看显示中文乱码 cat 查看 vim 查看 …

陶哲轩宣布主持白宫生成式AI工作组,李飞飞、Hassabis发表演讲

来源 | 新智源 ID | AI-era 【导读】最近&#xff0c;「数学天才」陶哲轩表示&#xff0c;自己将领导白宫生成式人工智能工作组&#xff0c;就当前AI评估并收集意见。在陶哲轩看来&#xff0c;加入工作流的ChatGPT在数学专业领域中&#xff0c;并没有太多增值。 近来&#xf…

Redis主从复制、哨兵、cluster集群原理+实验

Redis 主从复制 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点(Master)&#xff0c;后者称为从节点(Slave)&#xff1b;数据的复制是单向的&#xff0c;只能由主节点到从节点。 默认情况下&#xff0c;每台Redis服务…

Fluent局部坐标系(曲线坐标系)

1 概述 在某些模型中&#xff0c;利用局部坐标系可极大的方便模型设置&#xff0c;例如对弯曲的多孔板设置多孔介质属性、设置各向异性的材料属性等。 2 创建坐标系 通过树状菜单中“curvilinear coordinate system”可创建曲线型局部坐标系。 右键点击“新建”&#xff0c;在如…

Linux 安装redis

一、概述 官网&#xff1a;https://redis.io/ Redis 是完全开源免费的&#xff0c;遵守BSD协议&#xff0c;是一个高性能的key-value数据库。 Redis 与其他 key - value 缓存产品有以下三个特点&#xff1a; Redis支持数据的持久化&#xff0c;可以将内存中的数据保持在磁盘…

基于静态和动态特征融合的语音情感识别层次网络

题目Hierarchical Network based on the Fusion of Static and Dynamic Features for Speech Emotion Recognition时间2021年期刊\会议ICASSP 基于静态和动态特征融合的语音情感识别层次网络 摘要&#xff1a;许多关于自动语音情感识别&#xff08;SER&#xff09;的研究都致…

【集群划分】基于kmeans的电压调节的集群划分【IEEE33节点】

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

HTTP/HTTPS协议详解

目录 一. HTTP详解 ✅1.1 概念 ✅1.2 HTTP的协议格式 1.2.1 HTTP请求体格式&#xff1a; 1.2.2 HTTP响应体格式&#xff1a; ✅1.3 HTTP请求方法 ✅1.4 认识请求报头 ✅1.5 HTTP请求过程 ✅1.6 认识状态码 二. HTTPS详解 ✅2.1 HTTPS简介 ✅2.2 HTTPS加密过程 TCP/UDP是位于传…

d3d(Direct X)中的com技术详解

本文不会对Com进行非常详细的分析 因为这个技术分析起来难度还是非常大的 要想真正弄懂还是非常困难的 我只会针对d3d中使用到的com技术和comptr技术进行说明 所以看完本文后 可以熟练使用d3d中使用到的相应技术 comptr类似于c11中的智能指针,用于管理com对象的生命周期,所以我…

深度学习基础篇之卷积神经网络(CNN)

一、CNN的基本结构 首先我们来看CNN的解百纳结构&#xff0c;一个常见的图像识别CNN模型如下图&#xff1a; 从图中可以看出最左边的图像就是模型的输入层&#xff0c;在计算机中就是若干个矩阵&#xff0c;这点与DNN类似。 接着是卷积层&#xff08;Convolution Layer&…

rtmp协议

目录 1 rtmp格式 2 header 3 chunk data 1 rtmp格式 Real Time Messaging Protocol&#xff08;实时消息传送协议协议)是Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输开发的私有协议。 在RTMP协议中信令和媒体数据都称之为Message&#xff0c;包含Mess…

Intellij IDEA 提示 Thrift Support 支持不兼容

最近升级 Intellij IDEA 后老提示 Thrift Support 不兼容。 后来看了下这个插件已经不少时间没有更新了&#xff0c;也一直不知道这个插件是干什么 用的&#xff0c; 后来看了下&#xff0c;这个插件是&#xff1a; Thrift是一种接口描述语言和二进制通讯协议&#xff0c;它被…

【031】基于Vue的学生宿舍管理系统课设(含源码、数据库、运行教程

前排提示&#xff1a;项目源码已放在文末 基于VueSpringbootmysql员工考勤管理系统(多角色登录、请假、打卡) 开发环境&#xff1a;SpringbootMysqlVueNodejsMavenJDK1.8&#xff0b;redis 技术栈&#xff1a;spring-boot、mysql、mybatis-plus 数据库&#xff1a; 源码、…

Centos7单机部署Flink13.6及测试FinkCDC同步MySQL

一、背景 公司CDH6.3.2里面的版本是Flink1.12.0。而因为FlinkCDC2.0.0只支持Flink1.13.0以后&#xff0c;版本不匹配&#xff0c;所以只能升级版本。但是升级版本是个大工程&#xff0c;要编译、要parcel制作工具&#xff0c;而且是生产环境的升级&#xff0c;没办法因为要测试…

初识Spring MVC框架,Spring MVC工作原理

Java EE三层架构 在Java EE开发中&#xff0c;系统经典的三层架构包括表现层、业务层和持久层。三层架构中&#xff0c;每一层各司其职&#xff0c;表现层(Web层&#xff09;负责接收客户端请求&#xff0c;并向客户端响应结果;业务层( Service层&#xff09;负责业务逻辑处理…

3 手工推导Neural Networ

线性模型假设的问题 如上图&#xff0c;对非线性类边界的数据进行分类 一个解决方案是将数据映射到更高维的空间&#xff0c;就变成线性可分的了。 ϕ \phi ϕ 是一个映射函数&#xff0c;将x从一个低维空间映射到高维空间。 ϕ \phi ϕ 可不可以是一个线性函数&#xff1f; …

RK3568平台开发系列讲解(驱动基础篇)GPIO使用以及gpio-leds驱动讲解

🚀返回专栏总目录 文章目录 一、GPIO 介绍二、RK3568 GPIO 状况三、GPIO 引脚计算四、ITX-3568JQ LED4.1 LED 原理图4.2 LED 设备树4.3 LED 使用五、gpio-leds驱动5.1 介绍5.2 数据结构5.3 驱动分析沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍 GPIO使用…

[Hadoop]Apache Hadoop、HDFS

目录 大数据导论与Linux基础 Apache Hadopp概述 Hadoop介绍 Hadoop现状 Hadoop特性优点 Hadopp架构变迁 Apache Hadopp集群搭建 Hadopp集群简介 Hadoop集群模式安装 Hadoop集群启停命令、Web UI HDFS分布式文件系统基础 分布式存储系统的核心属性及功能含义 HDFS简…

Linux多路转接之epoll

文章目录 一、select方案和poll方案还存在的缺陷二、epoll的认识1.epoll的基本认识2.epoll的原理3.epoll函数接口 三、编写epoll服务器四、epoll工作方式1.LT模式2.ET模式 一、select方案和poll方案还存在的缺陷 多路转接方案一开始是select方案&#xff0c;但是select方案缺点…