1. 程式人生 > >Flutter佈局錦囊---手機號登入頁

Flutter佈局錦囊---手機號登入頁

設計給的效果如下:

UI佈局圖

拿到設計後,先把整體拆分成幾個部分:

  1. “運營位”,使用自定義的旋轉木馬滑塊元件實現可以滾動的運營位。
  2. “登入表單”,使用自定義的登入表單元件實現手機號、驗證碼登入的表單。
  3. “使用者協議”,使用自定義的使用者協議元件實現使用者協議的宣告文字。

然後就可以開始進行編碼了。

第1步:繪製元件樹

手機號登入頁的元件樹

第2步:實現“運營位”

先把需要引用的自定義元件一次引入,carousel_with_indicator.dartlogin_form.dartuser_agreement.dart檔案,它們分別對應《Flutter佈局錦囊—輪播圖片與滑塊》

《Flutter佈局錦囊—蠟筆畫的表單》《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),
                  ],
                ),
              ),
            ),

第5步:還原效果

手機號登入頁的還原效果