diff --git a/README.md b/README.md index 77aca77..8448fe2 100644 --- a/README.md +++ b/README.md @@ -41,3 +41,11 @@ samples, guidance on mobile development, and a full API reference. - 写布局前,先把结构列好,用函数拆分,用_bulid开头,表示私有布局函数 - 在使用elevatedbutton时,使用style将样式还原,在外面套一层Container作为装饰,更方便配置 - 使用Navigator.pushReplacement 替换路由 +## 表单 +- 表单TextField通过textfield.decoration进行装饰 +- 使用prefixIcon、suffixIcon设置前置、后置图标 +- 一些简单的验证可以放在TextField的onChanged中 +- 注意在涉及到更新状态时,使用setState +## 按钮组件 +- 抽取公共组件,放在commont里 +- 公共组件外露的属性,使用final修饰,并在构造函数中 \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 203dda5..039fc65 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -3,5 +3,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=file:///C:/Users/24811/.gradle/wrapper/dists/gradle-6.7-all.zip -# distributionUrl=file:///D:/Gradle/.gradle/wrapper/dists/gradle-6.7-all.zip \ No newline at end of file +# distributionUrl=file:///C:/Users/24811/.gradle/wrapper/dists/gradle-6.7-all.zip +distributionUrl=file:///D:/Gradle/.gradle/wrapper/dists/gradle-6.7-all.zip \ No newline at end of file diff --git a/assets/images/2.0x/icon_favourite.png b/assets/images/2.0x/icon_favourite.png new file mode 100644 index 0000000..228fa79 Binary files /dev/null and b/assets/images/2.0x/icon_favourite.png differ diff --git a/assets/images/2.0x/icon_lock.png b/assets/images/2.0x/icon_lock.png new file mode 100644 index 0000000..dd9da95 Binary files /dev/null and b/assets/images/2.0x/icon_lock.png differ diff --git a/assets/images/2.0x/icon_map.png b/assets/images/2.0x/icon_map.png new file mode 100644 index 0000000..cdae9a2 Binary files /dev/null and b/assets/images/2.0x/icon_map.png differ diff --git a/assets/images/2.0x/icon_offers.png b/assets/images/2.0x/icon_offers.png new file mode 100644 index 0000000..563b014 Binary files /dev/null and b/assets/images/2.0x/icon_offers.png differ diff --git a/assets/images/2.0x/icon_order.png b/assets/images/2.0x/icon_order.png new file mode 100644 index 0000000..3372f01 Binary files /dev/null and b/assets/images/2.0x/icon_order.png differ diff --git a/assets/images/2.0x/icon_payment.png b/assets/images/2.0x/icon_payment.png new file mode 100644 index 0000000..0c929ec Binary files /dev/null and b/assets/images/2.0x/icon_payment.png differ diff --git a/assets/images/2.0x/icon_user.png b/assets/images/2.0x/icon_user.png new file mode 100644 index 0000000..ebbe18f Binary files /dev/null and b/assets/images/2.0x/icon_user.png differ diff --git a/assets/images/3.0x/icon_favourite.png b/assets/images/3.0x/icon_favourite.png new file mode 100644 index 0000000..6f63114 Binary files /dev/null and b/assets/images/3.0x/icon_favourite.png differ diff --git a/assets/images/3.0x/icon_lock.png b/assets/images/3.0x/icon_lock.png new file mode 100644 index 0000000..38e7524 Binary files /dev/null and b/assets/images/3.0x/icon_lock.png differ diff --git a/assets/images/3.0x/icon_map.png b/assets/images/3.0x/icon_map.png new file mode 100644 index 0000000..c7e9b54 Binary files /dev/null and b/assets/images/3.0x/icon_map.png differ diff --git a/assets/images/3.0x/icon_offers.png b/assets/images/3.0x/icon_offers.png new file mode 100644 index 0000000..bdefaa5 Binary files /dev/null and b/assets/images/3.0x/icon_offers.png differ diff --git a/assets/images/3.0x/icon_order.png b/assets/images/3.0x/icon_order.png new file mode 100644 index 0000000..b19404f Binary files /dev/null and b/assets/images/3.0x/icon_order.png differ diff --git a/assets/images/3.0x/icon_payment.png b/assets/images/3.0x/icon_payment.png new file mode 100644 index 0000000..23e2db0 Binary files /dev/null and b/assets/images/3.0x/icon_payment.png differ diff --git a/assets/images/3.0x/icon_user.png b/assets/images/3.0x/icon_user.png new file mode 100644 index 0000000..7024d86 Binary files /dev/null and b/assets/images/3.0x/icon_user.png differ diff --git a/assets/images/files.txt b/assets/images/files.txt index f73865f..25112df 100644 --- a/assets/images/files.txt +++ b/assets/images/files.txt @@ -1,2 +1,9 @@ +static const iconFavouritePng = 'assets/images/icon_favourite.png'; +static const iconLockPng = 'assets/images/icon_lock.png'; +static const iconMapPng = 'assets/images/icon_map.png'; +static const iconOffersPng = 'assets/images/icon_offers.png'; +static const iconOrderPng = 'assets/images/icon_order.png'; +static const iconPaymentPng = 'assets/images/icon_payment.png'; +static const iconUserPng = 'assets/images/icon_user.png'; static const logoPng = 'assets/images/logo.png'; static const welcomePng = 'assets/images/welcome.png'; diff --git a/assets/images/icon_favourite.png b/assets/images/icon_favourite.png new file mode 100644 index 0000000..3a3f796 Binary files /dev/null and b/assets/images/icon_favourite.png differ diff --git a/assets/images/icon_lock.png b/assets/images/icon_lock.png new file mode 100644 index 0000000..eb3d08d Binary files /dev/null and b/assets/images/icon_lock.png differ diff --git a/assets/images/icon_map.png b/assets/images/icon_map.png new file mode 100644 index 0000000..b167306 Binary files /dev/null and b/assets/images/icon_map.png differ diff --git a/assets/images/icon_offers.png b/assets/images/icon_offers.png new file mode 100644 index 0000000..9213ae4 Binary files /dev/null and b/assets/images/icon_offers.png differ diff --git a/assets/images/icon_order.png b/assets/images/icon_order.png new file mode 100644 index 0000000..400c6be Binary files /dev/null and b/assets/images/icon_order.png differ diff --git a/assets/images/icon_payment.png b/assets/images/icon_payment.png new file mode 100644 index 0000000..42006a7 Binary files /dev/null and b/assets/images/icon_payment.png differ diff --git a/assets/images/icon_user.png b/assets/images/icon_user.png new file mode 100644 index 0000000..e687305 Binary files /dev/null and b/assets/images/icon_user.png differ diff --git a/lib/common/assets.dart b/lib/common/assets.dart index 2db0583..6759ee5 100644 --- a/lib/common/assets.dart +++ b/lib/common/assets.dart @@ -1,4 +1,12 @@ class AssetsImages { - static const logoPng = 'assets/images/logo.png'; - static const welcomePng = 'assets/images/welcome.png'; +static const iconFavouritePng = 'assets/images/icon_favourite.png'; +static const iconLockPng = 'assets/images/icon_lock.png'; +static const iconMapPng = 'assets/images/icon_map.png'; +static const iconOffersPng = 'assets/images/icon_offers.png'; +static const iconOrderPng = 'assets/images/icon_order.png'; +static const iconPaymentPng = 'assets/images/icon_payment.png'; +static const iconUserPng = 'assets/images/icon_user.png'; +static const logoPng = 'assets/images/logo.png'; +static const welcomePng = 'assets/images/welcome.png'; + } diff --git a/lib/common/button copy.dart b/lib/common/button copy.dart new file mode 100644 index 0000000..cc61574 --- /dev/null +++ b/lib/common/button copy.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +class ButtonWidget extends StatelessWidget { + const ButtonWidget({ + Key? key, this.text, this.width, this.height, this.radius, this.onPressed, + }) : super(key: key); + + final String? text; + final double? width; + final double? height; + final double? radius; + final void Function()? onPressed; + + + @override + Widget build(BuildContext context) { + //套一层Container,可以做很多事,比如设置尺寸 + return Container( + //不写默认撑开 + height: height ?? double.infinity, + width: width ?? double.infinity, + //需要裁切,不然没有圆角 + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(radius ?? 32), + ), + child: ElevatedButton( + onPressed: onPressed, + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + //设置最小值为0,是的尺寸为children尺寸 + minimumSize: MaterialStateProperty.all(Size.zero)), + child: Text(text ?? "", + style: const TextStyle( + fontSize: 16, + color: Colors.white, + fontWeight: FontWeight.w300, + )), + ), + ); + } +} diff --git a/lib/common/button.dart b/lib/common/button.dart new file mode 100644 index 0000000..05c87ff --- /dev/null +++ b/lib/common/button.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; + +class ButtonWidget extends StatelessWidget { + const ButtonWidget({ + Key? key, + this.text, + this.width, + this.height, + this.radius, + this.onPressed, + }) : super(key: key); + + final String? text; + final double? width; + final double? height; + final double? radius; + final void Function()? onPressed; + + @override + Widget build(BuildContext context) { + //套一层Container,可以做很多事,比如设置尺寸 + return ElevatedButton( + onPressed: onPressed, + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + //设置最小值为0,是的尺寸为children尺寸 + minimumSize: MaterialStateProperty.all(Size( + width ?? double.infinity, + height ?? double.infinity, + )), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(radius?? 32), + ), + ), + ), + child: Text(text ?? "", + style: const TextStyle( + fontSize: 16, + color: Colors.white, + fontWeight: FontWeight.w300, + )), + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index 641bfb8..bc966c6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; - -import 'pages/login.dart'; +import 'pages/splash.dart'; void main() { @@ -13,7 +12,7 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - home: const LoginPage(), + home: const SplashPage(), debugShowCheckedModeBanner: false, theme: ThemeData( //设置主题色 diff --git a/lib/pages/login.dart b/lib/pages/login.dart index bda56f6..5c9412a 100644 --- a/lib/pages/login.dart +++ b/lib/pages/login.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_qucikstart/common/button.dart'; import '../common/app_colors.dart'; import '../common/assets.dart'; @@ -11,9 +12,133 @@ class LoginPage extends StatefulWidget { } class _LoginPageState extends State { - //登录表达 + //检查账号输入是否有效 + bool isUserNameValid = false; + //登录表单 Widget _buildForm() { - return Container(); + return Container( + padding: const EdgeInsets.fromLTRB(20, 70, 20, 35), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(35), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //Username or Email + const Text( + 'Username or Email', + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w300, + color: Color(0xFF838383), + ), + ), + const SizedBox(height: 16), + TextField( + //Onchange时检测输入是否有效 + onChanged: (value) { + setState(() { + isUserNameValid = value.isNotEmpty && value.length > 6; + }); + }, + decoration: InputDecoration( + hintText: '@', + prefixIcon: Image.asset( + AssetsImages.iconUserPng, + width: 23, + height: 23, + ), + suffixIcon: isUserNameValid == true + ? const Icon( + Icons.done, + size: 24, + color: Colors.green, + ) + : null, + ), + ), + + const SizedBox(height: 36), + + //password + const Text( + 'Password', + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w300, + color: Color(0xFF838383), + ), + ), + const SizedBox(height: 16), + TextField( + //隐藏输入 + obscureText: true, + decoration: InputDecoration( + hintText: '6 digits', + prefixIcon: Image.asset( + AssetsImages.iconLockPng, + width: 19, + height: 26, + ), + suffixIcon: TextButton( + onPressed: (() {}), + child: const Text( + 'Forget?', + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w500, + color: Color(0xFF0274BC), + ), + ), + ), + ), + ), + + const SizedBox(height: 30), + + //Sign In btn + ButtonWidget( + text: "Sign In", + height: 57, + onPressed:(){} + ), + + + const SizedBox(height: 16), + + //Don't have an account? Sign up + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + //文字 + const Text( + "Don't have an account?", + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w300, + color: Color(0xFF171717), + ), + ), + //文字按钮 + TextButton( + onPressed: (() {}), + child: const Text( + "Sign up", + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + color: Color(0xFF0274bc), + ), + ), + ) + ], + ) + + //end + ], + ), + ); } //主视图 拆成函数 diff --git a/lib/pages/welcome.dart b/lib/pages/welcome.dart index b5a44bd..a6f83eb 100644 --- a/lib/pages/welcome.dart +++ b/lib/pages/welcome.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; import '../common/assets.dart'; +import '../common/button.dart'; +import '../pages/login.dart'; class WelcomePage extends StatelessWidget { const WelcomePage({Key? key}) : super(key: key); //按钮组 - Widget _bulidBtns() { + Widget _bulidBtns(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Row( @@ -26,28 +28,13 @@ class WelcomePage extends StatelessWidget { const Spacer(), //getstarted按钮 - //套一层Container,可以做很多事,比如设置尺寸 - Container( - height: 42, + ButtonWidget( + text: "Get Started", width: 139, - //需要裁切,不然没有圆角 - clipBehavior: Clip.antiAlias, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(32), - ), - child: ElevatedButton( - onPressed: (() {}), - style: ButtonStyle( - elevation: MaterialStateProperty.all(0), - //设置最小值为0,是的尺寸为children尺寸 - minimumSize: MaterialStateProperty.all(Size.zero)), - child: const Text('Get Started', - style: TextStyle( - fontSize: 16, - color: Colors.white, - fontWeight: FontWeight.w300, - )), - ), + height: 42, + radius: 32, + onPressed: () => Navigator.push(context, + MaterialPageRoute(builder: ((context) => const LoginPage()))), ), ], ), @@ -69,7 +56,7 @@ class WelcomePage extends StatelessWidget { ); } - Widget _buildView() { + Widget _buildView(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -91,7 +78,7 @@ class WelcomePage extends StatelessWidget { height: 70, ), //按钮组 - _bulidBtns(), + _bulidBtns(context), //end ], @@ -101,7 +88,7 @@ class WelcomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - body: Center(child: _buildView()), + body: Center(child: _buildView(context)), ); } }