TextField
其實就是前端程式碼的input
,輸入框元件。
基本的使用其實看api就已經可以日常使用了,官方的api解釋還是很清楚的。(翻譯軟體還挺給力)?
場景1:在較小的父級空間時
這種情況需要注意,不能給TextField
加一些花式操作(包括邊框,前後置icon等)。
如果加了這些,會導致輸入框的文字無法垂直居中,不管你加任何居中屬性都無法正常工作。
並且這種場景,你需要加上一個特殊屬性isDense
,作用是在較小空間時,使元件正常渲染(包括文字垂直居中)。
TextField(
decoration: InputDecoration(
isDense: true,
)
)
複製程式碼
這種情況,如果需要邊框、圓角等樣式,合理的做法應該是,實現一個帶樣式的Container
,作為TextField
的父級,並且要加上合適的padding
,因為Container
的圓角無法遮住input(即使使用overflow元件也無法達到你的期望)。
場景2:自定義輸入中文字的樣式
使用過這個TextField
的大兄嘚一定知道,預設的Editing Text
的樣式是黑色文字,無底色,黑色下劃線。
顯而易見,在日常APP的使用中,這種樣式很痛。誰叫我是處女座呢。
先來看下原本的樣式。
再看看微信的輸入樣式。 不多說,我就是喜歡有底色的。搞它。我剛開始準備修改這個樣式的時候,把我的腦袋整的是天翻地覆,因為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,
)
複製程式碼
看下效果:
舒服了~~~
總結
會持續補充~~~