Flutter 即學即用系列博客新篇章來了,UI 初窺,帶你探索神秘夢幻的 UI 世界 ...
前面三篇可以算是一個小小的里程碑。
主要是介紹了 Flutter 環境的搭建、如何創建 Flutter 項目以及如何在舊有 Android 項目引入 Flutter。
這一篇我們來學習下 Flutter 的 UI。
前言
說到 UI,我就簡單說下 Flutter 作為一門跨平臺語言具有的優勢之一,提高效率吧。
舉個例子:
假設現在要開發一個界面,Android 開發需要一天,iOS 開發也需要一天。那麼就是兩天。
如果你用 Flutter 開發,就只需要一天(因為 Android 和 iOS 都可以共用一套 Flutter 代碼)。這樣效率自然就提高了。
另外,假設後面產品發現界面有個位置需要調整,如果是 Android 或者 iOS 單獨開發,則兩個端都需要進行額外調整。
而 Flutter 就一套代碼而已,所以相較之下 Flutter 更易維護。
官網關於 UI 的介紹 User interface
這邊筆者按照自己的感受和認識進行說明。
讀者看完之後有了個基本的認識,後續不管是閱讀官方文檔還是使用搜索引擎搜索相關問題,相信會事半功倍。
記住一句話:
Flutter 裡面一切皆 Widget。
目錄
1. 基本配置
我們緊接之前文章,現在進入 MyApp/sub/my_flutter 位置。
打開 main.dart。如果提示下圖:
Dart support is not enabled for the project
我們點擊右邊第一個(Enabled Dart support)或者第二個(Open Dart settings)都是 OK 的。
如果點擊第二個,需要配置 dart 的目錄。
dart 的目錄在 flutter 的 bin 目錄下麵的 cache 目錄下麵。
舉個例子,筆者的 flutter bin 目錄(terminal 執行which flutter)為/Users/nesger/Desktop/nesger_folder/flutter/flutter/bin/,那麼 dart 目錄就在/Users/nesger/Desktop/nesger_folder/flutter/flutter/bin/cache/dart-sdk。
然後直接拷貝下麵代碼替換 main.dart 的代碼。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My Flutter'),
),
body: Center(),
)
);
}
}
實際編譯器可能會顯示如下圖,就是會有註釋顯示每個控制項。
這有好處也有壞處。好處就是你可以看到哪一塊是哪一個 Widget。壞處就是視覺干擾。
這個是自動產生的,不可刪除。
可以通過如下操作控制是否顯示:
Android Studio->Preferences->Editor->General->Appearance
2. main.dart 學習
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My Flutter'),
),
body: Center(),
)
);
}
}
執行 flutter run 運行後可以看到下圖:
對比上面代碼可看到頂部藍色區域是 AppBar 這個 Widget 來控制的。
你可以自行修改 Text 裡面的內容然後按 r 鍵通過熱重載看下效果。
我們可以看到,Flutter 裡面的 dart 代碼一個比較明顯的地方就是一個 Widget 套著一個 Widget,有點樹形的樣子。
比如這裡
我們嘗試把 AppBar 去掉,可以看到界面顯示就是一片純白的界面。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(),
)
);
}
}
那麼這裡的 MaterialApp Widget 是不是必需的呢?
其實 MaterialApp 說明這個界面是按照 Material Design 的風格。
我們看下如果去掉會怎樣?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(),
);
}
}
所以說 Scaffold 這個 Widget 不能直接返回,我們需要給它外面套一層 MaterialApp。
可以看下這個鏈接:https://github.com/nesger/FlutterNote/issues/4
我們返回之前的狀態,然後給他加一個 Hello World,看下怎樣?
我們知道,Flutter 一切皆 Widget,所以需要顯示 Hello World,就需要 Widget。
Widget 可以通過這個鏈接查看:https://flutter.io/docs/development/ui/widgets
可以看到 Text 這個 Widget
點擊進入
再點擊進入,可以看到介紹以及 Sample。
大家以後如果要看其他 Widget 也可以按照同樣的方式學習。
當然如果時間要求比較緊的話,大家學完博客可以直接在搜索引擎輸入關鍵字看下別人的 Sample,然後化用一下就沒問題啦。
我們點擊右邊複製,然後簡單修改如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Text(
'Hello World!',
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
);
}
}
可以看到我們將其放到 Center 這個 Widget 裡面,表示居中,同時作為它的一個 child。
大家可以試下去掉 Center 會怎樣,直接將 Text 作為 body,如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Text(
'Hello World!',
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
);
}
}
可以想象應該是不居中的。
到了這裡你應該可以發現,我們整個頁面其實是 body 對應的 Widget 來控制的。
上面我們的例子都是 MaterialApp,是不是一定只能這個 Widget 在最外層?
不是的,只是這裡 Scaffold 跟它配對而已,我們可以修改如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text(
'Hello, world!',
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
),
);
}
}
註意多了一行textDirection: TextDirection.ltr,沒有會報錯。
3. 以 Text 為例子初窺 Widget 寫法
我們點進去 Text 源碼看下,
對比一下上面我們的代碼:
Text(
'Hello, world!',
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold),
)
我們可以這樣認為,括弧裡面的是待傳入參數。其中沒有花括弧{}包裹的是必填項,有花括弧{}的是選填項。
有花括弧{}的在傳入參數時需要指定參數,格式為參數:值。不同參數之間逗號分隔。
所以我們可以猜測上面 Center 下麵的 child 應該是在花括弧裡面。所以才會有上面的寫法,我們跟進去源碼看看。
確實跟我們猜的一樣。而且由於參數的類型是 Widget,所以可以傳 Text 也是沒問題的。
所以到這裡你再回顧一下上面是不是就知道上面代碼的寫法了呢?
總結
由於 Flutter UI 內容比較多,講起來篇幅會比較大。
所以我們會拆分成幾篇文章進行講解。
回顧一下,本篇文章主要講解如下內容:
- dart sdk 配置和 dart 源代碼括弧後面編譯器提示的顯示和隱藏。
- 通過 main.dart 的修改初步熟悉 Flutter 界面的寫法。
- 通過 Text 說明如何在官方文檔上面查找控制項和對應 Sample。
- 通過一個具體的小控制項 Text 初窺 Flutter Widget 的寫法和使用方法。
小彩蛋
這個彩蛋是微信群里一個小伙伴說到的。這裡分享給大家。
簡單說就是設置 Android Studio 的背景圖。
先上圖
大家覺得哪種更加賞心悅目呢?
可以根據自己的喜好確定是否設置。
設置方法為
其中 Opacity 是不透明度。
0 表示完全透明,跟沒設置一樣。100 表示完全不透明。
一般預設即可。
背景圖公眾號回覆「ASBG」獲取。
更多閱讀:
Flutter 即學即用系列博客——01 環境搭建
Flutter 即學即用系列博客——02 一個純 Flutter Demo 說明
Flutter 即學即用系列博客——03 在舊有項目引入 Flutter