forked from lxm_flutter/FlutterUnit
登录和注册页面
This commit is contained in:
12
lib/app/api/user_api.dart
Normal file
12
lib/app/api/user_api.dart
Normal file
@@ -0,0 +1,12 @@
|
||||
/// create by 张风捷特烈 on 2021/1/17
|
||||
/// contact me by email 1981462002@qq.com
|
||||
/// 说明:
|
||||
|
||||
class UserApi{
|
||||
|
||||
Future<String> register({String email,String code}){
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import 'package:flutter_unit/views/pages/gallery/gallery_page.dart';
|
||||
import 'package:flutter_unit/views/pages/issues_point/issues_detail.dart';
|
||||
import 'package:flutter_unit/views/pages/issues_point/issues_point_page.dart';
|
||||
import 'package:flutter_unit/views/pages/login/login_page.dart';
|
||||
import 'package:flutter_unit/views/pages/register/register_page.dart';
|
||||
import 'package:flutter_unit/views/pages/search/serach_page.dart';
|
||||
import 'package:flutter_unit/views/pages/setting/code_style_setting.dart';
|
||||
import 'package:flutter_unit/views/pages/setting/font_setting.dart';
|
||||
@@ -24,7 +25,6 @@ import 'package:flutter_unit/views/pages/setting/setting_page.dart';
|
||||
import 'router_utils.dart';
|
||||
|
||||
class UnitRouter {
|
||||
|
||||
static const String widget_detail = '/widget_detail';
|
||||
|
||||
static const String detail = 'detail';
|
||||
@@ -52,6 +52,7 @@ class UnitRouter {
|
||||
static const String layout = 'LayoutUnitPage';
|
||||
static const String about_me = 'AboutMePage';
|
||||
static const String about_app = 'AboutAppPage';
|
||||
static const String register = 'register';
|
||||
|
||||
static Route<dynamic> generateRoute(RouteSettings settings) {
|
||||
switch (settings.name) {
|
||||
@@ -83,11 +84,17 @@ class UnitRouter {
|
||||
case version_info:
|
||||
return Right2LeftRouter(child: VersionInfo());
|
||||
|
||||
case version_info:
|
||||
return Right2LeftRouter(child: VersionInfo());
|
||||
|
||||
case issues_point:
|
||||
return Right2LeftRouter(child: IssuesPointPage());
|
||||
case login:
|
||||
return Right2LeftRouter(child: LoginPage());
|
||||
|
||||
case register:
|
||||
return Right2LeftRouter(child: RegisterPage());
|
||||
|
||||
case attr:
|
||||
return Right2LeftRouter(child: AttrUnitPage());
|
||||
case bug:
|
||||
|
||||
19
lib/blocs/register/bloc.dart
Normal file
19
lib/blocs/register/bloc.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'event.dart';
|
||||
import 'state.dart';
|
||||
|
||||
/// create by 张风捷特烈 on 2021/1/17
|
||||
/// contact me by email 1981462002@qq.com
|
||||
/// 说明:
|
||||
|
||||
class RegisterBloc extends Bloc<RegisterEvent, RegisterState> {
|
||||
RegisterBloc() : super(RegisterLoading());
|
||||
|
||||
@override
|
||||
Stream<RegisterState> mapEventToState(RegisterEvent event) async* {
|
||||
if (event is DoRegister) {
|
||||
yield RegisterLoading();
|
||||
}
|
||||
}
|
||||
}
|
||||
24
lib/blocs/register/event.dart
Normal file
24
lib/blocs/register/event.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_unit/model/enums.dart';
|
||||
import 'package:flutter_unit/storage/po/widget_po.dart';
|
||||
import 'package:flutter_unit/model/widget_model.dart';
|
||||
|
||||
/// create by 张风捷特烈 on 2020-03-03
|
||||
/// contact me by email 1981462002@qq.com
|
||||
/// 说明:
|
||||
|
||||
abstract class RegisterEvent extends Equatable {
|
||||
const RegisterEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
// 发送 邮箱验证
|
||||
class DoRegister extends RegisterEvent {
|
||||
final String email;
|
||||
final String code;
|
||||
|
||||
DoRegister(this.email, this.code);
|
||||
}
|
||||
44
lib/blocs/register/state.dart
Normal file
44
lib/blocs/register/state.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_unit/model/enums.dart';
|
||||
import 'package:flutter_unit/app/res/cons.dart';
|
||||
import 'package:flutter_unit/model/widget_model.dart';
|
||||
|
||||
/// create by 张风捷特烈 on 2020-03-03
|
||||
/// contact me by email 1981462002@qq.com
|
||||
/// 说明: 主页 Widget 列表 状态类
|
||||
|
||||
abstract class RegisterState extends Equatable {
|
||||
const RegisterState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class RegisterLoading extends RegisterState {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class RegisterError extends RegisterState {
|
||||
final String message;
|
||||
|
||||
const RegisterError(this.message);
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'RegisterError{message: $message}';
|
||||
}
|
||||
}
|
||||
|
||||
class RegisterSuccess extends RegisterState {
|
||||
final String username;
|
||||
|
||||
const RegisterSuccess(this.username);
|
||||
|
||||
@override
|
||||
List<Object> get props => [username];
|
||||
}
|
||||
47
lib/views/components/permanent/icon_input.dart
Normal file
47
lib/views/components/permanent/icon_input.dart
Normal file
@@ -0,0 +1,47 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// create by 张风捷特烈 on 2021/1/17
|
||||
/// contact me by email 1981462002@qq.com
|
||||
/// 说明:
|
||||
|
||||
class IconInput extends StatelessWidget {
|
||||
|
||||
final Widget textFiled;
|
||||
final IconData icon;
|
||||
|
||||
IconInput({Key key,this.textFiled,this.icon}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
width: 1.0,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 20.0,
|
||||
width: 1.0,
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
margin: const EdgeInsets.only(left: 00.0, right: 10.0),
|
||||
),
|
||||
Expanded(
|
||||
child: textFiled,
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// create by 张风捷特烈 on 2020/4/27
|
||||
/// contact me by email 1981462002@qq.com
|
||||
/// 说明:
|
||||
|
||||
class ArcClipper extends CustomClipper<Path> {
|
||||
final double factor;
|
||||
|
||||
ArcClipper({this.factor = 0.618});
|
||||
|
||||
@override
|
||||
Path getClip(Size size) => Path()
|
||||
..moveTo(0, 0)
|
||||
..relativeLineTo(size.width, 0)
|
||||
..relativeLineTo(0, 0.8 * size.height)
|
||||
..arcToPoint(
|
||||
Offset(0.0, size.height * 0.618),
|
||||
radius: const Radius.elliptical(50.0, 10.0),
|
||||
rotation: 0.0,
|
||||
)
|
||||
..close();
|
||||
|
||||
@override
|
||||
bool shouldReclip(ArcClipper oldClipper) => factor != oldClipper.factor;
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_unit/app/res/toly_icon.dart';
|
||||
import 'package:flutter_unit/app/router/unit_router.dart';
|
||||
import 'package:flutter_unit/views/components/permanent/feedback_widget.dart';
|
||||
|
||||
|
||||
@@ -24,7 +25,7 @@ class _LoginFromState extends State<LoginFrom> {
|
||||
children: <Widget>[
|
||||
Text("FlutterUnit 登录",style: TextStyle(fontSize: 25),),
|
||||
SizedBox(height: 5,),
|
||||
Text("请使用github用户名登录",style: TextStyle(color: Colors.grey),),
|
||||
Text("更多精彩,更多体验 ~",style: TextStyle(color: Colors.grey),),
|
||||
SizedBox(height:20,),
|
||||
buildUsernameInput(),
|
||||
Stack(
|
||||
@@ -45,17 +46,23 @@ class _LoginFromState extends State<LoginFrom> {
|
||||
style: TextStyle(color: Color(0xff444444), fontSize: 14),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
"如何注册?",
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
fontSize: 14,
|
||||
decoration: TextDecoration.underline),
|
||||
FeedbackWidget(
|
||||
onEnd: (){
|
||||
Navigator.of(context).pushNamed(UnitRouter.register);
|
||||
},
|
||||
child: Text(
|
||||
"用户注册",
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
fontSize: 14,
|
||||
decoration: TextDecoration.underline),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
_buildBtn(),
|
||||
buildOtherLogin()
|
||||
buildOtherLogin(),
|
||||
const Spacer(flex: 4),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -82,7 +89,7 @@ class _LoginFromState extends State<LoginFrom> {
|
||||
borderRadius: BorderRadius.all(Radius.circular(20))),
|
||||
color: Colors.blue,
|
||||
onPressed: _doLogIn,
|
||||
child: Text("登 录",
|
||||
child: Text("进入 Unit 世界",
|
||||
style: TextStyle(color: Colors.white, fontSize: 18)),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_unit/app/res/toly_icon.dart';
|
||||
import 'package:flutter_unit/views/pages/register/arc_clipper.dart';
|
||||
|
||||
import 'arc_clipper.dart';
|
||||
import 'login_form.dart';
|
||||
|
||||
/// create by 张风捷特烈 on 2020/4/24
|
||||
@@ -11,6 +10,8 @@ import 'login_form.dart';
|
||||
class LoginPage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size winSize = MediaQuery.of(context).size;
|
||||
|
||||
return
|
||||
|
||||
// BlocListener<AuthenticBloc, AuthenticState>(
|
||||
@@ -21,11 +22,13 @@ class LoginPage extends StatelessWidget {
|
||||
// },
|
||||
// child:
|
||||
|
||||
Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: Wrap(children: [
|
||||
arcBackground(),
|
||||
Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: Wrap(children: [
|
||||
UnitArcBackground(height: winSize.height * 0.32),
|
||||
Container(
|
||||
// color: Colors.green,
|
||||
height: winSize.height * 0.68,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
padding: const EdgeInsets.only(left: 20.0, right: 20, top: 20),
|
||||
child:
|
||||
@@ -34,10 +37,10 @@ class LoginPage extends StatelessWidget {
|
||||
// builder: (_, state) {
|
||||
// return
|
||||
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
LoginFrom(),
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
LoginFrom(),
|
||||
// if (state is LoginFailure)
|
||||
// Positioned(
|
||||
// bottom: 0,
|
||||
@@ -48,56 +51,17 @@ class LoginPage extends StatelessWidget {
|
||||
// LoadingView(
|
||||
// text: "登录中...",
|
||||
// )
|
||||
],
|
||||
|
||||
)
|
||||
],
|
||||
)
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// )
|
||||
// ]
|
||||
)]
|
||||
)
|
||||
]
|
||||
// ),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
Widget arcBackground() {
|
||||
return ArcBackground(
|
||||
image: AssetImage("assets/images/caver.webp"),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(50.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue.withAlpha(88), shape: BoxShape.circle),
|
||||
child: Icon(TolyIcon.icon_github,size: 100,)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ArcBackground extends StatelessWidget {
|
||||
final Widget child;
|
||||
final ImageProvider image;
|
||||
|
||||
ArcBackground({this.child, this.image});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ClipPath(
|
||||
clipper: ArcClipper(),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: image,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
77
lib/views/pages/register/arc_clipper.dart
Normal file
77
lib/views/pages/register/arc_clipper.dart
Normal file
@@ -0,0 +1,77 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_unit/views/components/permanent/circle_image.dart';
|
||||
|
||||
/// create by 张风捷特烈 on 2020/4/27
|
||||
/// contact me by email 1981462002@qq.com
|
||||
/// 说明:
|
||||
|
||||
class ArcClipper extends CustomClipper<Path> {
|
||||
final double factor;
|
||||
|
||||
ArcClipper({this.factor = 0.618});
|
||||
|
||||
@override
|
||||
Path getClip(Size size) => Path()
|
||||
..moveTo(0, 0)
|
||||
..relativeLineTo(size.width, 0)
|
||||
..relativeLineTo(0, 0.8 * size.height)
|
||||
..arcToPoint(
|
||||
Offset(0.0, size.height * 0.618),
|
||||
radius: const Radius.elliptical(50.0, 10.0),
|
||||
rotation: 0.0,
|
||||
)
|
||||
..close();
|
||||
|
||||
@override
|
||||
bool shouldReclip(ArcClipper oldClipper) => factor != oldClipper.factor;
|
||||
}
|
||||
|
||||
class ArcBackground extends StatelessWidget {
|
||||
final Widget child;
|
||||
final ImageProvider image;
|
||||
|
||||
ArcBackground({this.child, this.image});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ClipPath(
|
||||
clipper: ArcClipper(),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: image,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class UnitArcBackground extends StatelessWidget {
|
||||
final double height;
|
||||
UnitArcBackground({Key key,this.height}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: height,
|
||||
child: ArcBackground(
|
||||
image: AssetImage("assets/images/caver.webp"),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(30),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.blue.withAlpha(88), shape: BoxShape.circle),
|
||||
child: CircleImage(
|
||||
size: 100,
|
||||
roundColor: Colors.blue,
|
||||
image: AssetImage(
|
||||
'assets/images/sabar.webp',
|
||||
)),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
116
lib/views/pages/register/register_page.dart
Normal file
116
lib/views/pages/register/register_page.dart
Normal file
@@ -0,0 +1,116 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_unit/views/components/permanent/icon_input.dart';
|
||||
|
||||
import 'arc_clipper.dart';
|
||||
import 'send_code.dart';
|
||||
|
||||
/// create by 张风捷特烈 on 2020/4/24
|
||||
/// contact me by email 1981462002@qq.com
|
||||
/// 说明:
|
||||
|
||||
class RegisterPage extends StatefulWidget {
|
||||
@override
|
||||
_RegisterPageState createState() => _RegisterPageState();
|
||||
}
|
||||
|
||||
class _RegisterPageState extends State<RegisterPage> {
|
||||
final _usernameController = TextEditingController(text: '1981462002@qq.com');
|
||||
final _passwordController = TextEditingController(text: '');
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size winSize = MediaQuery.of(context).size;
|
||||
|
||||
return Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: Wrap(children: [
|
||||
UnitArcBackground(height: winSize.height * 0.32),
|
||||
Container(
|
||||
width: winSize.width,
|
||||
height: winSize.height * 0.68,
|
||||
padding: const EdgeInsets.only(left: 20.0, right: 20, top: 20),
|
||||
child: Container(
|
||||
// color: Colors.green,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
const Text(
|
||||
"FlutterUnit 注册",
|
||||
style: TextStyle(fontSize: 25),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
const Text(
|
||||
"更多精彩,更多体验 ~",
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
const Spacer(
|
||||
flex: 1,
|
||||
),
|
||||
IconInput(
|
||||
icon: Icons.person_outline,
|
||||
textFiled: TextField(
|
||||
controller: _usernameController,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText: '请输入邮箱',
|
||||
hintStyle: TextStyle(color: Colors.grey),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 10),
|
||||
|
||||
buildInputWithSend(),
|
||||
|
||||
const Spacer(flex: 1),
|
||||
_buildBtn(),
|
||||
const Spacer(flex: 4),
|
||||
],
|
||||
),
|
||||
))
|
||||
]),
|
||||
));
|
||||
}
|
||||
|
||||
Stack buildInputWithSend() {
|
||||
return Stack(
|
||||
alignment: Alignment(.8, 0),
|
||||
children: [
|
||||
IconInput(
|
||||
icon: Icons.code_outlined,
|
||||
textFiled: TextField(
|
||||
controller: _passwordController,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText: '请输入验证码',
|
||||
hintStyle: TextStyle(color: Colors.grey),
|
||||
),
|
||||
),
|
||||
),
|
||||
CountDownWidget(
|
||||
onPress: () {
|
||||
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBtn() => Container(
|
||||
margin: EdgeInsets.only(top: 10, left: 10, right: 10, bottom: 0),
|
||||
height: 40,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: RaisedButton(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20))),
|
||||
color: Colors.blue,
|
||||
onPressed: _doRegister,
|
||||
child: Text("开启 Unit 新世界",
|
||||
style: TextStyle(color: Colors.white, fontSize: 18)),
|
||||
),
|
||||
);
|
||||
|
||||
void _doRegister() {}
|
||||
}
|
||||
50
lib/views/pages/register/send_code.dart
Normal file
50
lib/views/pages/register/send_code.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// create by 张风捷特烈 on 2021/1/17
|
||||
/// contact me by email 1981462002@qq.com
|
||||
/// 说明:
|
||||
|
||||
class CountDownWidget extends StatefulWidget {
|
||||
final VoidCallback onPress;
|
||||
|
||||
CountDownWidget({Key key, this.onPress}) : super(key: key);
|
||||
|
||||
@override
|
||||
_CountDownWidgetState createState() => _CountDownWidgetState();
|
||||
}
|
||||
|
||||
class _CountDownWidgetState extends State<CountDownWidget> {
|
||||
Timer timer;
|
||||
int count = 60;
|
||||
bool startTimer = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextButton(
|
||||
onPressed: startTimer?null:() {
|
||||
timer = Timer.periodic(Duration(seconds: 1), _update);
|
||||
setState(() {
|
||||
startTimer = true;
|
||||
});
|
||||
},
|
||||
child: Text(startTimer?'$count 秒后重试':'获取验证码'));
|
||||
}
|
||||
|
||||
void _update(Timer timer) {
|
||||
count--;
|
||||
if (count == 0) {
|
||||
timer.cancel();
|
||||
startTimer = false;
|
||||
count=5;
|
||||
}
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user