【Flutter實戰】文本組件及五大案例


老孟導讀:你們好,這是【Flutter實戰】系列文章的第二篇,這一篇講解文本件,文本組件包括文本展現組件(Text和RichText)和文本輸入組件(TextField),基礎用法和五個案例助你快速掌握。javascript


Text

Text是顯示文本的組件,最經常使用的組件,沒有之一。基本用法以下:css

Text('老孟')

注意:Text組件必定要包裹在Scaffold組件下,不然效果以下:前端

文本的樣式在style中設置,類型爲TextStyleTextStyle中包含不少文本樣式屬性,下面介紹一些經常使用的。java


設置文本大小和顏色:android

Text('老孟',style: TextStyle(color: Colors.red,fontSize: 20),),

上面黑色的字體爲沒有設置的效果,做爲對比。ios


設置字體粗細:api

Text('老孟',style: TextStyle(fontWeight: FontWeight.bold))

字體粗細共有9個級別,爲w100w900FontWeight.boldw700

設置斜體:
Text('老孟',style: TextStyle(fontStyle: FontStyle.italic,))

設置自定義的字體:bash

  1. 首先下載字體庫(好比中華字體庫)微信

  2. 將字體文件拷貝的項目中,通常目錄是:assets/fonts/,assets和fonts都須要手動建立,此目錄不是必須的,而是約定俗成,資源通常都放在assets目錄下。app

  3. 配置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:依然顯示,此時將會溢出父組件。


設置全局字體樣式:

MaterialApptheme中設置以下

MaterialApp( title: 'Flutter Demo', theme: ThemeData( ... textTheme: TextTheme( bodyText2: TextStyle(color: Colors.red,fontSize: 24), ) ), home: Scaffold( body: TextDemo(), ),)
Text組件默認爲紅色,
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 表示長按時彈出的菜單,有copycutpasteselectAll,用法以下:
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( Rect.fromLTWH(0.0, 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), ), )), TextSpan(text: '泡沫滅火器可用於帶電滅火'),
]),)


「服務協議」

一般在登陸頁面的底部會出現登陸即表明贊成並閱讀 《服務協議》,其中《服務協議》爲藍色且可點擊:

Text.rich( TextSpan( text: '登陸即表明贊成並閱讀', style: TextStyle(fontSize: 11, color: Color(0xFF999999)), children: [ TextSpan( text: '《服務協議》', style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold), recognizer: TapGestureRecognizer() ..onTap = () { 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() ..onTap = () { print('onTap'); }, ), TextSpan( text: '你好,想知道Flutter發展前景如何?', ), ]),)


你可能還喜歡


關注「老孟Flutter」
讓你天天進步一點點

戳我,贈送330+Flutter控件詳細說明。

本文分享自微信公衆號 - 老孟Flutter(lao_meng_qd)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索