登录界面布局
效果
结构:login.dart和main.dart
1)main.dart
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'login.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. int _page = 0; @override Widget build(BuildContext context) { return MaterialApp( title: "Flutter", showSemanticsDebugger: false,//打开查看界面布局 theme: ThemeData( primarySwatch: Colors.pink ), home: HomePage() ); } }
2)login.dart
import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { TextEditingController _phone = new TextEditingController(); TextEditingController _pass = new TextEditingController(); bool _isCheck = true; TapGestureRecognizer _tapGestureRecognizer; @override void initState(){ super.initState(); _tapGestureRecognizer = TapGestureRecognizer(); _tapGestureRecognizer.onTap = myTap; } void myTap() { print("服务许可协议"); } Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomPadding: false, body: Container( decoration: BoxDecoration( color: Colors.white, //borderRadius: BorderRadius.only(bottomLeft: Radius.circular(30),bottomRight: Radius.circular(30)) ), child: Stack( children: <Widget>[ Container( color: Colors.pink[300], height: 250, ), Container( height: 300, margin: EdgeInsets.only(top: 180,right: 16,left: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8.0) ), ), Container( margin: EdgeInsets.only(top: 280), padding: EdgeInsets.only(left: 25,right: 25), child: Column( children: <Widget>[ Container( child: Text("登录",style: TextStyle(fontSize: 20,fontWeight: FontWeight.w800,color: Colors.lightBlue),), ), SizedBox( height: 25, ), Padding( padding: const EdgeInsets.all(3.0), child: TextField( controller: _phone, maxLength: 11, maxLines: 1, keyboardType: TextInputType.phone, decoration: InputDecoration( hintText: "请输入手机号", prefixIcon: Icon(Icons.smartphone), ), ), ), Padding( padding: const EdgeInsets.all(3.0), child: TextField( controller: _pass, maxLength: 30, maxLines: 1, obscureText: true, decoration: InputDecoration( hintText: "请输入密码", prefixIcon: Icon(Icons.lock), suffixIcon: Icon(Icons.remove_red_eye) ), ), ), Row( mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ Text("忘记密码?", style: TextStyle(fontSize: 16,color: Colors.grey), ), ], ), SizedBox( height: 50, ), InkWell( child: Container( height:50, decoration: BoxDecoration( color: Colors.pink[300], borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( offset: Offset(1.0,5.0), color: Color.fromRGBO(234, 61, 135, 0.4), blurRadius: 5.0 ) ] ), alignment: Alignment.center, child: Text( "登录", style: TextStyle(color: Colors.black,fontSize: 22,fontWeight: FontWeight.w800), ), ), ), SizedBox( height: 35, ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text("验证码登录",style: TextStyle(fontSize: 16,color: Colors.black)), Container( margin: EdgeInsets.only(left: 8,right: 8), height: 12, padding: EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( color: Colors.black45, ), width: 1, ), InkWell( child: Text("新用户注册",style: TextStyle(fontSize: 16,color: Colors.lightBlue),), ) ], ), SizedBox( height: 35, ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Checkbox( value: _isCheck, onChanged: (val){ setState(() { _isCheck = val; }); }, ), Text.rich( TextSpan( text: "我已阅读并同意遵守", style: TextStyle(fontSize: 14,color: Colors.grey), children: [ TextSpan( text: "《服务许可协议》", style: TextStyle(fontSize: 14,color: Colors.black54,fontWeight: FontWeight.w800,decoration: TextDecoration.underline), recognizer: _tapGestureRecognizer ) ] ) ), ], ) ], ), ), Align( alignment: Alignment.topCenter, child: Container( height: 150, width: 150, margin: EdgeInsets.only(top: 130), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(150) ), ), ), Align( alignment: Alignment.topCenter, child: Container( height: 130, width: 130, margin: EdgeInsets.only(top: 140), decoration: BoxDecoration( borderRadius: BorderRadius.circular(130), ), child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(130), image: DecorationImage( image: NetworkImage("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597589338548&di=32de3c568ee766705bed92432ef9e50d&imgtype=0&src=http%3A%2F%2Fwww.36588.com.cn%2FImageResourceMongo%2FUploadedFile%2Fdimension%2Fbig%2Fb911ff48-ebab-4269-9e01-c8ea21d7a37d.png"), fit: BoxFit.cover ) ), ), ), ), ], ), ), ); } }
补充:
1)
2)查看页面结构(类似谷歌浏览器的F12查看页面结构,直接鼠标点击指向对应页面元素)
3)看性能(打开后,操作一下,点击一下控件,柱状图就会动了,红色表示不合格(主要是由于在Debugger环境下),上下两个,上面指的是GPU线程渲染情况,下面指的是写的UI线程情况(代码情况,Dart一般比较快),柱条越低越好)
注:生成的APK在手机上看不到【网络引用的图片】,是由于授权问题
需要配置授权
在项目目录 android/app/src/main/AndroidManifest.xml中添加:
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
感谢:https://blog.csdn.net/qianlixiaomage/article/details/104102591