Flutter佈局錦囊---手機號登入頁
阿新 • • 發佈:2019-01-05
設計給的效果如下:
拿到設計後,先把整體拆分成幾個部分:
- “運營位”,使用自定義的旋轉木馬滑塊元件實現可以滾動的運營位。
- “登入表單”,使用自定義的登入表單元件實現手機號、驗證碼登入的表單。
- “使用者協議”,使用自定義的使用者協議元件實現使用者協議的宣告文字。
然後就可以開始進行編碼了。
第1步:繪製元件樹
第2步:實現“運營位”
先把需要引用的自定義元件一次引入,carousel_with_indicator.dart
、login_form.dart
和user_agreement.dart
檔案,它們分別對應《Flutter佈局錦囊—輪播圖片與滑塊》
import 'package:flutter/material.dart';
import 'widgets/carousel_with_indicator.dart';
import 'widgets/login_form.dart';
import 'widgets/user_agreement.dart';
/// 登入頁面元件。
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
實現“運營位”的UI很簡單,因為在《Flutter佈局錦囊—輪播圖片與滑塊》中,已經完成了具體的實現,你只需要呼叫CarouselWithIndicator
元件就可以了。
/// 與登入頁面元件關聯的狀態子類。
class _LoginPageState extends State<LoginPage> {
@override
Widget build(BuildContext context) {
// TODO: 第4步:實現“使用者協議”,實現“相對下方”佈局。
// 腳手架(`Scaffold`)元件,實現基本Material設計視覺佈局結構。
return Scaffold(
body: SafeArea(
child: ListView(
children: <Widget>[
CarouselWithIndicator(),
// TODO: 第3步:實現“登入表單”。
// TODO: 第4步:實現“使用者協議”。
],
),
),
);
}
}
第3步:實現“登入表單”
同上,實現“登入表單”也只需要呼叫LoginForm
元件即可,具體實現在《Flutter佈局錦囊—蠟筆畫的表單》中。
// TODO: 第3步:實現“登入表單”。
LoginForm(),
第4步:實現“使用者協議”
實現“使用者協議”的時候比較困難,因為你需要相對於螢幕下方來放置元件。筆者沒有在Flutter文件中找到能同時實現靈活佈局和相對螢幕下方佈局的方法,只能採取非常土的方法,先計算出螢幕上剩餘的空間。
// TODO: 第4步:實現“使用者協議”,實現“相對下方”佈局。
/// 螢幕下方的剩餘高度。
double screenHeight;
// 媒體查詢(`MediaQuery`)類,建立媒體查詢解析給定資料的子樹,返回媒體查詢資料(`MediaQueryData`)類。
// 媒體查詢資料(`MediaQueryData`)類的方向(`orientation`)屬性,媒體的方向,即裝置是處於橫向還是縱向模式。
if (MediaQuery.of(context).orientation == Orientation.portrait) {
// 媒體查詢資料(`MediaQueryData`)類的大小(`size`)屬性,邏輯畫素中的媒體大小,即螢幕的大小。
// 媒體查詢資料(`MediaQueryData`)類的填充(`padding`)屬性,應用程式可以呈現的顯示矩形每一側的物理畫素數。
// 填充(`padding`)屬性的頂部(`top`)值是狀態列高度,底部(`bottom`)值是系統操作欄高度。
screenHeight = MediaQuery.of(context).size.height - MediaQuery.of(context).padding.top -
MediaQuery.of(context).padding.bottom - 536;
} else {
// 橫屏時的高度,用於避免因為切換橫豎屏導致的異常顯示。
screenHeight = 82.0;
}
然後用大小框(SizedBox
)元件來佔據螢幕剩餘的空間,再通過垂直(Column
)元件的主軸對齊(mainAxisAlignment
)屬性把UserAgreement
元件佈局於螢幕下方。
// TODO: 第4步:實現“使用者協議”。
// 通過大小框(`SizedBox`)元件來利用螢幕剩餘的空間,實現從螢幕下方佈局。
SizedBox(
height: screenHeight,
child: Align(
alignment: Alignment.bottomCenter,
child: Column(
// 垂直(`Column`)元件的主軸對齊(`mainAxisAlignment`)屬性,如何將子元件放在主軸上。
mainAxisAlignment : MainAxisAlignment.end,
children: <Widget>[
UserAgreement(),
SizedBox(height: 20.0),
],
),
),
),