前言
- Flutter 作為Google出品的一個 新興的跨平台移動用戶端UI開發架構 ,正在被越來越多的開發者群組織使用,包括阿裡的鹹魚、騰訊的微信等。
- 今天,我主要講解Flutter中文本元件方面的Widget,包括Text、RichText、TextField,希望你們會喜歡。
1. Text
- 應用場景:普通文本
- 屬性設定
Text(this.data, {
Key key,
this.style, // 設定文字樣式,具體見下面的說明
this.textAlign, // 文字對齊方式:(center居中,left左對齊,right右對齊,justfy兩端對齊)
this.textDirection, // 文本方向(ltr從左至右,rtl從右至左)
this.locale,
this.softWrap,// 是否自動換行(true自動換行,false單行顯示,超出螢幕部分預設截斷處理)
this.overflow, // 文字超出螢幕之後的處理方式(clip裁剪,fade漸隐,ellipsis省略号)
this.textScaleFactor, // 字型顯示倍率
this.maxLines, // maxLines 文字顯示最大行數
this.semanticsLabel,
}
const TextStyle({
this.inherit = true,
this.color,//文本樣式
this.fontSize,//字型大小
this.fontWeight,//繪制文本時的字型粗細
this.fontStyle,//字型變體
this.letterSpacing,//水準字母之間的空間間隔(邏輯像素為機關),可以負值
this.wordSpacing,//單詞之間添加的空間間隔(邏輯像素為機關),可以負值
this.textBaseline,//對齊文本的水準線
this.height,//文本行與行的高度,作為字型代銷的倍數
this.locale,//用于選擇區域定字形的語言環境
this.foreground,//文本的前景色,不能與color共同設定
this.background,//文本背景色
this.shadows,//Flutter Decoration背景設定(邊框,圓角,陰影,漸變等)
this.decoration,//繪制文本裝飾,添加上下劃線,删除線
this.decorationColor,//文本裝飾的顔色
this.decorationStyle,//文本裝飾的樣式,控制畫虛線,點,波浪線
this.debugLabel,
String fontFamily,//使用字型的名稱
String package,
})
- 執行個體示範
import 'package:flutter/material.dart'; // Material UI元件庫
void main() => runApp(MyApp());
// 無狀态控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口傳回的元件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //标題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 傳回一個Widget對象,用來定義目前應用打開的時候,所顯示的界面
);
}
}
// 傳回的Widget對象
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//設定appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體
body: new Center(
//在螢幕中央顯示一個文本
child: Text(
"carson ho Demo", // 顯示的内容
style: TextStyle( // 通過Style設定樣式,可根據上述樣式進行設定,此處僅作最簡單屬性設定
color: Colors.blue, //顔色
fontSize: 14, // 字型大小
fontWeight: FontWeight.bold), // 字型加粗
//文本背景顔色
),
),
);
}
}
- 特别注意:在 Flutter 中,并不是每個 Widget 都有點選事件,如上述說的文本Text 就沒有
- 解決方案:需用一個 GestureDetector 元件包住Text 元件 & 實作onTap() 事件
2. RichText
- 應用場景:一段文本存在多種樣式(大小、顔色等),類似Android的SpannableString
- 屬性設定
RichText({
Key key,
@required this.text, // 差別于Text,RichText的text屬性不是String類型,而是TextSpan,TextSpan用于指定文本片段的風格及手勢互動,具體如下描述
this.textAlign = TextAlign.start, // 文字對齊方式
this.textDirection, // 文本方向(ltr從左至右,rtl從右至左)
this.softWrap = true, // 是否自動換行(true自動換行,false單行顯示,超出螢幕部分預設截斷處理)
this.overflow = TextOverflow.clip, // 文字超出螢幕之後的處理方式(clip裁剪,fade漸隐,ellipsis省略号)
this.textScaleFactor = 1.0,// 字型顯示倍率
this.maxLines,// maxLines 文字顯示最大行數
})
// TextSpan是一個樹狀結構,children表示子節點。每個節點代表一個文本片段,祖先節點的style對所有子孫節點起作用。
// 注:當祖先節點的style中指定的值與自身節點的style發生沖突時,自身style中指定的值會覆寫掉前者
TextSpan({
this.style, // 指定風格,類似text中的style
this.text, // String,指定文本片段
this.children, // List<TextSpan>類型,代表子節點,每個節點代表一個文本片段
this.recognizer, // GestureRecognizer類型,指定該文本片段的手勢互動,GestureRecognizer是一個抽象類(有許多子類,如點選監聽器TapGestureRecognizer
})
- 代碼示範
import 'package:flutter/gestures.dart';
/**
* 導入庫
**/
import 'package:flutter/material.dart'; // Material UI元件庫
void main() => runApp(MyApp());
// 無狀态控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口傳回的元件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //标題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 傳回一個Widget對象,用來定義目前應用打開的時候,所顯示的界面
);
}
}
// 傳回的Widget對象
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//設定appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體
body: new Center(
//在螢幕中央顯示一個文本
child: RichText( // 根節點的設定會影響下面兩個子節點
text: TextSpan(style: TextStyle(fontSize: 20), children: [
// 每個子節點的設定會覆寫根節點的設定
TextSpan(text: "Android ", style: TextStyle(
color: Colors.blue, fontSize: 60,),
recognizer: TapGestureRecognizer() // 設定點選事件,此處以點選監聽器TapGestureRecognizer()為例
..onTap = () {
print("點選了Android");
},),
TextSpan(text: "iOS ",
style: TextStyle(color: Colors.red, fontSize: 50,)),
TextSpan(text: "Web", style: TextStyle(
color: Colors.green, fontSize: 40,)),
]),
textDirection: TextDirection.ltr,
)
),
);
}
}
- 效果展示
特别注意
Text控件中,有一個靜态屬性rich,可達到類似RichText的效果
Text.rich(
this.textSpan, {
Key key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
})
深入Text的源碼build()方法可知,Text控件實際上是對RichText控件的封裝
@override
Widget build(BuildContext context) {
...
Widget result = RichText(
...
text: TextSpan(
...
text: data,
children: textSpan != null ? <TextSpan>[textSpan] : null,
),
);
...
return result;
}
3. TextField
- 應用場景:文本輸入框,類似于Android中的EditText
- 屬性說明
const TextField({
Key key,
this.controller, //編輯框的控制器,跟文本框的互動一般都通過該屬性完成,如果不建立的話預設會自動建立
this.focusNode, //用于管理焦點
this.decoration = const InputDecoration(), //輸入框的裝飾器,用來修改外觀
TextInputType keyboardType, //設定輸入類型,不同的輸入類型鍵盤不一樣
this.textInputAction, //用于控制鍵盤動作(一般位于右下角,預設是完成)
this.textCapitalization = TextCapitalization.none,
this.style, //輸入的文本樣式
this.textAlign = TextAlign.start, //輸入的文本位置
this.textDirection, //輸入的文字排列方向,一般不會修改這個屬性
this.autofocus = false, //是否自動擷取焦點
this.obscureText = false, //是否隐藏輸入的文字,一般用在密碼輸入框中
this.autocorrect = true, //是否自動校驗
this.maxLines = 1, //最大行
this.maxLength, //能輸入的最大字元個數
this.maxLengthEnforced = true, //配合maxLength一起使用,在達到最大長度時是否阻止輸入
this.onChanged, //輸入文本發生變化時的回調
this.onEditingComplete, //點選鍵盤完成按鈕時觸發的回調,該回調沒有參數,(){}
this.onSubmitted, //同樣是點選鍵盤完成按鈕時觸發的回調,該回調有參數,參數即為目前輸入框中的值。(String){}
this.inputFormatters, //對輸入文本的校驗
this.enabled, //輸入框是否可用
this.cursorWidth = 2.0, //光标的寬度
this.cursorRadius, //光标的圓角
this.cursorColor, //光标的顔色
this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.down,
this.enableInteractiveSelection,
this.onTap, //點選輸入框時的回調(){}
this.buildCounter,
})
// 此處主要介紹TextField.decoration屬性
InputDecoration({
this.icon, //位于裝飾器外部和輸入框前面的圖檔
this.labelText, //用于描述輸入框,例如這個輸入框是用來輸入使用者名還是密碼的,當輸入框擷取焦點時預設會浮動到上方,
this.labelStyle, // 控制labelText的樣式,接收一個TextStyle類型的值
this.helperText, //輔助文本,位于輸入框下方,如果errorText不為空的話,則helperText不會顯示
this.helperStyle, //helperText的樣式
this.hintText, //提示文本,位于輸入框内部
this.hintStyle, //hintText的樣式
this.hintMaxLines, //提示資訊最大行數
this.errorText, //錯誤資訊提示
this.errorStyle, //errorText的樣式
this.errorMaxLines, //errorText最大行數
this.hasFloatingPlaceholder = true, //labelText是否浮動,預設為true,修改為false則labelText在輸入框擷取焦點時不會浮動且不顯示
this.isDense, //改變輸入框是否為密集型,預設為false,修改為true時,圖示及間距會變小
this.contentPadding, //内間距
this.prefixIcon, //位于輸入框内部起始位置的圖示。
this.prefix, //預先填充的Widget,跟prefixText同時隻能出現一個
this.prefixText, //預填充的文本,例如手機号前面預先加上區号等
this.prefixStyle, //prefixText的樣式
this.suffixIcon, //位于輸入框後面的圖檔,例如一般輸入框後面會有個眼睛,控制輸入内容是否明文
this.suffix, //位于輸入框尾部的控件,同樣的不能和suffixText同時使用
this.suffixText,//位于尾部的填充文字
this.suffixStyle, //suffixText的樣式
this.counter,//位于輸入框右下方的小控件,不能和counterText同時使用
this.counterText,//位于右下方顯示的文本,常用于顯示輸入的字元數量
this.counterStyle, //counterText的樣式
this.filled, //如果為true,則輸入使用fillColor指定的顔色填充
this.fillColor, //相當于輸入框的背景顔色
this.errorBorder, //errorText不為空,輸入框沒有焦點時要顯示的邊框
this.focusedBorder, //輸入框有焦點時的邊框,如果errorText不為空的話,該屬性無效
this.focusedErrorBorder, //errorText不為空時,輸入框有焦點時的邊框
this.disabledBorder, //輸入框禁用時顯示的邊框,如果errorText不為空的話,該屬性無效
this.enabledBorder, //輸入框可用時顯示的邊框,如果errorText不為空的話,該屬性無效
this.border, //正常情況下的border
this.enabled = true, //輸入框是否可用
this.semanticCounterText,
this.alignLabelWithHint,
})
- 代碼示範
/**
* 導入庫
**/
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; // Material UI元件庫
void main() => runApp(MyApp());
// 無狀态控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口傳回的元件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //标題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 傳回一個Widget對象,用來定義目前應用打開的時候,所顯示的界面
);
}
}
// 傳回的Widget對象
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//設定appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體
body: new TextField(
decoration: InputDecoration(
icon: Icon(Icons.person), // 輸入框前加入圖檔
hintText: "hintText", // 提示輸入資訊
labelText: "labelText", // 描述輸入框,當輸入框擷取焦點時預設會浮動到上方
labelStyle: TextStyle( // labelText的樣式
color: Colors.red,
fontSize: 20,
),
hasFloatingPlaceholder: false,// labelText是否浮動,預設為true,修改為false則labelText在輸入框擷取焦點時不會浮動且不顯示
helperText: "helperText", // 輸入框下方提示
helperStyle: TextStyle( // 輸入框下方提示樣式
color: Colors.green,//綠色
fontSize: 20,//字型變大
),
errorText: "errorText", // 錯誤提示,若該屬性不為null,那麼labelText失效
prefixIcon: Icon(Icons.perm_identity), // 輸入框前端預填充圖檔
prefixText: "prefixText",// 預填充文字
suffixIcon: Icon(Icons.remove_red_eye,), // 輸入框後端預填充圖檔
suffixText: "suffixText", // 輸入框後端預填充文字
counterText: "counterText", // 輸入框右下方文字
filled: true, // 顔色填充
fillColor: Colors.grey,
// 邊界設定 - 外邊界
enabledBorder: OutlineInputBorder(
/*邊角*/
borderRadius: BorderRadius.all(
Radius.circular(30), //邊角為30
),
borderSide: BorderSide(
color: Colors.amber, //邊線顔色為黃色
width: 2, //邊線寬度為2
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.green, //邊框顔色為綠色
width: 5, //寬度為5
)),
// 邊界設定 - 底邊界
errorBorder: UnderlineInputBorder(
/*邊角*/
borderRadius: BorderRadius.all(
Radius.circular(30), //邊角為30
),
borderSide: BorderSide(
color: Colors.amber, //邊線顔色為黃色
width: 2, //邊線寬度為2
),
),
focusedErrorBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.green, //邊框顔色為綠色
width: 5, //寬度為5
)),
),
keyboardType: TextInputType.phone, // 隻能輸入手機号
textInputAction: TextInputAction.search, // 鍵盤動作的按鈕變為搜尋
onEditingComplete: (){ // 點選鍵盤的動作按鈕時的回調(無參)
print("點選了鍵盤上的動作按鈕");
},
onSubmitted: (val){// 點選鍵盤的動作按鈕時的回調(參數為輸入框的值)
print("點選了鍵盤上的動作按鈕,目前輸入框的值為:${val}");
},
onChanged: (val) { // 輸入文本發生變化時的回調,參數即為輸入框中的值
print(val);
},
inputFormatters: [ // 輸入限制
WhitelistingTextInputFormatter(RegExp("[a-z]")),// 白名單校驗,隻能輸入規定的字元,此處隻能輸入a-z
BlacklistingTextInputFormatter(RegExp("[a-z]")), // 黑名單校驗,除了規定的字元其他的都可以輸入,此處即除了a-z不能輸入其他都能輸入
LengthLimitingTextInputFormatter(5) // 限制輸入的長度
],
)
);
}
-
示意圖
[圖檔上傳失敗...(image-35d107-1595235302539)]
下面,額外展示一個屬性設定:TextField controller,用于對輸入框進進行指派 & 取值操作
/**
* 導入庫
**/
import 'package:flutter/material.dart';// Material UI元件庫
void main() => runApp(MyApp());
// 無狀态控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口傳回的元件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //标題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 傳回一個Widget對象,用來定義目前應用打開的時候,所顯示的界面
);
}
}
// 有狀态控件顯示
class MyHomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage>{
// 建立TextEditingController對象
TextEditingController _userEtController = TextEditingController();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
//設定appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體
body: Container(
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
TextField(
controller: _userEtController,
),
RaisedButton(
child: Text("指派"),
onPressed: () {
setState(() {
_userEtController.text = "carson.ho";// 通過_userEtController.text将設定的值設定到編輯框内
});
},
),
Text(_userEtController.text),// 通過_userEtController.text擷取到設定的值
],
),
),
);
}
}
作者:Carson_Ho
連結:https://www.jianshu.com/p/1dadad711dc7