Flutter学习笔记--做一个App登录界面

学习Flutter近5天了,开始做一个App的入门项目,做一个登录界面:
会涉及到以下知识点:
各种Widget的使用包含Container、Text、Image等,MaterialPageRoute()的窗口调用等;效果如下(同时给学校和老师的公司打了个广告,不过没收钱,哈哈哈):在这里插入图片描述
好,现在就开始吧,首先介绍下我的程序架构:

所有的程序都在lib文件夹下:
在这里插入图片描述
其他的constants.dart文件为自定义的颜色存储:
在这里插入图片描述
必要说明:文件的头引用是我自己的文件名,大家调用的时候不要忘记换成自己的:
在这里插入图片描述

sizedBox是我用来调节摆放位置用的在这里插入图片描述

下面把各段代码奉上:

  1. main.dart:
import 'package:flutter/material.dart';
import 'package:llggflutter_app/Screens/Welcome/welcome_screen.dart';
import 'package:llggflutter_app/constants.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
    
    
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    
    
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Auth',
      theme: ThemeData(
        primaryColor: kPrimaryColor,
        scaffoldBackgroundColor: Colors.white,
      ),
      home: WelcomeScreen(),
    );
  }
}

2.welcome_screen.dart

import 'package:flutter/material.dart';
import 'package:llggflutter_app/Screens/Welcome/components/body.dart';

class WelcomeScreen extends StatelessWidget {
    
    
  @override
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      body: Body(),
    );
  }
}

3.constants.dart

import 'package:flutter/material.dart';

const kPrimaryColor = Color(0xFF6F35A5);
const kPrimaryLightColor = Color(0xFFF1E6FF);

  1. Welcome下的body.dart
import 'package:flutter/material.dart';
import 'package:llggflutter_app/Screens/Login/login_screen.dart';
import 'package:llggflutter_app/Screens/Welcome/components/background.dart';
import 'package:llggflutter_app/components/round_button.dart';
import 'package:llggflutter_app/constants.dart';
import 'package:flutter_screenutil/screenutil.dart';

class Body extends StatelessWidget {
    
    
  @override
  Widget build(BuildContext context) {
    
    
    Size size = MediaQuery.of(context).size; //屏幕的整体宽高尺寸
    return Background(
      //child: SingleChildScrollView()
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            "Welcome To SQD",
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
          SizedBox(height: size.height * 0.1),
          //Image.asset('images/SQDlogo.png'),
          //-SvgPicture.assets("assetsName")
          RoundeButton(
            text: "LOGIN",
            press: () {
    
    
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) {
    
    
                    return LoginScreen();
                  },
                ),
              );
            },
          ),
          RoundeButton(
            text: "SIGN UP",
            color: kPrimaryLightColor,
            textColor: Colors.black,
            press: () {
    
    
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) {
    
    
                    return LoginScreen();
                  },
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

  1. welcome下的background.dart
import 'package:flutter/material.dart';

class Background extends StatelessWidget {
    
    
  final Widget child;
  const Background({
    
    
    Key key,
    @required this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    Size size = MediaQuery.of(context).size;
    return Container(
      height: size.height,
      width: double.infinity,
      child: Stack(
        children: <Widget>[
          Positioned(
            top: 80,
            left: 130,
            child: Image.asset("lip/Screens/Images/top.png"),
            /*Image.network(
              'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3196884667,4151300997&fm=26&gp=0.jpg',
              width: size.width * 0.3,
            ),*/
          ),
          /* Positioned(
            bottom: 0,
            left: 0,
            child: Image.network(
              'https://images.pexels.com/photos/2127969/pexels-photo-2127969.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
              width: size.width * 0.3,
            ),
          ),*/
          child,
        ],
      ),
    );
  }
}

6.signup_screen.dart

import 'package:flutter/material.dart';

class SignUpScreen extends StatelessWidget {
    
    
  @override
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      body: Body(),
    );
  }
}

class Body extends StatelessWidget {
    
    
  @override
  Widget build(BuildContext context) {
    
    
    Size size = MediaQuery.of(context).size;
    return Container(
      height: size.height,
      width: double.infinity,
      child: Stack(
        alignment: Alignment.center,
        children: <Widget>[
          Positioned(
            top: 80,
            left: 35,
            child: Image.network(
              'http://cdn.cnbj1.fds.api.mi-img.com/mi-mall/b72c3b4d58f15c2f2053f11510e72116.jpg?w=800&h=532',
              width: size.width * 0.8,
            ),
          )
        ],
      ),
    );
  }
}

  1. login_screen.dart
import 'package:flutter/material.dart';
import 'package:llggflutter_app/Screens/Login/components/body.dart';

class LoginScreen extends StatelessWidget {
    
    
  @override
  Widget build(BuildContext context) {
    
    
    return Scaffold(
      body: Body(),
    );
  }
}

  1. Login文件下的body.dart
import 'package:flutter/material.dart';
import 'package:llggflutter_app/Screens/Login/components/background.dart';
import 'package:llggflutter_app/Screens/Signup/signup_screen.dart';
import 'package:llggflutter_app/components/already_have_an_account_acheck.dart';
import 'package:llggflutter_app/components/round_button.dart';
import 'package:llggflutter_app/components/round_input_field.dart';
import 'package:llggflutter_app/components/round_password_field.dart';
import 'package:llggflutter_app/components/text_field_container.dart';
import 'package:llggflutter_app/constants.dart';

class Body extends StatelessWidget {
    
    
  const Body({
    
    
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    Size size = MediaQuery.of(context).size;
    return

        ///Background(
        SingleChildScrollView(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          /* Text(
            "WELCOME LOGIN",
            textAlign: TextAlign.center,
            style: TextStyle(
              color: Colors.grey,
              fontWeight: FontWeight.bold,
            ),
          ),*/
          SizedBox(height: size.height * 0.3),
          RoundedInputField(
            hintText: "Your Email ",
            onChanged: (value) {
    
    },
          ),
          RoundedPassworldField(
            onChanged: (value) {
    
    },
          ),
          RoundeButton(
            text: "LOGIN",
            // color: kPrimaryLightColor,
            // textColor: Colors.black,
            press: () {
    
    
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) {
    
    
                    return SignUpScreen();
                  },
                ),
              );
            },
          ),
          // SizedBox(height: size.height * 0.1),
          AlreadyHaveAnAccountCheck(
            press: () {
    
    },
          ),
          SizedBox(height: size.height * 0.04),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                padding: EdgeInsets.all(20),
                decoration: BoxDecoration(
                  border: Border.all(),
                  shape: BoxShape.circle,
                ),
                child: Image.network(
                    'https://src.onlinedown.net/d/file/p/2019-08-06/2dc4d1b597725835d85259829db3fcff.jpg',
                    width: size.width * 0.1),
              )
            ],
          )
        ],
      ),
    );
  }
}

9.login文件下的background.dart

import 'package:flutter/material.dart';

class Background extends StatelessWidget {
    
    
  final Widget child;
  const Background({
    
    
    Key key,
    @required this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    Size size = MediaQuery.of(context).size;
    return Scaffold(
      body: Container(
        width: double.infinity,
        height: size.height,
        child: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Positioned(
                top: 0,
                left: 50,
                child: Image.network(
                  'http://www.smu-sqd.com/upload/img/201912120939063520.png',
                  width: size.width * 0.55,
                  height: size.height * 0.3,
                )
                xxxxx
                //"assets/images/SQDlogo.png",

                ),
            //child,
          ],
        ),
      ),
    );
  }
}

10.already_have_an_account_acheck.dart

import 'package:flutter/material.dart';
import 'package:llggflutter_app/constants.dart';

class AlreadyHaveAnAccountCheck extends StatelessWidget {
    
    
  final bool login;
  final Function press;
  const AlreadyHaveAnAccountCheck({
    
    
    Key key,
    this.login = true,
    this.press,
  }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    
    
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text(
          login ? "Don't have an Account?" : "Already have an Account?",
          style: TextStyle(color: kPrimaryColor),
        ),
        GestureDetector(
          onTap: press,
          child: Text(
            login ? "Sign Up" : "Sign In",
            style: TextStyle(
              color: kPrimaryColor,
              fontWeight: FontWeight.bold,
            ),
          ),
        )
      ],
    );
  }

// This widget is the root of your application.
}

11.round_button.dart

import 'package:flutter/material.dart';
import 'package:llggflutter_app/constants.dart';

class RoundeButton extends StatelessWidget {
    
    
  final String text;
  final Function press;
  final Color color, textColor;
  const RoundeButton({
    
    
    Key key,
    this.text,
    this.press,
    this.color = kPrimaryColor,
    this.textColor = Colors.white,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    
    
    Size size = MediaQuery.of(context).size;
    return Container(
      margin: EdgeInsets.symmetric(vertical: 10, horizontal: 50), //调节间距
      width: size.width * 0.8,
      child: ClipRRect(
        borderRadius: BorderRadius.circular(29),
        child: FlatButton(
          padding: EdgeInsets.symmetric(vertical: 20, horizontal: 40),
          color: color,
          onPressed: press,
          child: Text(
            text,
            style: TextStyle(color: textColor),
          ),
        ),
      ),
    );
  }
}

12.round_input_field.dart

扫描二维码关注公众号,回复: 12450804 查看本文章
import 'package:flutter/material.dart';
import 'package:llggflutter_app/components/text_field_container.dart';
import 'package:llggflutter_app/constants.dart';

class RoundedInputField extends StatelessWidget {
    
    
  final String hintText;
  final IconData icon;
  final ValueChanged<String> onChanged;
  const RoundedInputField({
    
    
    Key key,
    this.hintText,
    this.icon = Icons.person,
    this.onChanged,
    Color color,
  }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    
    
    return TextFieldContainer(
      child: TextField(
        onChanged: onChanged,
        decoration: InputDecoration(
            fillColor: Colors.black,
            icon: Icon(
              icon,
              color: Colors.blue,
            ),
            hintText: hintText,
            border: InputBorder.none),
      ),
    );
  }
}

13.round_password_field.dart

import 'package:flutter/material.dart';
import 'package:llggflutter_app/components/text_field_container.dart';
import 'package:llggflutter_app/constants.dart';

class RoundedPassworldField extends StatelessWidget {
    
    
  final ValueChanged<String> onChanged;
  const RoundedPassworldField({
    
    
    Key key,
    this.onChanged,
  }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    
    
    return TextFieldContainer(
      child: TextField(
        obscureText: true,
        onChanged: onChanged,
        decoration: InputDecoration(
          fillColor: Colors.red, //*** */
          hintText: "Password",
          icon: Icon(
            Icons.lock,
            color: Colors.blue,
          ),
          suffixIcon: Icon(
            Icons.visibility,
            color: Colors.blue,
          ),
          border: InputBorder.none,
        ),
      ),
    );
  }
}

14.text_field_container.dart

import 'package:flutter/material.dart';
import 'package:llggflutter_app/constants.dart';

class TextFieldContainer extends StatelessWidget {
    
    
  final Widget child;
  const TextFieldContainer({
    
    
    Key key,
    this.child,
  }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    
    
    Size size = MediaQuery.of(context).size;
    return Container(
      margin: EdgeInsets.symmetric(vertical: 10),
      padding: EdgeInsets.symmetric(horizontal: 20, vertical: 5),
      width: size.width * 0.8,
      decoration: BoxDecoration(
        color: Colors.grey,
        borderRadius: BorderRadius.circular(29),
      ),
      child: child,
    );
  }
}

a。ok,全部代码完毕,程序里的Image.network 后面的地址,大家换成自己的哈;
b。输入框中的安全线一样的东西是个bug:
在这里插入图片描述
大家可以将输入框与键盘隔开写距离,然后这个安全线会消失,或者使用SingleChildScrollView(),将排布的内容放进去,也会避免这个问题(这时候把background里的东西放到body中,要不然SingleChildScrollView()无法对图片进行排布)
c。下方的微信图标是画上去的,并没有引用,做做样子哈
在这里插入图片描述

关于第三方登录的实现有个github上的sharesdk包,大家可以找下哈。
添加链接描述

喜欢的朋友可以收藏或点个赞哈,或留言交流。大家一起学习呀。

猜你喜欢

转载自blog.csdn.net/qq_42434073/article/details/108085433
今日推荐