flutter学习三:实现登录界面,登录成功后跳转到首页,从我的界面退出登录

效果图依次如下:

               

                  

一步一步摸索、查找资源,最后实现登录界面,登录成功后跳转到首页,从我的界面退出登录,代码有相关的注释,完整代码如下:

1.main.dar

import 'package:flutter/material.dart';
import 'package:flutter_app/screen/Home.dart';
import 'package:flutter_app/screen/LoginScreen.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {

      return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),

      routes: {//命名导航路由,
        '/': (BuildContext context) => new LoginScreen(),
        '/Home': (BuildContext context) => new Home(),
        '/login': (BuildContext context) => new LoginScreen()
      }, 
     }
}  

2.1 LoginScreen.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class LoginScreen extends StatefulWidget {
  @override
  State<LoginScreen> createState() {
    return new _LoginScreenState();
  }
}

class _LoginScreenState extends State<LoginScreen> {
  static bool _accountState, _passwordState = false; //用于登录时判断输入的账号、密码是否符合要求
  static String _checkHint; //提示语
  static TextEditingController _accountController = new TextEditingController();
  static TextEditingController _passwordController =
      new TextEditingController();
  static BuildContext context1;

  //校验账号是否符合条件
  static void _checkAccount() {
    //校验账号不为空且长度大于7(自定义校验条件)
    if (_accountController.text.isNotEmpty &&
        _accountController.text.trim().length > 7) {
      _accountState = true;
    } else {
      _accountState = false;
    }
  }

  //校验密码是否符合条件
  static void _checkPassword() {
    //校验密码不为空且长度大于8小于等于15(自定义校验条件)
    if (_passwordController.text.isNotEmpty &&
        _passwordController.text.length > 8 &&
        _passwordController.text.length <= 15) {
      _passwordState = true;
    } else {
      _passwordState = false;
    }
  }

  //账号输入框样式
  static Widget buildAccountTextFied(TextEditingController controller) {
    /**
     *需要定制一下某些颜色时返回Theme,不需要时返回TextField(如后面的密码)
     * 修改输入框颜色:没有获取焦点时为hintColor,获取焦点后为:primaryColor
     */
    return Theme(
      data: new ThemeData(
          primaryColor: Colors.amber, hintColor: Colors.greenAccent),
      child: new TextField(
        controller: controller,
        //最大长度
        maxLength: 30,
        //颜色跟hintColor
        //最大行数
        maxLines: 1,
        //是否自动更正
        autocorrect: true,
        //是否自动化对焦
        autofocus: false,
        //是否是密码格式(输入的内容不可见)
        obscureText: false,
        //文本对齐方式
        textAlign: TextAlign.start,
        //输入文本的样式
        style: TextStyle(fontSize: 20, color: Colors.black),
        //允许输入的格式(digitsOnly数字)
        inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
        //内容改变回调
        onChanged: (account) {
          print('change $account');
        },
        onSubmitted: (account) {
          print('submit $account');
        },
        //是否禁用
        enabled: true,
        decoration: InputDecoration(
            fillColor: Colors.blue[50],
            //底色
            filled: true,
            //有聚焦,labelText就会缩小到输入框左上角,颜色primaryColor,没聚焦前颜色跟hintColor
            labelText: '账号',
            //聚焦时才显示,颜色跟hintColor
            hintText: '请输入账号',
            //红色
//          errorText: '输入错误',
            //红色,现在在输入框的左下角,跟errorText位置一样(优先显示errorText)
//          helperText: 'acount',
            //有聚焦,颜色跟primaryColor
            prefixIcon: Icon(Icons.person),
            //有聚焦显示颜色跟hintColor,显示在输入框的右边
//          suffixText: '右边',
            contentPadding: EdgeInsets.all(5),
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(21.11), //边框裁剪成11.11°角
              borderSide: BorderSide(
                  color: Colors.black,
                  width: 25.0), //边框颜色、大小没有效果,所以使用返回的是Theme,
            )),
      ),
    );
  }

  //密码输入框样式
  static Widget buildPasswordTextFied(TextEditingController controller) {
    return TextField(
      controller: controller,
      //最大长度
      maxLength: 30,
      //颜色跟hintColor
      //最大行数
      maxLines: 1,
      //是否自动更正
      autocorrect: true,
      //是否自动化对焦
      autofocus: false,
      //是否是密码格式(输入的内容不可见)
      obscureText: true,
      //文本对齐方式
      textAlign: TextAlign.start,
      //输入文本的样式
      style: TextStyle(fontSize: 20, color: Colors.black),
      //允许输入的格式(digitsOnly数字)
      inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
      //内容改变回调
      onChanged: (password) {
        print('change $password');
      },
      onSubmitted: (password) {
        print('submit $password');
      },
      //是否禁用
      enabled: true,
      decoration: InputDecoration(
          fillColor: Colors.blue[50],
          //底色
          filled: true,
          //输入聚焦以后,labelText就会缩小到输入框左上角,红色,没聚焦前颜色跟hintColor
          labelText: '密码',
          //聚焦时才显示,颜色跟hintColor
          hintText: '请输入密码',
          //红色
//          errorText: '输入错误',
          //红色,现在在输入框的左下角,跟errorText位置一样(优先显示errorText)
//          helperText: 'acount',
          //输入聚焦时,颜色跟primaryColor
          prefixIcon: Icon(Icons.lock),
          //聚焦时才显示颜色跟hintColor,显示在输入框的右边
//          suffixText: '右边',
          contentPadding: EdgeInsets.all(5),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(21.11), //边框裁剪成11.11°角
            borderSide: BorderSide(
                color: Colors.black, width: 25.0), //没有效果,想要修改就返回Theme(如前面账号样式)
          )),
    );
  }

  Widget textSection = new Container(
    padding: const EdgeInsets.all(32.0),
    child: new Column(
      mainAxisSize: MainAxisSize.max,
      //MainAxisAlignment:主轴方向上的对齐方式,会对child的位置起作用
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        buildAccountTextFied(_accountController),
        buildPasswordTextFied(_passwordController),
      ],
    ),
  );

  Widget loginButton = new Container(
      margin: const EdgeInsets.only(left: 35, right: 35),
      child: new SizedBox(
          //用来设置宽高,如直接使用RaisedButton则不能设置
          height: 50,
          child: new RaisedButton(
              color: Colors.red,
              child: new Text(
                '登录',
                style: TextStyle(color: Colors.white, fontSize: 20),
              ),
              onPressed: () {
                _checkAccount();
                _checkPassword();
                if (_accountState) {
                  if (_passwordState) {
                    _checkHint =
                        '恭喜账号:' + _accountController.text.toString() + "登录成功";
                  } else {
                    _checkHint = '请输入8~15位密码!';
                  }
                } else {
                  _checkHint = '请输入不低于7位账号!';
                }
                showDialog(
                  context: context1,
                  barrierDismissible: true, //点击弹窗外部是否消失
                  child: new AlertDialog(
                    title: new Text(
                      '提示',
                      style:
                          new TextStyle(color: Colors.red[300], fontSize: 18),
                    ),
                    content: new Text(_checkHint),
                    actions: <Widget>[
                      new FlatButton(
                          onPressed: () {
                            Navigator.of(context1).pop();
                          },
                          child: Text('取消')),
                      new FlatButton(
                          //对话框按钮
                          onPressed: () {
                            if (_accountState && _passwordState) {
                              Navigator.pushNamed(
                                  context1, '/Home'); //跳转到main.dart命名路由对应的界面
                            } else {
                              Navigator.of(context1).pop();
                            }
                          },
                          child: Text('确定')),
                    ],
                  ),
                );
              })));

  @override
  Widget build(BuildContext context) {
    context1 = context;
    return Scaffold(
        appBar: new AppBar(
          title: new Text('登录'),
        ),
        body: new ListView(
          children: [
            new Image.asset(
              'images/lake.jpg',
              width: 600,
              height: 240,
              //cover(充满容器)、fill(充满父容器)、contain(总有宽或高跟父一样)、none(原图居中显示)、fitWidth(宽度跟父一样)、fitHeight(高度跟父一样)
              fit: BoxFit.contain,
            ),
            textSection,
            loginButton,
          ],
        ));
  }
}

2.2图片资源的添加

  • 根目录建立images文件夹,把准备好的lake.jpg图片放进去,如下图

  • pubspec.yaml,增加的图片资源,需要加进去,如下:
    flutter:
      assets:
        - images/lake.jpg

3.Home.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/screen/HomePage.dart';
import 'package:flutter_app/screen/MineScreen.dart';


class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new _HomeState();
  }
}

class _HomeState extends State<Home> {
  int _currentIndex = 0;
  final List<Widget> _children = [
    new HomeScreen(),//首页界面
    new MineScreen(),//我的界面
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _children[_currentIndex],
      bottomNavigationBar: new BottomNavigationBar(
        onTap: onTabTapped, //点击切换
        currentIndex: _currentIndex,
        items: [
          new BottomNavigationBarItem(
            icon: new Icon(Icons.home),
            title: new Text('首页'),
          ),
          new BottomNavigationBarItem(
            icon: new Icon(Icons.person),
            title: new Text('我的'),
          ),
        ],
      ),
    );
  }

  void onTabTapped(int index) {
    setState(() {
      _currentIndex = index;
    });
  }
}

4.HomeScreen.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('首页'),
      ),
      body: new Center(
        child: new Text(
            '我是Home界面',
          style: TextStyle(color: Colors.red, fontSize: 20),
        )
      ),
    );
  }
}

5.MineScreen.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class MineScreen extends StatelessWidget {
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('我的'),
      ),
      body: new Center(
        child: new RaisedButton(
            child: new Text('退出登录'),
            onPressed: () {
              Navigator.of(context).pushNamed('/login');//跳转到main.dart命名路由对应的界面
            }),
      ),
    );
  }
}

上一篇:flutter学习二:亲测实现官网构建布局第一个例子完整代码 

发布了64 篇原创文章 · 获赞 11 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_40420578/article/details/103993656
今日推荐