Flutter實戰(zhàn) 文本及樣式

2021-03-06 17:38 更新

#3.3.1 Text

Text用于顯示簡單樣式文本,它包含一些控制文本顯示樣式的一些屬性,一個簡單的例子如下:

Text("Hello world",
  textAlign: TextAlign.left,
);


Text("Hello world! I'm Jack. "*4,
  maxLines: 1,
  overflow: TextOverflow.ellipsis,
);


Text("Hello world",
  textScaleFactor: 1.5,
);

運行效果如圖3-5所示:

image-20180829103242552

  • textAlign:文本的對齊方式;可以選擇左對齊、右對齊還是居中。注意,對齊的參考系是Text widget 本身。本例中雖然是指定了居中對齊,但因為 Text 文本內(nèi)容寬度不足一行,Text 的寬度和文本內(nèi)容長度相等,那么這時指定對齊方式是沒有意義的,只有 Text 寬度大于文本內(nèi)容長度時指定此屬性才有意義。下面我們指定一個較長的字符串:

  Text("Hello world "*6,  //字符串重復六次
    textAlign: TextAlign.center,
  );

運行效果如圖3-6所示:

字符串內(nèi)容超過一行,Text 寬度等于屏幕寬度,第二行文本便會居中顯示。

  • maxLinesoverflow:指定文本顯示的最大行數(shù),默認情況下,文本是自動折行的,如果指定此參數(shù),則文本最多不會超過指定的行。如果有多余的文本,可以通過overflow來指定截斷方式,默認是直接截斷,本例中指定的截斷方式TextOverflow.ellipsis,它會將多余文本截斷后以省略符“...”表示;TextOverflow 的其它截斷方式請參考 SDK 文檔。
  • textScaleFactor:代表文本相對于當前字體大小的縮放因子,相對于去設(shè)置文本的樣式style屬性的fontSize,它是調(diào)整字體大小的一個快捷方式。該屬性的默認值可以通過MediaQueryData.textScaleFactor獲得,如果沒有MediaQuery,那么會默認值將為1.0。

#3.3.2 TextStyle

TextStyle用于指定文本顯示的樣式如顏色、字體、粗細、背景等。我們看一個示例:

Text("Hello world",
  style: TextStyle(
    color: Colors.blue,
    fontSize: 18.0,
    height: 1.2,  
    fontFamily: "Courier",
    background: new Paint()..color=Colors.yellow,
    decoration:TextDecoration.underline,
    decorationStyle: TextDecorationStyle.dashed
  ),
);

效果如圖3-7所示:

此示例只展示了 TextStyle 的部分屬性,它還有一些其它屬性,屬性名基本都是自解釋的,在此不再贅述,讀者可以查閱 SDK 文檔。值得注意的是:

  • height:該屬性用于指定行高,但它并不是一個絕對值,而是一個因子,具體的行高等于fontSize*height。
  • fontFamily :由于不同平臺默認支持的字體集不同,所以在手動指定字體時一定要先在不同平臺測試一下。
  • fontSize:該屬性和 Text 的textScaleFactor都用于控制字體大小。但是有兩個主要區(qū)別:
    • fontSize可以精確指定字體大小,而textScaleFactor只能通過縮放比例來控制。
    • textScaleFactor主要是用于系統(tǒng)字體大小設(shè)置改變時對 Flutter 應(yīng)用字體進行全局調(diào)整,而fontSize通常用于單個文本,字體大小不會跟隨系統(tǒng)字體大小變化。

#3.3.3 TextSpan

在上面的例子中,Text 的所有文本內(nèi)容只能按同一種樣式,如果我們需要對一個 Text 內(nèi)容的不同部分按照不同的樣式顯示,這時就可以使用TextSpan,它代表文本的一個“片段”。我們看看 TextSpan 的定義:

const TextSpan({
  TextStyle style, 
  Sting text,
  List<TextSpan> children,
  GestureRecognizer recognizer,
});

其中styletext屬性代表該文本片段的樣式和內(nèi)容。 children是一個TextSpan的數(shù)組,也就是說TextSpan可以包括其他TextSpan。而recognizer用于對該文本片段上用于手勢進行識別處理。下面我們看一個效果(圖3-8),然后用TextSpan實現(xiàn)它。

3-8

源碼:

Text.rich(TextSpan(
    children: [
     TextSpan(
       text: "Home: "
     ),
     TextSpan(
       text: "https://flutterchina.club",
       style: TextStyle(
         color: Colors.blue
       ),  
       recognizer: _tapRecognizer
     ),
    ]
))

  • 上面代碼中,我們通過 TextSpan 實現(xiàn)了一個基礎(chǔ)文本片段和一個鏈接片段,然后通過Text.rich 方法將TextSpan 添加到Text中,之所以可以這樣做,是因為 Text 其實就是 RichText 的一個包裝,而 RichText 是可以顯示多種樣式(富文本)的 widget。
  • _tapRecognizer,它是點擊鏈接后的一個處理器(代碼已省略),關(guān)于手勢識別的更多內(nèi)容我們將在后面單獨介紹。

#3.3.4 DefaultTextStyle

在 Widget 樹中,文本的樣式默認是可以被繼承的(子類文本類組件未指定具體樣式時可以使用 Widget 樹中父級設(shè)置的默認樣式),因此,如果在 Widget 樹的某一個節(jié)點處設(shè)置一個默認的文本樣式,那么該節(jié)點的子樹中所有文本都會默認使用這個樣式,而DefaultTextStyle正是用于設(shè)置默認文本樣式的。下面我們看一個例子:

DefaultTextStyle(
  //1.設(shè)置文本默認樣式  
  style: TextStyle(
    color:Colors.red,
    fontSize: 20.0,
  ),
  textAlign: TextAlign.start,
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      Text("hello world"),
      Text("I am Jack"),
      Text("I am Jack",
        style: TextStyle(
          inherit: false, //2.不繼承默認樣式
          color: Colors.grey
        ),
      ),
    ],
  ),
);

上面代碼中,我們首先設(shè)置了一個默認的文本樣式,即字體為20像素(邏輯像素)、顏色為紅色。然后通過DefaultTextStyle 設(shè)置給了子樹 Column 節(jié)點處,這樣一來 Column 的所有子孫 Text 默認都會繼承該樣式,除非 Text 顯示指定不繼承樣式,如代碼中注釋2。示例運行效果如圖3-9:

3-9

#3.3.5 字體

可以在 Flutter 應(yīng)用程序中使用不同的字體。例如,我們可能會使用設(shè)計人員創(chuàng)建的自定義字體,或者其它第三方的字體,如Google Fonts (opens new window)中的字體。本節(jié)將介紹如何為Flutter應(yīng)用配置字體,并在渲染文本時使用它們。

在Flutter中使用字體分兩步完成。首先在pubspec.yaml中聲明它們,以確保它們會打包到應(yīng)用程序中。然后通過TextStyle (opens new window)屬性使用字體。

#在asset中聲明

要將字體文件打包到應(yīng)用中,和使用其它資源一樣,要先在pubspec.yaml中聲明它。然后將字體文件復制到在pubspec.yaml中指定的位置。如:

flutter:
  fonts:
    - family: Raleway
      fonts:
        - asset: assets/fonts/Raleway-Regular.ttf
        - asset: assets/fonts/Raleway-Medium.ttf
          weight: 500
        - asset: assets/fonts/Raleway-SemiBold.ttf
          weight: 600
    - family: AbrilFatface
      fonts:
        - asset: assets/fonts/abrilfatface/AbrilFatface-Regular.ttf

#使用字體

// 聲明文本樣式
const textStyle = const TextStyle(
  fontFamily: 'Raleway',
);


// 使用文本樣式
var buttonText = const Text(
  "Use the font for this text",
  style: textStyle,
);

#Package中的字體

要使用 Package 中定義的字體,必須提供package參數(shù)。例如,假設(shè)上面的字體聲明位于my_package包中。然后創(chuàng)建 TextStyle 的過程如下:

const textStyle = const TextStyle(
  fontFamily: 'Raleway',
  package: 'my_package', //指定包名
);

如果在 package 包內(nèi)部使用它自己定義的字體,也應(yīng)該在創(chuàng)建文本樣式時指定package參數(shù),如上例所示。

一個包也可以只提供字體文件而不需要在 pubspec.yaml 中聲明。 這些文件應(yīng)該存放在包的lib/文件夾中。字體文件不會自動綁定到應(yīng)用程序中,應(yīng)用程序可以在聲明字體時有選擇地使用這些字體。假設(shè)一個名為 my_package 的包中有一個字體文件:

lib/fonts/Raleway-Medium.ttf

然后,應(yīng)用程序可以聲明一個字體,如下面的示例所示:

 flutter:
   fonts:
     - family: Raleway
       fonts:
         - asset: assets/fonts/Raleway-Regular.ttf
         - asset: packages/my_package/fonts/Raleway-Medium.ttf
           weight: 500

lib/是隱含的,所以它不應(yīng)該包含在 asset 路徑中。

在這種情況下,由于應(yīng)用程序本地定義了字體,所以在創(chuàng)建 TextStyle 時可以不指定package參數(shù):

const textStyle = const TextStyle(
  fontFamily: 'Raleway',
);
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號