1. 程式人生 > >Flutter 實現不同樣式(有樣式) 的TextField (可自定義),類似微博#話題#、@使用者,(給TextField加TextSpan)

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程式碼為:

 1 import 'package:flutter/cupertino.dart';
 2 
 3 /// 範圍樣式,規定不同範圍不同樣式
 4 class RangeStyle extends Comparable<RangeStyle> {
 5   RangeStyle({@required this.range, this.style});
 6 
 7   /// 範圍
 8   final TextRange range;
 9 
10   /// 指定樣式
11   final TextStyle style;
12 
13   @override
14   int compareTo(RangeStyle other) {
15     return range.start.compareTo(other.range.start);
16   }
17 
18   @override
19   String toString() {
20     return 'RangeStyle(range:$range, style:$style)';
21   }
22 }

程式碼地址: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

&n