flutter开发环境搭建略
如果是新搭建好的环境,需要开启web支持和windows支持
flutter config --enable-windows-desktop
flutter config --enable-web
创建项目名为spore,英文翻译为孢子,希望可以”做大做强“(无名之辈的发音)吧,毕竟谁不好大喜功呢!
flutter create spore
cd spore

web运行查看
flutter run -d Chrome

windows运行查看
flutter run -d Windows

本篇的主要目的就是把这个页面搞成登录页,就算OK
来说一下目录结构

红色箭头指向的两个文件夹是添加平台支持后才会有的,如果你的目录中没有,就是添加支持出问题,或者干脆忘记添加了。
蓝色箭头指向的是和本篇关系很大的两个文件,尤其是main.dart,是整个项目的主入口文件,灰常重要

因为是第一篇,就搞的尽量简单点,后面丰富吧,我一向提倡先解决有的问题,再解决好看的问题。当然也不能太不想个样子,lib下新建文件夹pages,pages新建login.dart

先贴代码的基本结构,注释说明

import 'package:flutter/material.dart';class LoginPage extends StatefulWidget {//继承StatefulWidget类,表示它是一个有状态的组件const LoginPage({Key? key}) : super(key: key);@override_LoginPageState createState() => _LoginPageState();//如果集成StatelessWidget类,这里就该是Widget build(BuildContext context)
}class _LoginPageState extends State<LoginPage>{@overrideWidget build(BuildContext context) {//构建UI,写控件的地方// TODO: implement buildthrow UnimplementedError();}}

flutter把控件从状态的角度分为两大类:StatefulWidget和StatelessWidget,据说懂RN的这个自然懂,反正我不懂。。。
StatefulWidget为了更好的提升实现状态管理和UI重绘等性能,设计成createState()返回一个组件的State对象来进行操作。具体原理先不用懂,反正就是王八的屁股—规定

基础勉强实现功能版

代码如下

import 'package:flutter/material.dart';class LoginPage extends StatefulWidget {//继承StatefulWidget类,表示它是一个有状态的组件const LoginPage({Key? key}) : super(key: key);@override_LoginPageState createState() => _LoginPageState();//如果集成StatelessWidget类,这里就该是Widget build(BuildContext context)
}class _LoginPageState extends State<LoginPage>{final GlobalKey<FormState> formKey = GlobalKey<FormState>();String? userName;String? password;@overrideWidget build(BuildContext context) {//构建UI,写控件的地方return Theme(data: ThemeData(),child: Scaffold(body: _buildPageContent(),),);}Widget _buildPageContent() {return Container(color: const Color.fromARGB(255, 148, 200, 207),child: ListView(children: <Widget>[const Center(child: Text("欢迎使用本系统",style: TextStyle(fontSize: 18, color: Colors.black),textScaleFactor: 3.2 //缩放倍数,没有这个字会很小)),const SizedBox(height: 20.0),_buildLoginForm(),//缩进写到烦人,搞个方法。const SizedBox(height: 20.0),],),);}Container _buildLoginForm() {return Container(color: const Color.fromARGB(255, 45, 183, 201),child: Stack(//自由位置的组件children: [Center(child: Container(width: 500,height: 260,margin: EdgeInsets.only(top: 40),padding: EdgeInsets.all(10.0),decoration: BoxDecoration(//白色的圆角方框borderRadius: BorderRadius.all(Radius.circular(40.0)),color: Colors.white,),child: Form(key: formKey,child: Column(children: [Container(child: TextFormField(initialValue: "admin",//可以不要这个参数onSaved: (v) {userName = v;},validator: (v) {return v!.isEmpty ? "请输入用户名" : null;},),),Container(child: TextFormField(initialValue: "123456",obscureText: true,onSaved: (v) {password = v;},validator: (v) {return v!.isEmpty ? "请输入密码" : null;},),),],))),),Container(height: 260,alignment: Alignment.bottomCenter,child: SizedBox(width: 420,child: ElevatedButton(onPressed: _login,style: ButtonStyle(shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(40.0))),),child: const Text("登录", style: TextStyle(color: Colors.white70, fontSize: 20)),),),),],),);}_login(){var form = formKey.currentState!;if (!form.validate()) {return;}form.save();//会调用TextFormField的onSaveif(userName=='admin' && password=='123456'){_showAlertDialog(context,'登录成功');}else{_showAlertDialog(context,'用户名或密码错误');}}//没有找到方便的toast控件,搞个这代替_showAlertDialog(BuildContext context,String msg) {//设置按钮Widget okButton = TextButton(child: const Text("OK"),onPressed: () {Navigator.of(context).pop(); },);//设置对话框AlertDialog alert = AlertDialog(title: const Text("提示"),content: Text(msg),actions: [okButton,],);//显示对话框showDialog(context: context,builder: (BuildContext context) {return alert;},);}
}

精细化版,抄别人的,最后贴地址

虽然还是丑,以后有的是机会再优化,代码如下:

import 'package:flutter/material.dart';class LoginPage extends StatefulWidget {//继承StatefulWidget类,表示它是一个有状态的组件const LoginPage({Key? key}) : super(key: key);@override_LoginPageState createState() => _LoginPageState();//如果集成StatelessWidget类,这里就该是Widget build(BuildContext context)
}class _LoginPageState extends State<LoginPage>{final GlobalKey<FormState> formKey = GlobalKey<FormState>();String? userName;String? password;FocusNode focusNodeUserName = FocusNode();FocusNode focusNodePassword = FocusNode();@overrideWidget build(BuildContext context) {//构建UI,写控件的地方return Theme(data: ThemeData(),child: Scaffold(body: _buildPageContent(),),);}Widget _buildPageContent() {return Container(color: const Color.fromARGB(255, 110, 238, 255),child: ListView(children: <Widget>[const Center(child: Text("欢迎使用本系统",style: TextStyle(fontSize: 18, color: Colors.black),textScaleFactor: 3.2 //缩放倍数,没有这个字会很小)),const SizedBox(height: 20.0),_buildLoginForm(),//缩进写到烦人,搞个方法。const SizedBox(height: 20.0),],),);}Container _buildLoginForm() {return Container(padding: const EdgeInsets.fromLTRB(0, 30, 0, 30),color: const Color.fromARGB(255, 45, 183, 201),child: Stack(//自由位置的组件children: [Center(child: Container(width: 500,height: 320,margin: const EdgeInsets.only(top: 40),padding: const EdgeInsets.all(10.0),decoration: const BoxDecoration(//白色的圆角方框borderRadius: BorderRadius.all(Radius.circular(40.0)),color: Colors.white,),child: Form(key: formKey,child: Column(mainAxisAlignment: MainAxisAlignment.center,//垂直居中children: [Container(padding: const EdgeInsets.fromLTRB(20, 0, 20, 20),child: TextFormField(focusNode: focusNodeUserName,initialValue: "admin",style: const TextStyle(color: Colors.black),decoration: const InputDecoration(border: OutlineInputBorder(),labelText: "用户名",icon: Icon(Icons.people,color: Colors.blue,),),onSaved: (v) {userName = v;},validator: (v) {return v!.isEmpty ? "请输入用户名" : null;},onFieldSubmitted: (v) {//按shift触发方法focusNodePassword.requestFocus();},),),Container(padding: const EdgeInsets.fromLTRB(20, 0, 20, 20),child: TextFormField(focusNode: focusNodePassword,initialValue: "123456",obscureText: true,style: const TextStyle(color: Colors.black),decoration: const InputDecoration(border: OutlineInputBorder(),labelText: "密码",icon: Icon(Icons.lock,color: Colors.blue,),),onSaved: (v) {password = v;},validator: (v) {return v!.isEmpty ? "请输入密码" : null;},onFieldSubmitted: (v) {_login();},),),Row(mainAxisAlignment: MainAxisAlignment.end,children: <Widget>[TextButton(child: const Text('去注册',style: TextStyle(color: Colors.blue),),onPressed: () {},),TextButton(child: const Text('忘记密码',style: TextStyle(color: Colors.black45),),onPressed: () {},)],),],))),),Container(height: 320,alignment: Alignment.bottomCenter,child: SizedBox(width: 420,child: ElevatedButton(onPressed: _login,style: ButtonStyle(shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(40.0))),),child: const Text("登录", style: TextStyle(color: Colors.white70, fontSize: 20)),),),),],),);}_login(){var form = formKey.currentState!;if (!form.validate()) {return;}form.save();//会调用TextFormField的onSave//等集成dio再优化if(userName=='admin' && password=='123456'){_showAlertDialog(context,'登录成功');}else{_showAlertDialog(context,'用户名或密码错误');}}//没有找到方便的toast控件,搞个这代替_showAlertDialog(BuildContext context,String msg) {//设置按钮Widget okButton = TextButton(child: const Text("OK"),onPressed: () {Navigator.of(context).pop(); },);//设置对话框AlertDialog alert = AlertDialog(title: const Text("提示"),content: Text(msg),actions: [okButton,],);//显示对话框showDialog(context: context,builder: (BuildContext context) {return alert;},);}
}

注册页面和登录差不多,举一反三尝试复制一份改个名字,稍作调整,就可以了

我并不是精通flutter的移动开发之后写这个博客,是拿别人的项目一边抄,一边学习,一边摸索,一边实践,顺便记录下来,我直接参考的项目地址就列出来,如果有和我想法差不多的,我建议直接拿去学习研究吧

github地址:flutterAdmin gitee也有,但是作者好久没更新了,我就不贴了

另一个 知乎看到的另一个看着也不错的,可以看看,作参考

本篇博客完整demo下载spore-01.zip

Flutter Web(一)新建项目和登录页相关推荐

  1. Flutter web 滚动循环 title(Flutter Web端 滚动显示浏览器标签页名)

    应用场景:一般用于页面收到新消息通知时,或者正在播放音视频时浏览器标签页会循环显示标签名称,以达到提醒或表示正在进行的效果. Flutter 代码 /*** 修改html的title {repeat ...

  2. H5C3第一个完整大项目————三国杀登录页跳转游卡官网

    本次展示一下游卡官网的代码与成果图 成果图如下 其中业务板块可以悬停切换图片与下面内容 代码如下 html代码 <!DOCTYPE html> <html lang="en ...

  3. Web收银台系统[项目] -- (3) 登录页面

    1. 登录页面的过程: 输入用户名和密码点击登录, 点击完登录之后, 还是要交给相应的servlet, 接着这个登录的servlet会去操作数据库, 进行查询一下当前要登录的用户在数据库中是否存在, ...

  4. vue3-admin商品管理后台项目(登录页开发和功能实现)

    今天来实现vue3-admin商品管理后台项目的登录页功能 首先在pages文件夹下面添加一个login.vue文件,里面先写入简单的template <template><div& ...

  5. CAS—修改默认登录页

    1.  部署CAS-Server 本文以cas-server-3.4.11-release.zip为例,解压提取cas-server-3.4.11/modules/cas-server-webapp- ...

  6. flutter Web QQ登录

    目前flutter插件库里面的QQ登录并不支持web端,所以这一块的代码必须自己实现 首先需要在腾讯开放平台注册一个网页应用,然后拿到appid 一.引入QQ登录sdk web工程下面的index.h ...

  7. Flutter Web实战项目打造真正跨平台应用(windows,android,ios,linux,macos,web)

    Flutter Web项目 Flutter 最近发布了 Flutter V2.5.1,其性能得到了很大提升,支持 Web.macOS.Android 和 iOS. 这就是为什么今天我们使用在 Web. ...

  8. Eclipse新建项目里没有Web Project应该如何处理

    我试图通过Eclipse的新建项目向导,创建一个dynamic web project,发现向导里并没有对应的选项: 使用Install New package安装必要的资源.首先弄清楚自己使用Ecl ...

  9. vs2005新建项目中没有ASP.NET WEB应用程序

    今天正准备使用vs 2005,发现根本打不开老师发过来的源代码Portal_Article.csproj文件,上网查了一下,好多人都说是是因为没有给vs 2005打补丁.我的新建项目里根本没有ASP. ...

最新文章

  1. hdu 6148 数位dp
  2. OpenCV 腐蚀和膨胀
  3. Centos7 Minimal 版安装后安装图形界面教程
  4. Android 百度地图之全局搜索周边搜索全国搜索城市路线规划(升级版附源码)
  5. QuickWAP V1.5利用ASP读取Access记录集一例
  6. java学习(75):GUL文本框和标签
  7. python安装过程中出现文件或目录损坏且无法读取_解决安装python库时windows error5 报错的问题...
  8. 常用 shell sql 命令
  9. Mac: Failed to connect to raw.githubusercontent.com port 443: Connection refused error:
  10. 【电子签章】HTML格式合同转化成PDF文件
  11. SSM框架整合思想及步骤
  12. 渲梦工厂V2.1.5.0简体中文官方版,作图快10倍~
  13. 树莓派3B+新麦克风调试
  14. android 地球坐标 火星坐标系,Android LBS地图开发:地球地理GPS坐标系经纬度偏移偏差...
  15. 仙人掌植物盆栽ui布局特效
  16. Asset Pricing:Valuation
  17. day16_雷神_前端04
  18. linux注册域名命令,Linux基础命令---显示域名ypdomainname
  19. UART串行通信模式
  20. js --- 转数值类型

热门文章

  1. 卷积核大小、个数,卷积层数是如何确定的 ?
  2. 1.Postman之发送get请求
  3. CorelDRAW X6和PhotoZoom在一起,会碰撞出什么样的火花?
  4. 半导体衰落超出想象,会熊市反弹? – 25 年来 71 家公司的库存分析
  5. Java 从键盘输入一个字符串,统计某个字符的个数
  6. visio 2007:方向键无法移动图像解决方法
  7. 企微SCRM软件能让微信营销达到什么新高度
  8. 量化股票是什么意思?
  9. 单片机之基础编程 流水灯(二)
  10. 一套代码实现1对1 、1对N在线课堂与低延迟大班课