Flutter佈局錦囊---有背景圖的頭像選擇

設計給的效果如下:

UI佈局圖

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

  1. “獲取相冊圖片”,Flutter團隊開發的圖片選擇器(image_picker)插件,從手機相冊中獲取圖片。
  2. “默認頭像圖片”,新用戶默認的頭像圖片,右下方通過一個小圖片提醒用戶可以點擊設置頭像。
  3. “圓形頭像圖片”,經過簡單裁剪後的圓形頭像圖片,上面覆蓋一層邊框背景圖片。

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

第1步:繪製組件樹

有背景圖的頭像選擇的組件樹

第2步:實現“獲取相冊圖片”

使用Flutter團隊開發的image_picker插件,你可以輕鬆的調用Android和iOS系統的相冊和相機,它會返回用戶所選擇的圖片文件路徑,這樣你就可以通過文件路徑去訪問用戶所選圖片。

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';

/// 自定義的上傳頭像組件。
class UploadAvatar extends StatefulWidget {
  @override
  _UploadAvatarState createState() => _UploadAvatarState();
}

/// 與自定義的上傳頭像組件關聯的狀態子類。
class _UploadAvatarState extends State<UploadAvatar> {
  // 文件(`File`)類,對文件系統上的文件的引用。
  /// 從相冊選擇的圖片文件。
  File _image;

  /// 打開系統相冊並選擇一張照片。
  Future getImage() async {
    // Flutter團隊開發的圖片選擇器(`image_picker`)插件。
    // 適用於iOS和Android的Flutter插件,用於從圖像庫中拾取圖像,並使用相機拍攝新照片。
    // https://pub.dartlang.org/packages/image_picker
    var image = await ImagePicker.pickImage(source: ImageSource.gallery);

    setState(() {
      // 更新用作頭像的照片。
      _image = image;
    });
  }

  // TODO: 第3步:實現“默認頭像圖片”

  // TODO: 第4步:實現“圓形頭像圖片”

  @override
  Widget build(BuildContext context) {
    return Row(
      // 主軸對齊(`mainAxisAlignment`)屬性,如何將子組件放在主軸上。
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        GestureDetector(
          onTap: getImage,
          child: Container(
            width: 130.0,
            height: 135.0,
            child: _image == null
                  // 第3步實現的自定義組件。
                  ? defaultImage
                  // 第4步實現的自定義組件。
                  : ovalImage(_image),
          ),
        ),
      ],
    );
  }
}

第3步:實現“默認頭像圖片”

通過堆棧(Stack)組件在默認頭像圖片的上面放提醒操作的圖片,作爲用戶沒有選擇頭像圖片時的默認顯示組件。

  // TODO: 第3步:實現“默認頭像圖片”
  /// 自定義的默認頭像組件,用來顯示默認圖片。
  Widget defaultImage = Stack(
    children: <Widget>[
      Align(
        // 默認頭像圖片放在左上方。
        alignment: Alignment.topLeft,
        child: Image.asset(
          'assets/icon_head_default.png',
          fit: BoxFit.contain,
          height: 130.0,
          width: 135.0,
        ),
      ),
      Align(
        // 編輯頭像圖片放在右下方。
        alignment: Alignment.bottomRight,
        child: Image.asset(
          'assets/icon_edit.png',
          fit: BoxFit.contain,
          height: 48.0,
        ),
      ),
    ],
  );

第4步:實現“圓形頭像圖片”

使用剪輯橢圓形(ClipOval)組件將圖片裁剪成圓形圖片,放在邊框背景圖片的下面,再通過容器(Container)組件來對齊位置,使它們嚴絲合縫的結合在一起。

  // TODO: 第4步:實現“圓形頭像圖片”
  /// 自定義的橢圓形頭像組件,用來裁剪顯示頭像。
  Widget ovalImage(File image) {
    return Stack(
      children: <Widget>[
        Container(
          // 通過容器(`Container`)組件的填充(`padding`)屬性,使頭像對齊邊框。
          padding: EdgeInsets.fromLTRB(9.0, 10.5, 0.0, 0.0),
          // 剪輯橢圓形(`ClipOval`)組件,使用橢圓剪輯其子項的組件。
          child: ClipOval(
            // 圖片.文件(`Image.file`)構造函數,創建一個窗口組件,顯示從文件獲取的圖片流。
            child: Image.file(
              image,
              fit: BoxFit.cover,
              height: 109.0,
              width: 109.0,
            ),
          ),
        ),
        // 頭像邊框圖片默認放在左上方。
        Image.asset(
          'assets/icon_head_default_null.png',
          fit: BoxFit.contain,
          height: 130.0,
          width: 135.0,
        ),
      ],
    );
  }

第5步:還原效果

有背景圖的頭像選擇的還原效果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章