天天看點

Flutter主題Theme的詳解(建立&使用&擷取)Flutter主題Theme的詳解(建立&使用&擷取)

Flutter主題Theme的詳解(建立&使用&擷取)

為了在整個應用中共享顔色和字型樣式,我們可以使用主題。定義主題有兩種方式:全局主題或使用Theme來定義應用程式局部的顔色和字型樣式。事實上,全局主題隻是由應用程式根MaterialApp建立的Theme。

定義一個主題後,我們可以在我們自己的Widgets中使用它。另外,Flutter提供的Material Widgets将使用我們的主題為AppBars、Buttons、Checkboxes等設定背景顔色和字型樣式。

建立主題

可以通過配置ThemeData類輕松更改應用程式的主題。

ThemeData

ThemeData是Material Design Widget庫的主題資料,Material庫的Widget需要遵守相應的設計規範,而這些規範可自定義(部分),是以我們可以通過ThemeData來自定義應用主題,我們可以通過Theme.of方法來擷取目前的ThemeData。

ThemeData部分資料:

ThemeData({
  Brightness brightness, //深色還是淺色
  MaterialColor primarySwatch, //主題顔色樣本,見下面介紹
  Color primaryColor, //主色,決定導航欄顔色
  Color accentColor, //次級色,決定大多數Widget的顔色,如進度條、開關等。
  Color cardColor, //卡片顔色
  Color dividerColor, //分割線顔色
  ButtonThemeData buttonTheme, //按鈕主題
  Color cursorColor, //輸入框光标顔色
  Color dialogBackgroundColor,//對話框背景顔色
  String fontFamily, //文字字型
  TextTheme textTheme,// 字型主題,包括标題、body等文字樣式
  IconThemeData iconTheme, // Icon的預設樣式
  TargetPlatform platform, //指定平台,應用特定平台控件風格
  ...
})
           

設定整個應用的主題

例如,為了在整個應用程式中共享包含顔色和字型樣式的主題,我們可以提供ThemeData給MaterialApp的構造函數。

示例:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'budaye',
      theme: new ThemeData(
        brightness: Brightness.dark,
        primaryColor: Colors.white,
        accentColor: Colors.cyan[600],
      ),
      home: new RandomWords(),
    );
  }}
           

局部主題

如果我們想在應用程式的一部分中覆寫應用程式的全局的主題,我們可以将要覆寫得部分封裝在一個Theme Widget中。

有兩種方法可以解決這個問題:建立特有的ThemeData或擴充父主題。

1. 建立特有的 ThemeData

如果我們不想繼承任何應用程式的顔色或字型樣式,我們可以通過new ThemeData()建立一個執行個體并将其傳遞給Theme Widget。

new Theme(
  // Create a unique theme with "new ThemeData"
  data: new ThemeData(
    accentColor: Colors.yellow,
  ),
  child: new FloatingActionButton(
    onPressed: () {},
    child: new Icon(Icons.add),
  ),
);
           
2. 擴充父主題

擴充父主題時無需覆寫所有的主題屬性,我們可以通過使用copyWith方法來實作。

new Theme(
  // Find and Extend the parent theme using "copyWith". Please see the next 
  // section for more info on `Theme.of`.
  data: Theme.of(context).copyWith(accentColor: Colors.yellow),
  child: new FloatingActionButton(
    onPressed: null,
    child: new Icon(Icons.add),
  ),
);
           

使用主題

1. 應用主題的使用

應用主題的使用上面已經介紹了,這裡不做重複介紹了。

2. 局部主題的使用

在想要應用局部主題的widget外部,包裹Theme來實作:

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // backgroundColor: Colors.green, //設定标題欄的背景顔色
        title: new Title(
          child: new Text(
            '這是一個标題',
          ),
          color: Colors.white,
        ),
      ),
      body: new Theme(
        // Create a unique theme with "new ThemeData"
        data: new ThemeData(
          // accentColor: Colors.yellow,
        ),
        child: new FloatingActionButton(
          onPressed: () {},
          child: new Icon(Icons.add),
        ),
      ),
    );
  }
}

           

3. 主題的擷取

現在我們已經定義了一個主題,我們可以在Widget的build方法中通過Theme.of(context)函數使用它。

Theme.of(context)将查找Widget樹并傳回樹中最近的Theme。如果我們的Widget之上有一個單獨的Theme定義,則傳回該值。如果不是,則傳回App主題。

new Container(
  color: Theme.of(context).accentColor,
  child: new Text(
    'Text with a background color',
    style: Theme.of(context).textTheme.title,
  ),
);