Flutter 实现不同样式(有样式) 的TextField (可自定义),类似微博#话题#、@用户,(给TextField加TextSpan)
描述
先上效果图

在项目中,有 @ 和 话题功能,需要在编辑时即可回显,但是官方原生的TextField不支持对部分文字定义不同的样式,所以封装了一个。
注意:这不是富文本插件,不支持在输入框中显示图片,仅是 TextField 的扩展,让其支持自定义 TextSpan。
本文介绍封装思路,如果想要直接在项目中应用,可以直接通过以下方式引入:
插件地址:https://pub.dev/packages/text_span_field
text_span_field: 1.0.0
使用方式为:
TextSpanField(
controller: TextEditingController(
text: "这是一条测试信息,你们看他的颜色",
),
rangeStyles: [
RangeStyle(
range: TextRange(start: 0, end: 1),
style: TextStyle(color: Color(0xFF5BA2FF)),
),
RangeStyle(
range: TextRange(start: 3, end: 4),
style: TextStyle(color: Color(0xFF9C7BFF)),
),
],
),
正文
项目地址:https://github.com/JiangJuHong/FlutterTextSpanField
项目结构:

首先,我们要在TextField中进行扩展,必要的查看源代码,直接跳转到 build 渲染,发现代码如下:

TextField内部使用的是EditableText,在Flutter官网介绍如如下:

"基本文本输入域"
EditableText 组件内部有一个可重写方法 buildTextSpan,它定义了内容如何展示在输入框中,默认未经过处理,我们需要展示不同的内容,则需要重写该方法并根据要求进行封装。
第一步:继承 EditableText 并重写 buildTextSpan 属性
因此我们创建一个名叫 “EditableTextSpan”的组件,并继承了EditableText,然后重写了buildTextSpan,经过重写的代码如下:

代码地址:https://github.com/JiangJuHong/FlutterTextSpanField/blob/master/lib/editable_text_span.dart
其中 rangeStyle 为自定义范围样式类,方便组件使用时传递,rangeStyle代码为:
import 'package:flutter/cupertino.dart'; /// 范围样式,规定不同范围不同样式
class RangeStyle extends Comparable<RangeStyle> {
RangeStyle({@required this.range, this.style}); /// 范围
final TextRange range; /// 指定样式
final TextStyle style; @override
int compareTo(RangeStyle other) {
return range.start.compareTo(other.range.start);
} @override
String toString() {
return 'RangeStyle(range:$range, style:$style)';
}
}
代码地址:https://github.com/JiangJuHong/FlutterTextSpanField/blob/master/lib/range_style.dart
重写的 buildTextSpan 中主要的业务逻辑为根据 TextRange 定义的范围,应用不同的 TextStyle
第二步:重新封装TextField
buildTextSpan重写完毕后,默认的TextField并不会使用我们重写过后的文件,所以我们需要进行如下步骤操作:
1. 将 TextField的文件拷贝出来后命名为TextSpanField,随后将 build 方法中的EditableText 替换成EditableTextSpan。

2. 在 TextSpanField 中公开 rangeStyle 属性,并传递给 EditabledTextSpan
代码地址:https://github.com/JiangJuHong/FlutterTextSpanField/blob/master/lib/text_span_field.dart
结束
到这一步,我们组件已经封装完成,可以实现对不同的范围渲染不同的样式。
使用方法:
TextSpanField(
controller: TextEditingController(
text: "这是一条测试信息,你们看他的颜色",
),
rangeStyles: [
RangeStyle(
range: TextRange(start: 0, end: 1),
style: TextStyle(color: Color(0xFF5BA2FF)),
),
RangeStyle(
range: TextRange(start: 3, end: 4),
style: TextStyle(color: Color(0xFF9C7BFF)),
),
],
),
由于本文章并未精准讲解每一行代码,可能需要结合源代码一起研究,源代码地址为:https://github.com/JiangJuHong/FlutterTextSpanField/tree/master/lib
该内容已封装为插件 text_span_field ,由于并未对原生内容进行改动,所以兼容TextField,理论上在TextField支持的操作,在TextSpanField同样支持。
我的主页:https://github.com/JiangJuHong
Flutter 实现不同样式(有样式) 的TextField (可自定义),类似微博#话题#、@用户,(给TextField加TextSpan)的更多相关文章
- css002 创建样式和样式表
创建样式和样式表 一个样式表包含多个样式 样式表的种类 1.内部样式表,存放在<head></head>之间.如: <head> <style> ( ...
- CSS3初学篇章_5(背景样式/列表样式/过渡动画)
背景样式 1.背景颜色语法:background-color : transparent | color body { background-color:#CCCCCC;} 2.渐变色彩语法:back ...
- cdr创建样式与样式集的方法
样式是一组定义对象属性的格式化属性,如轮廓或填充.例如,要定义轮廓样式,您可以指定轮廓宽度.颜色和线条类型等属性.要定义字符样式,您可以指定字体类型.字体样式和大小.文本颜色和背景色.字符位置.大写等 ...
- JavaScript获取非行间样式/定义样式
html节点的样式分为以下几种 (1)浏览器默认样式 (2)引用样式(引用外部css文件的样式.style标签内定义的样式) 引用外部css样式:<link rel="styleshe ...
- WPF 样式(定义样式、引用样式、样式作用域、Trigger触发器)
1.定义 资源字典 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta ...
- Bootstrap-全局CSS样式-图片样式
Bootstrap第二部分:全局CSS样式-图片样式.img-rounded 圆角图片.img-circle 圆形图片.img-thumbnail 缩略图片.img-responsive响应 ...
- css样式表--样式表分类
样式表分类 1.内联式.写在body里.控制精确,可重复性差. <body> <div style="color:#90F">更好发挥的返回结果还 < ...
- 用JS改变页面中b标签的样式啊 样式的等
用JS改变页面中b标签的样式啊 样式的等 ,实际上是在标签内加上样式 ,用媒体查询的话 ,不能生效 <!DOCTYPE html> <html lang="en&qu ...
- amazeui学习笔记--css(基本样式)--样式统一Normalize
amazeui学习笔记--css(基本样式)--样式统一Normalize 一.总结 1.统一浏览器默认样式: Amaze UI 也使用了 normalize.css,就是让不同浏览器显示相同的样式 ...
随机推荐
- RROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2
RROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2 ...
- Readings
1984 ([英] 乔治·奥威尔) 这书看完我觉得这根本就是一本恐怖小说,当里面的内容正在和将要发生的时候你就不会觉得里面的描述有点搞笑了.不过看到后面有译者的补充内容说和其他国家的朋友讨论的时候, ...
- hexo-next-travis-ci 构建自动化部署博客
构建效果如上面视频所示,如果浏览器不支持请戳一下链接: 自动化部署构建效果 .只要将编辑的 .md 文件推送到 github 上,博客网站就可以更新这篇文章. 其实差不多半年前也构建过一次,由于安装 ...
- HBase源码系列之HFile
本文讨论0.98版本的hbase里v2版本.其实对于HFile能有一个大体的较深入理解是在我去查看"到底是不是一条记录不能垮block"的时候突然意识到的. 首先说一个对HFile ...
- PHP实现读取一个1G的文件大小
需求如下: 现有一个1G左右的日志文件,大约有500多万行, 用php返回最后几行的内容. 1. 直接采用file函数来操作 or file_get_content() 肯定报内存溢出注: 由于 fi ...
- 用java实现的微信公众号爬虫
Published: 2016-11-23 In Spider. tags: Spider 版权声明:本文为博主原创文章,未经博主允许不得转载. 思路: 直接从chuansong.me爬取,由于微信公 ...
- Dizcuz站点部署-包教会
Dizcuz站点部署-包教会-有需要请联系小编! 小编微信号:wvqusrtg
- Mysql5.7.25安装步骤
安装步骤 在官网下载mysql-5.7.25-winx64.zip压缩包到本地,解压到非中文目录. 列如(D:\Program Files\mysql-5.7.25-winx64). 在环境变量中添加 ...
- Python安装3 —— Python3.8和2.7共存
本文内容皆为作者原创,如需转载,请注明出处:https://www.cnblogs.com/xuexianqi/p/12400896.html 一:Python解释器为什么要2个版本? 众所周知,Py ...
- js笔记系列之--时间及时间戳
js入门系列之 时间及时间戳 时间及时间戳 时间及时间戳是js里面很常见的一个概念,在我们写前端页面的时候,经常会遇到需要获取当前时间的情况,所以,了解js中的时间概念非常重要.而时间戳是指格林威治时 ...