Created
February 17, 2019 23:15
-
-
Save pedromassango/96a4a1ef27e6f862cc1e2eebd7d7aa46 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'package:flutter/material.dart'; | |
| import 'package:flutter/services.dart'; | |
| void main() => runApp(MyApp()); | |
| class MyApp extends StatelessWidget { | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| title: 'Sliding Login', | |
| home: HomePage(), | |
| ); | |
| } | |
| } | |
| class HomePage extends StatefulWidget { | |
| @override | |
| HomePageState createState() { | |
| return HomePageState(); | |
| } | |
| } | |
| class HomePageState extends State<HomePage> | |
| with SingleTickerProviderStateMixin { | |
| bool isLogin = true; | |
| Animation<double> loginSize; | |
| AnimationController loginController; | |
| AnimatedOpacity opacityAnimation; | |
| Duration animationDuration = Duration(milliseconds: 270); | |
| @override | |
| void initState() { | |
| super.initState(); | |
| SystemChrome.setEnabledSystemUIOverlays([]); | |
| loginController = | |
| AnimationController(vsync: this, duration: animationDuration); | |
| opacityAnimation = | |
| AnimatedOpacity(opacity: 0.0, duration: animationDuration); | |
| } | |
| @override | |
| void dispose() { | |
| loginController.dispose(); | |
| super.dispose(); | |
| } | |
| Widget _buildLoginWidgets() { | |
| return Container( | |
| padding: EdgeInsets.only(bottom: 62, top: 16), | |
| width: MediaQuery.of(context).size.width, | |
| height: loginSize.value, | |
| decoration: BoxDecoration( | |
| color: Color(0XFF2a3ed7), | |
| borderRadius: BorderRadius.only( | |
| bottomLeft: Radius.circular(190), | |
| bottomRight: Radius.circular(190))), | |
| child: Align( | |
| alignment: Alignment.bottomCenter, | |
| child: AnimatedOpacity( | |
| opacity: loginController.value, | |
| duration: animationDuration, | |
| child: GestureDetector( | |
| onTap: isLogin ? null : () { | |
| loginController.reverse(); | |
| setState(() { | |
| isLogin = !isLogin; | |
| }); | |
| }, | |
| child: Container( | |
| child: Text( | |
| 'LOG IN'.toUpperCase(), | |
| style: TextStyle( | |
| fontSize: 32, | |
| fontWeight: FontWeight.bold, | |
| color: Colors.white), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ); | |
| } | |
| Widget _buildLoginComponents() { | |
| return Column( | |
| mainAxisSize: MainAxisSize.min, | |
| children: <Widget>[ | |
| Visibility( | |
| visible: isLogin, | |
| child: Padding( | |
| padding: const EdgeInsets.only(left: 42, right: 42), | |
| child: Column( | |
| children: <Widget>[ | |
| TextField( | |
| style: TextStyle(color: Colors.white, height: 0.5), | |
| decoration: InputDecoration( | |
| prefixIcon: Icon(Icons.email), | |
| hintText: 'Email', | |
| border: OutlineInputBorder( | |
| borderRadius: BorderRadius.all(Radius.circular(32)) | |
| ) | |
| ), | |
| ), | |
| Padding( | |
| padding: const EdgeInsets.only(top: 16), | |
| child: TextField( | |
| style: TextStyle(color: Colors.white, height: 0.5), | |
| decoration: InputDecoration( | |
| prefixIcon: Icon(Icons.vpn_key), | |
| hintText: 'Password', | |
| border: OutlineInputBorder( | |
| borderRadius: BorderRadius.all( | |
| Radius.circular(32)))), | |
| ), | |
| ), | |
| Container( | |
| width: 200, | |
| height: 40, | |
| margin: EdgeInsets.only(top: 32), | |
| decoration: BoxDecoration( | |
| color: Colors.white, | |
| borderRadius: BorderRadius.all(Radius.circular(50)) | |
| ), | |
| child: Center( | |
| child: Text( | |
| 'LOG IN', | |
| style: TextStyle(color: Color(0XFF2a3ed7), | |
| fontWeight: FontWeight.bold | |
| ), | |
| ), | |
| ), | |
| ) | |
| ], | |
| ), | |
| ), | |
| ), | |
| ], | |
| ); | |
| } | |
| Widget _buildRegistercomponents() { | |
| return Padding( | |
| padding: EdgeInsets.only( | |
| left: 42, | |
| right: 42, | |
| top: 32, | |
| bottom: 32 | |
| ), | |
| child: Column( | |
| mainAxisSize: MainAxisSize.min, | |
| children: <Widget>[ | |
| Padding( | |
| padding: const EdgeInsets.only(bottom: 32), | |
| child: Text( | |
| 'Sign Up'.toUpperCase(), | |
| style: TextStyle( | |
| fontSize: 32, | |
| fontWeight: FontWeight.bold, | |
| color: Color(0XFF2a3ed7)), | |
| ), | |
| ), | |
| TextField( | |
| style: TextStyle(color: Colors.black, height: 0.5), | |
| decoration: InputDecoration( | |
| prefixIcon: Icon( | |
| Icons.email, | |
| ), | |
| hintText: 'Email', | |
| border: OutlineInputBorder( | |
| borderRadius: BorderRadius.all(Radius.circular(32)))), | |
| ), | |
| Padding( | |
| padding: const EdgeInsets.only(bottom: 16, top: 16), | |
| child: TextField( | |
| style: TextStyle(color: Colors.black, height: 0.5), | |
| decoration: InputDecoration( | |
| prefixIcon: Icon(Icons.vpn_key), | |
| hintText: 'Password', | |
| border: OutlineInputBorder( | |
| borderRadius: BorderRadius.all(Radius.circular(32)))), | |
| ), | |
| ), | |
| TextField( | |
| style: TextStyle(color: Colors.black, height: 0.5), | |
| decoration: InputDecoration( | |
| prefixIcon: Icon(Icons.vpn_key), | |
| hintText: 'Confirm Password', | |
| border: OutlineInputBorder( | |
| borderRadius: BorderRadius.all(Radius.circular(32)))), | |
| ), | |
| Padding( | |
| padding: const EdgeInsets.only(top: 24), | |
| child: Container( | |
| width: 200, | |
| height: 40, | |
| margin: EdgeInsets.only(top: 32), | |
| decoration: BoxDecoration( | |
| color: Color(0XFF2a3ed7), | |
| borderRadius: BorderRadius.all(Radius.circular(50)) | |
| ), | |
| child: Center( | |
| child: Text( | |
| 'SIGN UP', | |
| style: TextStyle(color: Colors.white, | |
| fontWeight: FontWeight.bold | |
| ), | |
| ), | |
| ), | |
| ) , | |
| ) | |
| ], | |
| ), | |
| ); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| double _defaultLoginSize = MediaQuery.of(context).size.height / 1.6; | |
| loginSize = Tween<double>(begin: _defaultLoginSize, end: 200).animate( | |
| CurvedAnimation(parent: loginController, curve: Curves.linear)); | |
| return Scaffold( | |
| backgroundColor: Colors.white, | |
| body: Stack( | |
| children: <Widget>[ | |
| Align( | |
| alignment: Alignment.bottomCenter, | |
| child: AnimatedOpacity( | |
| opacity: isLogin ? 0.0 : 1.0, | |
| duration: animationDuration, | |
| child: Container(child: _buildRegistercomponents()), | |
| ), | |
| ), | |
| Align( | |
| alignment: Alignment.bottomCenter, | |
| child: Container( | |
| color: isLogin && !loginController.isAnimating ? Colors.white : Colors.transparent, | |
| width: MediaQuery.of(context).size.width, | |
| height: _defaultLoginSize/1.5, | |
| child: Visibility( | |
| visible: isLogin, | |
| child: GestureDetector( | |
| onTap: () { | |
| loginController.forward(); | |
| setState(() { | |
| isLogin = !isLogin; | |
| }); | |
| }, | |
| child: Center( | |
| child: Text( | |
| 'Sign Up'.toUpperCase(), | |
| style: TextStyle( | |
| fontSize: 32, | |
| fontWeight: FontWeight.bold, | |
| color: Color(0XFF2a3ed7), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| ), | |
| AnimatedBuilder( | |
| animation: loginController, | |
| builder: (context, child) { | |
| return _buildLoginWidgets(); | |
| }, | |
| ), | |
| Align( | |
| alignment: Alignment.topCenter, | |
| child: Container( | |
| width: MediaQuery.of(context).size.width, | |
| height: MediaQuery.of(context).size.height/2, | |
| child: Center(child: _buildLoginComponents()), | |
| ) | |
| ) | |
| ], | |
| ), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment