Flutter Web开发模仿系列(1) - 登陆页面

272 阅读3分钟

开篇

       学一门语言, 当然要用了. 凭空创造我又没有那审美, 所以从模仿开始, 今天从网上搜了一个登陆模版, 就从登陆开始仿起. 如下是原图

实现

看到页面, 先分析结构.

层级结构如下:

整体层级结构和上面差不多, 看下具体实现

import 'package:flutter/material.dart';class LoginPage extends StatefulWidget {  const LoginPage({super.key});  @override  State<LoginPage> createState() => _LoginPageState();}class _LoginPageState extends State<LoginPage> {  Widget _buildMainView() {    return Scaffold(      backgroundColor: const Color(0xFFEDEDED),      body: Center(        child: Container(          width: 900,          height: 550,          decoration: const BoxDecoration(            image: DecorationImage(image: AssetImage("assets/images/bg.jpg"), fit: BoxFit.fill),          ),          child: Row(children: [            Container(              width: 640,              height: double.infinity,              color: Colors.white,              child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [                const SizedBox(height: 50),                const Text("欢迎回来", style: TextStyle(fontSize: 26, fontWeight: FontWeight.bold)),                const SizedBox(height: 35),                const Text("邮箱", style: TextStyle(fontSize: 12, color: Color(0xFF909399))),                const SizedBox(                  width: 260,                  height: 30,                  child: TextField(                    decoration: InputDecoration(                      focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.black26)),                      enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.black26)),                      isCollapsed: true,                    ),                    cursorColor: Colors.black26,                    textAlign: TextAlign.center,                    cursorHeight: 16,                  ),                ),                const SizedBox(height: 25),                const Text("密码", style: TextStyle(fontSize: 12, color: Color(0xFF909399))),                const SizedBox(                  width: 260,                  height: 30,                  child: TextField(                    decoration: InputDecoration(                      focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.black26)),                      enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.black26)),                      isCollapsed: true,                    ),                    cursorColor: Colors.black26,                    textAlign: TextAlign.center,                    obscureText: true,                    cursorHeight: 16,                  ),                ),                const SizedBox(height: 15),                const Text(                  "忘记密码?",                  style: TextStyle(                    fontSize: 12,                    color: Color(0xFFcfcfcf),                    decoration: TextDecoration.underline,                    decorationColor: Color(0xFFcfcfcf),                  ),                ),                const SizedBox(height: 40),                SizedBox(                  width: 260,                  height: 36,                  child: TextButton(                    style: ButtonStyle(                      splashFactory: NoSplash.splashFactory,                      backgroundColor: MaterialStateProperty.all(const Color(0xFFd4af7a)),                      shape: MaterialStateProperty.all(RoundedRectangleBorder(                        borderRadius: BorderRadius.circular(90),                        side: const BorderSide(width: 2, color: Colors.white),                      )),                      padding: MaterialStateProperty.all(EdgeInsets.zero),                      elevation: MaterialStateProperty.all(0),                    ),                    onPressed: () {},                    child: const Text("登 录", style: TextStyle(fontSize: 15, color: Colors.white, fontWeight: FontWeight.w500)),                  ),                ),                const SizedBox(height: 20),                SizedBox(                  width: 260,                  height: 36,                  child: TextButton(                    style: ButtonStyle(                      splashFactory: NoSplash.splashFactory,                      shape: MaterialStateProperty.all(RoundedRectangleBorder(                        borderRadius: BorderRadius.circular(90),                        side: const BorderSide(width: 2, color: Color(0xFFD3DAE9)),                      )),                      padding: MaterialStateProperty.all(EdgeInsets.zero),                      elevation: MaterialStateProperty.all(0),                    ),                    onPressed: () {},                    child: const Text("使用Facebook账号登录", style: TextStyle(fontSize: 15, color: Color(0xFF8FA1C7), fontWeight: FontWeight.w500)),                  ),                ),              ]),            ),            Expanded(              child: Container(                decoration: const BoxDecoration(boxShadow: [BoxShadow(color: Colors.black54)]),                child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [                  const SizedBox(height: 50),                  const Text(                    "还未注册?",                    style: TextStyle(                      color: Colors.white,                      fontSize: 26,                      fontWeight: FontWeight.w400,                    ),                  ),                  const SizedBox(height: 10),                  const Text(                    "立即注册, 发现大量机会!",                    style: TextStyle(                      color: Colors.white,                      fontSize: 14,                      fontWeight: FontWeight.w600,                    ),                  ),                  const Spacer(),                  SizedBox(                    width: 100,                    height: 36,                    child: TextButton(                      style: ButtonStyle(                        splashFactory: NoSplash.splashFactory,                        // backgroundColor: MaterialStateProperty.all(const Color(0xFF18BC84)),                        shape: MaterialStateProperty.all(RoundedRectangleBorder(                          borderRadius: BorderRadius.circular(90),                          side: const BorderSide(width: 2, color: Colors.white),                        )),                        padding: MaterialStateProperty.all(EdgeInsets.zero),                        elevation: MaterialStateProperty.all(0),                      ),                      onPressed: () {},                      child: const Text("注册", style: TextStyle(fontSize: 15, color: Colors.white, fontWeight: FontWeight.w500)),                    ),                  ),                  const SizedBox(height: 150),                ]),              ),            ),          ]),        ),      ),    );  }  @override  Widget build(BuildContext context) {    return _buildMainView();  }}

运行效果如下(本demo是单独页面, 如试运行,需要自己在main中引入该页面)

总结

       实现过程中的间距和字体都是通过浏览器F12检查得出, 所以模仿出来的页面给人感觉无法和原页面效果一致. 就比如原页面用了h2标签, 在flutter中设置字体大小, 同时设置字重fontweight, 这个字重设置bold就显得太粗, 所以适当w500代替. 所以整体给人的效果还是很难和原页面效果一致. 

       其次就是facebook三方登陆的按钮, 这里里面其实是需要使用rich富文本实现, 结果发现这里没实现...ahaha, 算了, 后续再说吧.

       最后, 整体登陆页面仿造就这样了. 本次主要熟悉了文字加下划线、删除线, 登陆按钮圆角设置边框及背景色, 输入框光标居中、居左、居右输入等使用.