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,就是让不同浏览器显示相同的样式 ...
随机推荐
- codeforces #332 div 2 D. Spongebob and Squares
http://codeforces.com/contest/599/problem/D 题意:给出总的方格数x,问有多少种不同尺寸的矩形满足题意,输出方案数和长宽(3,5和5,3算两种) 思路:比赛的 ...
- Python野生库
https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
- 添砖加瓦:Linux /proc目录简介
Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构.改变内核设置的机制.proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文件系统的方式为访问系 ...
- View 属性
关于 View 设置属性的方式: JavaxmlstyledefStyleAttrdefStyleResTheme 关于 defStyleRes 的使用,和在 xml 中声明 style=" ...
- Codeforces Round #620 (Div. 2)
Codeforces Round #620 (Div. 2) A. Two Rabbits 题意 两只兔子相向而跳,一只一次跳距离a,另一只一次跳距离b,每次同时跳,问是否可能到同一位置 题解 每次跳 ...
- js中~~和^=分别代表什么,用处是什么?
先看个栗子: ~~false === 0 ~~true === 1 ~~undefined === 0 ~~!undefined === 1 ~~null === 0 ~~!null === 1 ~~ ...
- Python线性优化基础讲解~
目前,各组织正在利用数据科学和机器学习来解决各种业务问题.为了创造一个真正的业务影响,如何弥合数据科学管道和业务决策管道之间的差距显得尤为重要. 数据科学管道的结果往往是数据中的预测.模式和洞察(通常 ...
- Educational Codeforces Round 83 (Rated for Div. 2)A--C
题意:给出一个边数为n的等边多边形,问是否可以变成m的等边多边形.条件是同一个中心,共用原顶点. 解析:直接n%m==0即可,这样就是平分了.签到题没得说了. #include<iostream ...
- Mac 下 Docker 运行较慢的原因分析及个人见解
在mac 使用 docker 的时候,我总感觉程序在 docker 下运行速度很慢,接下来我一一分析我遇到的问题,希望大家能进行合理的讨论和建议. 问题: valet 下打开 laravel 首页耗时 ...
- Java集合01——List 的几个实现类,了解一下?
从本文起,我们将开始分享 Java 集合方面的知识,关注公众号「Java面典」了解更多 Java 知识点. List 是继承于 Collection 的接口,其实现类有 ArrayList,Linke ...