Flutter折騰記一(TextField的樣式之痛)

chavesgu發表於2019-12-10

TextField其實就是前端程式碼的input,輸入框元件。

基本的使用其實看api就已經可以日常使用了,官方的api解釋還是很清楚的。(翻譯軟體還挺給力)?

場景1:在較小的父級空間時

這種情況需要注意,不能給TextField加一些花式操作(包括邊框,前後置icon等)。

如果加了這些,會導致輸入框的文字無法垂直居中,不管你加任何居中屬性都無法正常工作。 並且這種場景,你需要加上一個特殊屬性isDense,作用是在較小空間時,使元件正常渲染(包括文字垂直居中)。

TextField(
    decoration: InputDecoration(
      isDense: true,
    )
)
複製程式碼

這種情況,如果需要邊框、圓角等樣式,合理的做法應該是,實現一個帶樣式的Container,作為TextField的父級,並且要加上合適的padding,因為Container的圓角無法遮住input(即使使用overflow元件也無法達到你的期望)。

場景2:自定義輸入中文字的樣式

使用過這個TextField的大兄嘚一定知道,預設的Editing Text的樣式是黑色文字,無底色,黑色下劃線

顯而易見,在日常APP的使用中,這種樣式很痛。誰叫我是處女座呢。

先來看下原本的樣式。

https://cdn.chavesgu.com/flutter/textField-1.jpg
再看看微信的輸入樣式。
https://cdn.chavesgu.com/flutter/textField-2.jpg
不多說,我就是喜歡有底色的。搞它。

我剛開始準備修改這個樣式的時候,把我的腦袋整的是天翻地覆,因為TextField沒有任何一個屬性樣式可以修改這個。

本來就要準備在“某群”找“收費解決問題”的大佬(錢蛆)搞定這個問題,但是囊中羞澀的我保持了理智,繼續鑽研這個元件,終於讓我發現了控制這個樣式的東西!

TextEditingController

這是flutter用來控制輸入框的文字輸入、賦值、監聽、focus/blur的控制器,我特麼哪能想到這玩意還控制樣式??無意中看到他的英文帶有Editing,才認真看了這東西。

我在這個TextEditingController的原始碼中發現了這麼一段:

  /// Builds [TextSpan] from current editing value.
  ///
  /// By default makes text in composing range appear as underlined.
  /// Descendants can override this method to customize appearance of text.
  TextSpan buildTextSpan({TextStyle style , bool withComposing}) {
複製程式碼

大概的中文意思就是,當前正在輸入的文字的build方式(方法),預設表現是underline,後代可以重寫這個方法自定義文字的表現。(我四級沒過的還能看懂這段英文,太棒了)

我就嘗試寫一個MyTextEditingController繼承TextEditingController,然後重寫buildTextSpan方法。

import 'package:flutter/material.dart';

class MyTextEditingController extends TextEditingController {

  MyTextEditingController({
    String text,
    this.editingTextStyle = const TextStyle(backgroundColor: Colors.black12),
  })
    : super(text: text);

// 增加editingTextStyle引數,讓他隨時可變自定義,預設灰色---↑↑↑↑↑↑↑↑↑↑↑↑↑
  final TextStyle editingTextStyle;

  @override
  TextSpan buildTextSpan({TextStyle style , bool withComposing}) {
    if (!value.composing.isValid || !withComposing) {
      return TextSpan(style: style, text: text);
    }
    // -----此處就是正在輸入的樣式
    final TextStyle composingStyle = style.merge(
      const TextStyle(decoration: TextDecoration.underline),
    );
    // -----↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓--------
    final TextStyle composingStyle = style.merge(editingTextStyle);
    // ---------------------------
    return TextSpan(
      style: style,
      children: <TextSpan>[
        TextSpan(text: value.composing.textBefore(value.text)),
        TextSpan(
          style: composingStyle,
          text: value.composing.textInside(value.text),
        ),
        TextSpan(text: value.composing.textAfter(value.text)),
      ]);
  }
}
複製程式碼

寫完新的MyTextEditingController,就可以開始使用了。

final _inputController = MyTextEditingController();

TextField(
    controller: _inputController,
)
複製程式碼

看下效果:

https://cdn.chavesgu.com/flutter/textField-3.png

舒服了~~~

總結

會持續補充~~~

相關文章