前言
-
Flutter 作為Google出品的一個新興的跨平臺移動客戶端UI開發(fā)框架齿尽,正在被越來越多的開發(fā)者和組織使用,包括阿里的咸魚灯节、騰訊的微信等循头。
今天,我主要講解Flutter中文本組件方面的Widget显晶,包括Text贷岸、RichText、TextField磷雇,希望你們會喜歡偿警。
1. Text
- 應(yīng)用場景:普通文本
- 屬性設(shè)置
Text(this.data, {
Key key,
this.style, // 設(shè)置文字樣式,具體見下面的說明
this.textAlign, // 文字對齊方式:(center居中唯笙,left左對齊螟蒸,right右對齊,justfy兩端對齊)
this.textDirection, // 文本方向(ltr從左至右崩掘,rtl從右至左)
this.locale,
this.softWrap,// 是否自動換行(true自動換行七嫌,false單行顯示,超出屏幕部分默認(rèn)截斷處理)
this.overflow, // 文字超出屏幕之后的處理方式(clip裁剪苞慢,fade漸隱诵原,ellipsis省略號)
this.textScaleFactor, // 字體顯示倍率
this.maxLines, // maxLines 文字顯示最大行數(shù)
this.semanticsLabel,
}
const TextStyle({
this.inherit = true,
this.color,//文本樣式
this.fontSize,//字體大小
this.fontWeight,//繪制文本時的字體粗細(xì)
this.fontStyle,//字體變體
this.letterSpacing,//水平字母之間的空間間隔(邏輯像素為單位),可以負(fù)值
this.wordSpacing,//單詞之間添加的空間間隔(邏輯像素為單位),可以負(fù)值
this.textBaseline,//對齊文本的水平線
this.height,//文本行與行的高度,作為字體代銷的倍數(shù)
this.locale,//用于選擇區(qū)域定字形的語言環(huán)境
this.foreground,//文本的前景色,不能與color共同設(shè)置
this.background,//文本背景色
this.shadows,//Flutter Decoration背景設(shè)定(邊框挽放,圓角绍赛,陰影,漸變等)
this.decoration,//繪制文本裝飾,添加上下劃線辑畦,刪除線
this.decorationColor,//文本裝飾的顏色
this.decorationStyle,//文本裝飾的樣式吗蚌,控制畫虛線,點(diǎn)纯出,波浪線
this.debugLabel,
String fontFamily,//使用字體的名稱
String package,
})
- 實例演示
import 'package:flutter/material.dart'; // Material UI組件庫
void main() => runApp(MyApp());
// 無狀態(tài)控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口返回的組件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //標(biāo)題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 返回一個Widget對象蚯妇,用來定義當(dāng)前應(yīng)用打開的時候,所顯示的界面
);
}
}
// 返回的Widget對象
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//設(shè)置appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體
body: new Center(
//在屏幕中央顯示一個文本
child: Text(
"carson ho Demo", // 顯示的內(nèi)容
style: TextStyle( // 通過Style設(shè)置樣式暂筝,可根據(jù)上述樣式進(jìn)行設(shè)置箩言,此處僅作最簡單屬性設(shè)置
color: Colors.blue, //顏色
fontSize: 14, // 字體大小
fontWeight: FontWeight.bold), // 字體加粗
//文本背景顏色
),
),
);
}
}
- 特別注意:在 Flutter 中,并不是每個 Widget 都有點(diǎn)擊事件焕襟,如上述說的文本Text 就沒有
- 解決方案:需用一個 GestureDetector 組件包住Text 組件 & 實現(xiàn)onTap() 事件
2. RichText
- 應(yīng)用場景:一段文本存在多種樣式(大小分扎、顏色等),類似Android的SpannableString
- 屬性設(shè)置
RichText({
Key key,
@required this.text, // 區(qū)別于Text胧洒,RichText的text屬性不是String類型畏吓,而是TextSpan,TextSpan用于指定文本片段的風(fēng)格及手勢交互卫漫,具體如下描述
this.textAlign = TextAlign.start, // 文字對齊方式
this.textDirection, // 文本方向(ltr從左至右菲饼,rtl從右至左)
this.softWrap = true, // 是否自動換行(true自動換行,false單行顯示列赎,超出屏幕部分默認(rèn)截斷處理)
this.overflow = TextOverflow.clip, // 文字超出屏幕之后的處理方式(clip裁剪宏悦,fade漸隱,ellipsis省略號)
this.textScaleFactor = 1.0,// 字體顯示倍率
this.maxLines,// maxLines 文字顯示最大行數(shù)
})
// TextSpan是一個樹狀結(jié)構(gòu)包吝,children表示子節(jié)點(diǎn)饼煞。每個節(jié)點(diǎn)代表一個文本片段,祖先節(jié)點(diǎn)的style對所有子孫節(jié)點(diǎn)起作用诗越。
// 注:當(dāng)祖先節(jié)點(diǎn)的style中指定的值與自身節(jié)點(diǎn)的style發(fā)生沖突時砖瞧,自身style中指定的值會覆蓋掉前者
TextSpan({
this.style, // 指定風(fēng)格,類似text中的style
this.text, // String嚷狞,指定文本片段
this.children, // List<TextSpan>類型块促,代表子節(jié)點(diǎn),每個節(jié)點(diǎn)代表一個文本片段
this.recognizer, // GestureRecognizer類型床未,指定該文本片段的手勢交互竭翠,GestureRecognizer是一個抽象類(有許多子類,如點(diǎn)擊監(jiān)聽器TapGestureRecognizer
})
- 代碼演示
import 'package:flutter/gestures.dart';
/**
* 導(dǎo)入庫
**/
import 'package:flutter/material.dart'; // Material UI組件庫
void main() => runApp(MyApp());
// 無狀態(tài)控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口返回的組件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //標(biāo)題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 返回一個Widget對象薇搁,用來定義當(dāng)前應(yīng)用打開的時候斋扰,所顯示的界面
);
}
}
// 返回的Widget對象
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//設(shè)置appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體
body: new Center(
//在屏幕中央顯示一個文本
child: RichText( // 根節(jié)點(diǎn)的設(shè)置會影響下面兩個子節(jié)點(diǎn)
text: TextSpan(style: TextStyle(fontSize: 20), children: [
// 每個子節(jié)點(diǎn)的設(shè)置會覆蓋根節(jié)點(diǎn)的設(shè)置
TextSpan(text: "Android ", style: TextStyle(
color: Colors.blue, fontSize: 60,),
recognizer: TapGestureRecognizer() // 設(shè)置點(diǎn)擊事件,此處以點(diǎn)擊監(jiān)聽器TapGestureRecognizer()為例
..onTap = () {
print("點(diǎn)擊了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控件中啃洋,有一個靜態(tài)屬性rich传货,可達(dá)到類似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
- 應(yīng)用場景:文本輸入框裂允,類似于Android中的EditText
- 屬性說明
const TextField({
Key key,
this.controller, //編輯框的控制器坊夫,跟文本框的交互一般都通過該屬性完成,如果不創(chuàng)建的話默認(rèn)會自動創(chuàng)建
this.focusNode, //用于管理焦點(diǎn)
this.decoration = const InputDecoration(), //輸入框的裝飾器显设,用來修改外觀
TextInputType keyboardType, //設(shè)置輸入類型废封,不同的輸入類型鍵盤不一樣
this.textInputAction, //用于控制鍵盤動作(一般位于右下角,默認(rèn)是完成)
this.textCapitalization = TextCapitalization.none,
this.style, //輸入的文本樣式
this.textAlign = TextAlign.start, //輸入的文本位置
this.textDirection, //輸入的文字排列方向十饥,一般不會修改這個屬性
this.autofocus = false, //是否自動獲取焦點(diǎn)
this.obscureText = false, //是否隱藏輸入的文字窟勃,一般用在密碼輸入框中
this.autocorrect = true, //是否自動校驗
this.maxLines = 1, //最大行
this.maxLength, //能輸入的最大字符個數(shù)
this.maxLengthEnforced = true, //配合maxLength一起使用,在達(dá)到最大長度時是否阻止輸入
this.onChanged, //輸入文本發(fā)生變化時的回調(diào)
this.onEditingComplete, //點(diǎn)擊鍵盤完成按鈕時觸發(fā)的回調(diào)逗堵,該回調(diào)沒有參數(shù)秉氧,(){}
this.onSubmitted, //同樣是點(diǎn)擊鍵盤完成按鈕時觸發(fā)的回調(diào),該回調(diào)有參數(shù)蜒秤,參數(shù)即為當(dāng)前輸入框中的值汁咏。(String){}
this.inputFormatters, //對輸入文本的校驗
this.enabled, //輸入框是否可用
this.cursorWidth = 2.0, //光標(biāo)的寬度
this.cursorRadius, //光標(biāo)的圓角
this.cursorColor, //光標(biāo)的顏色
this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.down,
this.enableInteractiveSelection,
this.onTap, //點(diǎn)擊輸入框時的回調(diào)(){}
this.buildCounter,
})
// 此處主要介紹TextField.decoration屬性
InputDecoration({
this.icon, //位于裝飾器外部和輸入框前面的圖片
this.labelText, //用于描述輸入框亚斋,例如這個輸入框是用來輸入用戶名還是密碼的,當(dāng)輸入框獲取焦點(diǎn)時默認(rèn)會浮動到上方攘滩,
this.labelStyle, // 控制labelText的樣式,接收一個TextStyle類型的值
this.helperText, //輔助文本帅刊,位于輸入框下方,如果errorText不為空的話漂问,則helperText不會顯示
this.helperStyle, //helperText的樣式
this.hintText, //提示文本赖瞒,位于輸入框內(nèi)部
this.hintStyle, //hintText的樣式
this.hintMaxLines, //提示信息最大行數(shù)
this.errorText, //錯誤信息提示
this.errorStyle, //errorText的樣式
this.errorMaxLines, //errorText最大行數(shù)
this.hasFloatingPlaceholder = true, //labelText是否浮動,默認(rèn)為true蚤假,修改為false則labelText在輸入框獲取焦點(diǎn)時不會浮動且不顯示
this.isDense, //改變輸入框是否為密集型栏饮,默認(rèn)為false,修改為true時磷仰,圖標(biāo)及間距會變小
this.contentPadding, //內(nèi)間距
this.prefixIcon, //位于輸入框內(nèi)部起始位置的圖標(biāo)袍嬉。
this.prefix, //預(yù)先填充的Widget,跟prefixText同時只能出現(xiàn)一個
this.prefixText, //預(yù)填充的文本,例如手機(jī)號前面預(yù)先加上區(qū)號等
this.prefixStyle, //prefixText的樣式
this.suffixIcon, //位于輸入框后面的圖片,例如一般輸入框后面會有個眼睛芒划,控制輸入內(nèi)容是否明文
this.suffix, //位于輸入框尾部的控件冬竟,同樣的不能和suffixText同時使用
this.suffixText,//位于尾部的填充文字
this.suffixStyle, //suffixText的樣式
this.counter,//位于輸入框右下方的小控件,不能和counterText同時使用
this.counterText,//位于右下方顯示的文本民逼,常用于顯示輸入的字符數(shù)量
this.counterStyle, //counterText的樣式
this.filled, //如果為true泵殴,則輸入使用fillColor指定的顏色填充
this.fillColor, //相當(dāng)于輸入框的背景顏色
this.errorBorder, //errorText不為空,輸入框沒有焦點(diǎn)時要顯示的邊框
this.focusedBorder, //輸入框有焦點(diǎn)時的邊框,如果errorText不為空的話拼苍,該屬性無效
this.focusedErrorBorder, //errorText不為空時笑诅,輸入框有焦點(diǎn)時的邊框
this.disabledBorder, //輸入框禁用時顯示的邊框,如果errorText不為空的話疮鲫,該屬性無效
this.enabledBorder, //輸入框可用時顯示的邊框吆你,如果errorText不為空的話,該屬性無效
this.border, //正常情況下的border
this.enabled = true, //輸入框是否可用
this.semanticCounterText,
this.alignLabelWithHint,
})
- 代碼演示
/**
* 導(dǎo)入庫
**/
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; // Material UI組件庫
void main() => runApp(MyApp());
// 無狀態(tài)控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口返回的組件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //標(biāo)題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 返回一個Widget對象俊犯,用來定義當(dāng)前應(yīng)用打開的時候妇多,所顯示的界面
);
}
}
// 返回的Widget對象
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
//設(shè)置appbar
appBar: new AppBar(
title: new Text('Flutter Demo'),
),
//主體
body: new TextField(
decoration: InputDecoration(
icon: Icon(Icons.person), // 輸入框前加入圖片
hintText: "hintText", // 提示輸入信息
labelText: "labelText", // 描述輸入框,當(dāng)輸入框獲取焦點(diǎn)時默認(rèn)會浮動到上方
labelStyle: TextStyle( // labelText的樣式
color: Colors.red,
fontSize: 20,
),
hasFloatingPlaceholder: false,// labelText是否浮動燕侠,默認(rèn)為true者祖,修改為false則labelText在輸入框獲取焦點(diǎn)時不會浮動且不顯示
helperText: "helperText", // 輸入框下方提示
helperStyle: TextStyle( // 輸入框下方提示樣式
color: Colors.green,//綠色
fontSize: 20,//字體變大
),
errorText: "errorText", // 錯誤提示,若該屬性不為null绢彤,那么labelText失效
prefixIcon: Icon(Icons.perm_identity), // 輸入框前端預(yù)填充圖片
prefixText: "prefixText",// 預(yù)填充文字
suffixIcon: Icon(Icons.remove_red_eye,), // 輸入框后端預(yù)填充圖片
suffixText: "suffixText", // 輸入框后端預(yù)填充文字
counterText: "counterText", // 輸入框右下方文字
filled: true, // 顏色填充
fillColor: Colors.grey,
// 邊界設(shè)置 - 外邊界
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
)),
// 邊界設(shè)置 - 底邊界
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, // 只能輸入手機(jī)號
textInputAction: TextInputAction.search, // 鍵盤動作的按鈕變?yōu)樗阉?
onEditingComplete: (){ // 點(diǎn)擊鍵盤的動作按鈕時的回調(diào)(無參)
print("點(diǎn)擊了鍵盤上的動作按鈕");
},
onSubmitted: (val){// 點(diǎn)擊鍵盤的動作按鈕時的回調(diào)(參數(shù)為輸入框的值)
print("點(diǎn)擊了鍵盤上的動作按鈕七问,當(dāng)前輸入框的值為:${val}");
},
onChanged: (val) { // 輸入文本發(fā)生變化時的回調(diào),參數(shù)即為輸入框中的值
print(val);
},
inputFormatters: [ // 輸入限制
WhitelistingTextInputFormatter(RegExp("[a-z]")),// 白名單校驗茫舶,只能輸入規(guī)定的字符械巡,此處只能輸入a-z
BlacklistingTextInputFormatter(RegExp("[a-z]")), // 黑名單校驗,除了規(guī)定的字符其他的都可以輸入,此處即除了a-z不能輸入其他都能輸入
LengthLimitingTextInputFormatter(5) // 限制輸入的長度
],
)
);
}
-
示意圖
下面讥耗,額外展示一個屬性設(shè)置:TextField controller有勾,用于對輸入框進(jìn)進(jìn)行賦值 & 取值操作
/**
* 導(dǎo)入庫
**/
import 'package:flutter/material.dart';// Material UI組件庫
void main() => runApp(MyApp());
// 無狀態(tài)控件顯示
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 主界面入口返回的組件 = MaterialApp
return MaterialApp(
title: 'Widget_Demo', //標(biāo)題
theme: ThemeData(primarySwatch: Colors.blue), //主題色
home: MyHomePage(), // 返回一個Widget對象,用來定義當(dāng)前應(yīng)用打開的時候葛账,所顯示的界面
);
}
}
// 有狀態(tài)控件顯示
class MyHomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage>{
// 創(chuàng)建TextEditingController對象
TextEditingController _userEtController = TextEditingController();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
//設(shè)置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將設(shè)置的值設(shè)置到編輯框內(nèi)
});
},
),
Text(_userEtController.text),// 通過_userEtController.text獲取到設(shè)置的值
],
),
),
);
}
}
4. 總結(jié)
- 本文主要講解了Flutter中完整頁面方面的Widget柠衅,包括Text、RichText籍琳、TextField
- 接下來推出的文章,我將繼續(xù)講解Flutter的相關(guān)知識贷祈,包括更多的Widget用法趋急、實例應(yīng)用等,感興趣的讀者可以繼續(xù)關(guān)注我的博客哦:Carson_Ho的Android博客
請點(diǎn)贊势誊!因為你們的贊同/鼓勵是我寫作的最大動力呜达!
相關(guān)文章閱讀
Android開發(fā):最全面、最易懂的Android屏幕適配解決方案
Android開發(fā):史上最全的Android消息推送解決方案
Android開發(fā):最全面粟耻、最易懂的Webview詳解
Android開發(fā):JSON簡介及最全面解析方法!
Android四大組件:Service服務(wù)史上最全面解析
Android四大組件:BroadcastReceiver史上最全面解析
歡迎關(guān)注Carson_Ho的簡書查近!
不定期分享關(guān)于安卓開發(fā)的干貨,追求短挤忙、平霜威、快,但卻不缺深度册烈。