老孟導讀:你們好,這是【Flutter實戰】系列文章的第二篇,這一篇講解文本組件,文本組件包括文本展現組件(Text和RichText)和文本輸入組件(TextField),基礎用法和五個案例助你快速掌握。javascript
Text
Text是顯示文本的組件,最經常使用的組件,沒有之一。基本用法以下:css
Text('老孟')
注意:Text組件必定要包裹在Scaffold組件下,不然效果以下:前端
文本的樣式在style
中設置,類型爲TextStyle
,TextStyle
中包含不少文本樣式屬性,下面介紹一些經常使用的。java
設置文本大小和顏色:android
Text('老孟',style: TextStyle(color: Colors.red,fontSize: 20),),
上面黑色的字體爲沒有設置的效果,做爲對比。ios
設置字體粗細:api
Text('老孟',style: TextStyle(fontWeight: FontWeight.bold))
w100
至w900
,FontWeight.bold是w700
。
Text('老孟',style: TextStyle(fontStyle: FontStyle.italic,))
設置自定義的字體:bash
首先下載字體庫(好比中華字體庫)微信
將字體文件拷貝的項目中,通常目錄是:assets/fonts/,assets和fonts都須要手動建立,此目錄不是必須的,而是約定俗成,資源通常都放在assets目錄下。app
配置
pubspec.yaml
:
fonts: family: maobi fonts: asset: assets/fonts/maobi.ttf
maobi:是本身對當前字體的命名,有意義便可。
asset:字體文件的目錄。
使用:
Text('老孟', style: TextStyle(fontFamily: 'maobi',)),
Container( height: 100, width: 200, color: Colors.blue.withOpacity(.4), child: Text('老孟', textAlign: TextAlign.center),),
textAlign
只是控制水平方向的對齊方式,值說明以下:
left:左對齊
right:右對齊
center:居中
justify:兩端對齊,此屬性中文存在bug(Flutter版本:1.17.3)也能夠在官方issue中關注此問題
start:前端對齊,和
TextDirection
屬性有關,若是設置TextDirection.ltr
,則左對齊,設置TextDirection.rtl
則右對齊。end:末端對齊,和
TextDirection
屬性有關,若是設置TextDirection.ltr
,則右對齊,設置TextDirection.rtl
則左對齊。
設置文本自動換行:
Container( height: 100, width: 200, color: Colors.blue.withOpacity(.4), child: Text('老孟,專一分享Flutter技術和應用實戰',softWrap: true,),)
Container( height: 100, width: 200, color: Colors.blue.withOpacity(.4), child: Text('老孟,專一分享Flutter技術和應用實戰',overflow: TextOverflow.ellipsis,),)
溢出的處理方式:
clip:直接裁剪。
fade:愈來愈透明。
ellipsis:省略號結尾。
visible:依然顯示,此時將會溢出父組件。
設置全局字體樣式:
在MaterialApp
的theme
中設置以下
MaterialApp( title: 'Flutter Demo', theme: ThemeData( ... textTheme: TextTheme( bodyText2: TextStyle(color: Colors.red,fontSize: 24), ) ), home: Scaffold( body: TextDemo(), ),)
Text('老孟'),
Text('老孟',style: TextStyle(color: Colors.blue,fontSize: 20),),
RichText
RichText的屬性和Text基本同樣,使用以下:
RichText( text: TextSpan( style: DefaultTextStyle.of(context).style, children: <InlineSpan>[ TextSpan(text: '老孟', style: TextStyle(color: Colors.red)), TextSpan(text: ','), TextSpan(text: '專一分享Flutter技術和應用實戰'), ]),)
TextField
TextField是文本輸入組件,即輸入框,經常使用組件之一。基本用法:
TextField()
decoration
是TextField組件的裝飾(外觀)參數,類型是InputDecoration。
icon
顯示在輸入框的前面,用法以下:
TextField( decoration: InputDecoration( icon: Icon(Icons.person), ),)
當輸入框是空並且沒有焦點時,labelText顯示在輸入框上邊,當獲取焦點或者不爲空時labelText往上移動一點,labelStyle
參數表示文本樣式,具體參考TextStyle
, 用法以下:
TextField( decoration: InputDecoration( labelText: '姓名:', labelStyle: TextStyle(color:Colors.red) ),)
hasFloatingPlaceholder
參數控制當輸入框獲取焦點或者不爲空時是否還顯示labelText
,默認爲true,顯示。
helperText
顯示在輸入框的左下部,用於提示用戶,helperStyle
參數表示文本樣式,具體參考TextStyle
用法以下:
TextField( decoration: InputDecoration( helperText: '用戶名長度爲6-10個字母', helperStyle: TextStyle(color: Colors.blue), helperMaxLines: 1 ),)
hintText
是當輸入框爲空時的提示,不爲空時不在顯示,用法以下:
TextField( decoration: InputDecoration( hintText: '請輸入用戶名', hintStyle: TextStyle(color: Colors.grey), hintMaxLines: 1 ),)
errorText
顯示在輸入框的左下部,默認字體爲紅色,用法以下:
TextField( decoration: InputDecoration( errorText: '用戶名輸入錯誤', errorStyle: TextStyle(fontSize: 12), errorMaxLines: 1, errorBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.red)), ),)
prefix
系列的組件是輸入框前面的部分,用法以下:
TextField( decoration: InputDecoration( prefixIcon: Icon(Icons.person) ),)
注意prefix和icon的區別,icon是在輸入框邊框的外部,而prefix在裏面。
suffix和prefix相反,suffix在輸入框的尾部,用法以下:
TextField( decoration: InputDecoration( suffixIcon: Icon(Icons.person) ),)
counter
組件統計輸入框文字的個數,counter僅僅是展現效果,不具有自動統計字數的功能, 自動統計字數代碼以下:
var _textFieldValue = '';TextField( onChanged: (value){ setState(() { _textFieldValue = value; }); }, decoration: InputDecoration( counterText: '${_textFieldValue.length}/32' ),)
filled
爲true時,輸入框將會被fillColor
填充,仿QQ登陸輸入框代碼以下:
Container( height: 60, width: 250, child: TextField( decoration: InputDecoration( fillColor: Color(0x30cccccc), filled: true, enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0x00FF0000)), borderRadius: BorderRadius.all(Radius.circular(100))), hintText: 'QQ號/手機號/郵箱', focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0x00000000)), borderRadius: BorderRadius.all(Radius.circular(100))), ), ),)
controller
是輸入框文本編輯的控制器,能夠獲取TextField的內容、設置TextField的內容,下面將輸入的英文變爲大寫:
TextEditingController _controller;
@overridevoid initState() { super.initState(); _controller = TextEditingController() ..addListener(() { //獲取輸入框的內容,變爲大寫 _controller.text = _controller.text.toUpperCase();
});}
@overrideWidget build(BuildContext context) { return TextField( controller: _controller, );}
@overridedispose() { super.dispose(); _controller.dispose();}
有時輸入框後面帶有「清除」功能,須要controller來實現。若是須要2個TextField的內容進行同步,只須要給2個TextField設置同一個controller便可實現。
keyboardType
參數控制軟鍵盤的類型,說明以下:
text:通用鍵盤。
multiline:當TextField爲多行時(maxLines設置大於1),右下角的爲「換行」 按鍵。
number:數字鍵盤。
phone:手機鍵盤,比數字鍵盤多"*"和 "#"。
datetime:在ios上和text同樣,在android上出現數字鍵盤、":"和 "-"。
emailAddress:郵箱鍵盤,有"@" 和 "."按鍵。
url:url鍵盤,有"/" 和 "."按鍵。
visiblePassword:既有字幕又有數字的鍵盤。
textInputAction
參數控制軟鍵盤右下角的按鍵,說明以下:
none:android上顯示返回鍵,ios不支持。
unspecified:讓操做系統本身決定哪一個合適,通常狀況下,android顯示「完成」或者「返回」。
done:android顯示錶明「完成」的按鈕,ios顯示「Done」(中文:完成)。
go:android顯示錶達用戶去向目的地的圖標,好比向右的箭頭,ios顯示「Go」(中文:前往)。
search:android顯示錶達搜索的按鈕,ios顯示"Search"(中文:搜索)。
send:android顯示錶達發送意思的按鈕,好比「紙飛機」按鈕,ios顯示"Send"(中文:發送)。
next:android顯示錶達「前進」的按鈕,好比「向右的箭頭」,ios顯示"Next"(中文:下一項)。
previous:android顯示錶達「後退」的按鈕,好比「向左的箭頭」,ios不支持。
continueAction:android 不支持,ios僅在ios9.0+顯示"Continue"(中文:繼續)。
join:Android和ios顯示"Join"(中文:加入)。
route:android 不支持,ios顯示"Route"(中文:路線)。
emergencyCall:android 不支持,ios顯示"Emergency Call"(中文:緊急電話)。
newline:android顯示錶達「換行」的按鈕,ios顯示」換行「。
你們可能發現了,Android上顯示的按鈕大部分是不肯定的,好比next
有的顯示向右的箭頭,有的顯示前進,這是由於各大廠商對Android ROM定製引起的。
textCapitalization
參數是配置鍵盤是大寫仍是小寫,僅支持鍵盤模式爲text
,其餘模式下忽略此配置,說明以下:
words:每個單詞的首字母大寫。
sentences:每一句話的首字母大寫。
characters:每一個字母都大寫
none:都小寫
這裏僅僅是控制軟鍵盤是大寫模式仍是小寫模式,你也能夠切換大小寫,系統並不會改變輸入框內的內容。
textAlignVertical
表示垂直方向的對齊方式,textDirection
表示文本方向,用法以下:
TextField( textAlignVertical: TextAlignVertical.center, textDirection: TextDirection.rtl,)
toolbarOptions
表示長按時彈出的菜單,有copy
、cut
、paste
、selectAll
,用法以下:
TextField( toolbarOptions: ToolbarOptions( copy: true, cut: true, paste: true, selectAll: true ),)
cursor
表示光標,用法以下:
TextField( showCursor: true, cursorWidth: 3, cursorRadius: Radius.circular(10), cursorColor: Colors.red,)
obscureText
屬性設置true便可,用法以下:
TextField( obscureText: true,)
inputFormatters
能夠限制用戶輸入的內容,好比只想讓用戶輸入字符,設置以下:
TextField( inputFormatters: [ WhitelistingTextInputFormatter(RegExp("[a-zA-Z]")), ],)
這時用戶是沒法輸入數字的。
onChanged
是當內容發生變化時回調,onSubmitted
是點擊回車或者點擊軟鍵盤上的完成回調,onTap
點擊輸入框時回調,用法以下:
TextField( onChanged: (value){ print('onChanged:$value'); }, onEditingComplete: (){ print('onEditingComplete'); }, onTap: (){ print('onTap'); },)
buildCounter
,建議使用此方法,用法以下:
TextField( maxLength: 100, buildCounter: ( BuildContext context, { int currentLength, int maxLength, bool isFocused, { return Text( '$currentLength/$maxLength', ); },)
FocusScope.of(context).requestFocus(_focusNode);
_focusNode
爲TextField的focusNode:
_focusNode = FocusNode();
TextField( focusNode: _focusNode, ...)
_focusNode.unfocus();
過渡顏色的文字
Builder( builder: (BuildContext context) { RenderBox box = context.findRenderObject(); final Shader linearGradient = LinearGradient( colors: <Color>[Colors.purple, Colors.blue], ).createShader( 0.0, box?.size?.width, box?.size?.height));
return Text( '老孟,專一分享Flutter技術和應用實戰', style: new TextStyle( fontSize: 18.0, fontWeight: FontWeight.bold, foreground: Paint()..shader = linearGradient), ); },)
Builder
組件是爲了計算當前Text組件大小,生成LinearGradient。
帶先後置標籤的文本
RichText( text: TextSpan( style: DefaultTextStyle.of(context).style, children: <InlineSpan>[ WidgetSpan( child: Container( margin: EdgeInsets.only(right: 10), padding: EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(20)), color: Colors.blue), child: Text( '判斷題', style: TextStyle(color: Colors.white), ), )), '泡沫滅火器可用於帶電滅火'), :
]),)
「服務協議」
一般在登陸頁面的底部會出現登陸即表明贊成並閱讀 《服務協議》,其中《服務協議》爲藍色且可點擊:
Text.rich( TextSpan( text: '登陸即表明贊成並閱讀', style: TextStyle(fontSize: 11, color: Color(0xFF999999)), children: [ TextSpan( text: '《服務協議》', style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold), recognizer: TapGestureRecognizer() () { = print('onTap'); }, ), ]),)
登陸密碼輸入框
TextField( decoration: InputDecoration( fillColor: Color(0x30cccccc), filled: true, enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0x00FF0000)), borderRadius: BorderRadius.all(Radius.circular(100))), hintText: '輸入密碼', focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Color(0x00000000)), borderRadius: BorderRadius.all(Radius.circular(100))),
), textAlign: TextAlign.center, obscureText: true, onChanged: (value) {
},)
評論回覆
Text.rich( TextSpan( text: '回覆', style: TextStyle(fontSize: 11, color: Color(0xFF999999)), children: [ TextSpan( text: '@老孟:', style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold), recognizer: TapGestureRecognizer() () { = print('onTap'); }, ), TextSpan( text: '你好,想知道Flutter發展前景如何?', ), ]),)
![](http://static.javashuo.com/static/loading.gif)
![qrcode_for_gh_eac93591a531_258.jpg](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
本文分享自微信公衆號 - 老孟Flutter(lao_meng_qd)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。