初略講解Flutter的文字及樣式

zane發表於2019-07-30

Text

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

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

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

Text("Hello world",
  textScaleFactor: 1.5,
);
複製程式碼

執行效果如下:

初略講解Flutter的文字及樣式

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

    Text("Hello World "*6,  //字串重複六次
      textAlign: TextAlign.center,
    );
    複製程式碼

    執行效果如下:

    初略講解Flutter的文字及樣式
    字串內容超過一行,Text寬度等於螢幕寬度,第二行文字便會居中顯示。

  • maxLinesoverflow:指定文字顯示的最大行數,預設情況下,文字是自動折行的,如果指定此引數,則文字最多不會超過指定的行。如果有多餘的文字,可以通過overflow來指定截斷方式,預設是直接截斷,本例中指定的截斷方式TextOverflow.ellipsis,它會將多餘文字截斷後以省略符“...”表示;TextOverflow的其它截斷方式請參考SDK文件。

  • textScaleFactor;代表文字相對於當前字型大小的縮放因子,相對於去設定文字的樣式style屬性的fontSize,它是調整字型大小的一個快捷方式。 該屬性的預設值可以通過MediaQueryData.textScaleFactor獲得,如果沒有MediaQuery,那麼預設值將為1.0。

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
  ),
);
複製程式碼

執行效果如下:

初略講解Flutter的文字及樣式

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

  • height:該屬性用於指定行高,但它並不是一個絕對值,而是一個因子,具體的行高等於fontSize*height
  • fontFamily:由於不同平臺預設支援的字型集不同,所以在手動指定字型時一定要先在不同平臺上進行測試。
  • fontSize:該屬性和TexttextScaleFactor都用於控制字型大小,但是有兩個主要區別:
    • fontSize:可以精確指定字型大小,而textScaleFactor只能通過縮放比例來控制。
    • textScaleFactor:主要是用於系統字型大小設定改變時對Flutter應用字型進行全域性調整,而fontSize通常用於單個文字,字型大小不會跟隨系統字型大小變化。

TextSpan

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

const TextSpan({
  TextStyle style, 
  Sting text,
  List<TextSpan> children,
  GestureRecognizer recognizer,
});
複製程式碼

其中styletext屬性代表該文字片段的樣式和內容。children是一個TextSpan的陣列,也就是說TextSpan可以包括其它TextSpan。而recognizer用於對該文字片段上用於手勢進行識別處理。下面我們看一個效果,然後用TextSpan實現它。

初略講解Flutter的文字及樣式

程式碼如下:

Text.rich(TextSpan(
    children: [
     TextSpan(
       text: "Home: "
     ),
     TextSpan(
       text: "https://juejin.im/user/5670f9c060b294bccfdf4325",
       style: TextStyle(
         color: Colors.blue
       ),  
       recognizer: _tapRecognizer
     ),
    ]
))
複製程式碼
  • 上面程式碼中,我們通過TextSpan實現了一個基礎文字片段和一個連結片段,然後通過Text.rich方法將TextSpan新增到Text中,之所以可以這樣做,是因為Text其實就是RichText的一個封裝,而RichText是可以顯示多種樣式(富文字)的Widget。
  • _tapRecognizer,它是點選連結後的一個處理器(程式碼已省略),關於手勢識別的更多內容我們將在後面單獨介紹。

DefaultTextStyle

在Widget樹中,文字的樣式預設是可以被繼承的,因此,如果在Widget樹的某一個節點處設定一個預設的文字樣式,那麼該節點的子樹中所有文字都會預設使用這個樣式,而DefaultTextStyle正是用於設定預設文字樣式的。下面我們看一個例子:

DefaultTextStyle(
  //1.設定文字預設樣式  
  style: TextStyle(
    color:Colors.red,
    fontSize: 20.0,
  ),
  textAlign: TextAlign.start,
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      Text("hello world"),
      Text("I am Zane"),
      Text("I am Zane",
        style: TextStyle(
          //2.不繼承預設樣式
          inherit: false, 
          color: Colors.grey
        ),
      ),
    ],
  ),
);
複製程式碼

上面程式碼中,我們首先設定了一個預設的文字樣式,即字型為20px(邏輯畫素)、顏色為紅色。然後通過DefaultTextStyle設定給了子樹Column節點處,這樣一來Column的所有子孫Text預設都會繼承該樣式,除非Text顯示指定不繼承樣式,如程式碼中inherit: false。示例執行效果如下:

初略講解Flutter的文字及樣式

使用字型

可以在Flutter應用程式中使用不同的字型。例如,我們可能會使用設計人員建立的自定義字型,或者其它第三方的字型,如Google Fonts中的字型。下面將介紹如何為Flutter應用配置字型,並渲染文字時使用它們。

在Flutter中使用字型分兩步完成:

  • 首先在pubspec.yaml中宣告它們,以確保它們會打包到應用程式中;
  • 然後通過TextStyle屬性使用字型。

在asset中宣告

要將字型檔案打包到應用中和使用其它資源一樣,要先在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引數。例如,假設上面的字型宣告位於my_package包中,那麼建立TextStyle的過程如下:

const textStyle = const TextStyle(
  fontFamily: 'Raleway',
  package: 'my_package', //指定包名
);
複製程式碼

如果在package包內部使用它自己定義的字型,也應該在建立文字樣式時指定package引數,如上例所示。

一個包也可以只提供字型檔案而不需要在pubspec.yaml中宣告,這些檔案應該存放在包的lib/資料夾中。字型檔案不會自動繫結到應用程式中,應用程式可以在宣告字型時有選擇的使用這些字型。

假設一個名為my_package的包中有一個字型檔案:

lib/fonts/Raleway-Medium.ttf
複製程式碼

然後,應用程式可以宣告一個字型,如下面的示例所示:

flutter:
   fonts:
     - family: Raleway
       fonts:
         - asset: assets/fonts/Raleway-Regular.ttf
         - asset: packages/my_package/fonts/Raleway-Medium.ttf
           weight: 500
複製程式碼

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

在這種情況下,由於應用程式本地定義了字型,所以在建立TextStyle時可以不指定package引數:

const textStyle = const TextStyle(
  fontFamily: 'Raleway',
);
複製程式碼

相關文章