Flutter----登陆页面的简单demon

效果图
在这里插入图片描述
功能
1.打开页面的时候默认读取上次的用户信息,把用户名密码显示出来。
2.当用户名改变后,密码自动清空。
3:输入用户名按下键盘的回车按键,能够根据用户名进行查询对应的仓库,仓库下拉框默认选中第一条记录。
4.当查询到仓库后,光标自动从用户名那边跳转到密码框。
5.点击登陆按钮,判断是否内容都不为空,然后访问服务端验证用户名密码是否正确,正确的情况下查询用户的权限,并且记录用户名和密码。然后跳转到主页。

以下是主要的俩个页面。Global是一个存全局变量的一个类,而Services就是一个统一管网络访问的一个类,主要功能就是访问对应的接口,并返回查询到的数据。数据类型是BaseResult

mian.dart

import 'package:flutter/material.dart';
import 'home.dart';
import 'login.dart';


void main() {
  runApp(MyApp());

}

class MyApp extends StatelessWidget { //整个APP的设置
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      initialRoute: "login" ,//设置默认的首页面(对本app而言,是登陆页)
      theme: ThemeData(
        primarySwatch: Colors.blue, //设置主题为蓝色
      ),

      //在路由表注册路由,对应的字符对应哪个route
      routes: {"login":(context)=> LoginRoute(),
        "home":(context)=>HomeRoute()
      },
    );
  }
}

login.dart

import 'dart:collection';
import 'package:app_flutter/common/obj_util.dart';
import 'package:app_flutter/models/userinfo.dart';
import 'package:app_flutter/models/warehouse.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'common/global.dart';
import 'common/services.dart';
import 'models/function_obj.dart';

class LoginRoute extends StatefulWidget{
  const LoginRoute({Key? key}) : super(key: key);

  @override
  State<LoginRoute> createState() =>_LoginRouteState();
}

class _LoginRouteState extends State<LoginRoute>{

  //输入框控制器
  late TextEditingController _userController;
  late TextEditingController _passwordController;
  FocusNode _passwordFocusNode=FocusNode();
  String userId="";
  String? dropdownValue=null;
  List<WareHouse>? wareList= <WareHouse>[];
   //根据用户名去获取仓库
  void _getWareHouse(String userId) async {
    //获取查询结果
    var _params=LinkedHashMap<String,dynamic>();
    _params['userId']=userId;
    _params['methodName']='getWareHouse';
    var _result =await Services.getWarehouse(_params);

    if(_result.code==Global.SUCCESS){
      setState(() {
          wareList=_result.data;
          dropdownValue=wareList?[0].warehouseId;
          FocusScope.of(context).requestFocus(_passwordFocusNode);
      });
    }else{
       Global.showCenterCodeToast(_result.code,_result.msg);
    }
  }

  //根据用户和密码进行登陆
  void _login() async{
    var _params=LinkedHashMap<String,dynamic>();

    if(_userController.text.isEmpty){//如果用户为空
      Global.showCenterToast("请输入账号");
    }else if(_passwordController.text.isEmpty){
      Global.showCenterToast("请输入密码");
    }else if(ObjUtil.isEmpty(dropdownValue)){
      Global.showCenterToast("请选择仓库");
    }

    _params['userId']=_userController.text;
    _params['password']=_passwordController.text;
    _params['methodName']='doLogin';
    var _result =await Services.doLogin(_params);
    if(_result.code==Global.SUCCESS) {//查询成功了

      UserInfo? _userInfo=_result.data?[0];

      //存到持久化里面去 下次登陆可以用
      SharedPreferences _prefs = await SharedPreferences.getInstance();
      _prefs.setString('userId', _userInfo?.userId??'');
      _prefs.setString('password',_passwordController.text);
      Global.roleId=_userInfo?.roleId??'';
      Global.userId=_userController.text;
      Global.warehouseId=dropdownValue??'';
      _getFunction();
    }else{//失败
       Global.showCenterCodeToast(_result.code,_result.msg);
    }

  }

   //获取权限
  void _getFunction() async{
    var _result =await Services.getFunction({'methodName':'getFunction','userID':_userController.text});
    if(_result.code==Global.SUCCESS) { //查询成功了
      List<FunctionObj>? _functionList=_result.data;
       _functionList?.forEach((element) {
       Global.functionMap.addAll(element.toJson());//赋值给全局变量 之后可以用
      });
      Navigator.pushNamed(context, "home");
    }else{
      Global.showCenterCodeToast(_result.code,_result.msg);
    }
  }


  @override
  void initState() {
    super.initState();
    _userController = TextEditingController();
    _userController.addListener(() {
      userId=_userController.text;
    });
    _passwordController = TextEditingController();
  }

  @override
  void dispose() {
    _userController.dispose();
    _passwordController.dispose();
    super.dispose();
  }



  @override
  Widget build(BuildContext context) {

    //该界面输入框的外框样式(用户框,密码框)
    final  OutlineInputBorder outlineInputBorder=  OutlineInputBorder(borderRadius:  BorderRadius.circular(40.0),borderSide: BorderSide(
        color: Color(0xFFFFFFFF)
    ) );


    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: ConstrainedBox(
        constraints: BoxConstraints(
            minWidth:double.infinity,
            minHeight: double.infinity
        ),
        child: DecoratedBox(
            decoration: BoxDecoration(
              image: DecorationImage(
                  fit: BoxFit.fill ,
                  image: AssetImage("images/bg.jpg")
              ),
            ),
            child:Column(
              children: [
                Expanded( // 1/3空间
                  flex: 1,
                  child: Center(
                    child: Image.asset('images/hzlogo.png'),
                  ),
                ),
                Expanded( // 1/3空间
                  flex: 1,
                  child: Column(
                    children: [
                      Padding(
                          padding:EdgeInsets.symmetric(vertical: 2.0,horizontal: 30.0),
                          child:  TextField(
                            controller: _userController,
                            onChanged:(String value)=> {
                            setState( () {
                            wareList=<WareHouse>[];
                            dropdownValue=null;
                            })
                            } ,
                            onSubmitted: (String value)=>_getWareHouse(value),
                            autofocus:true,
                            decoration: InputDecoration(
                                border: outlineInputBorder,
                                focusedBorder: outlineInputBorder,
                                enabledBorder: outlineInputBorder,
                                fillColor:Colors.white ,
                                filled: true,
                                hintText: "用户名",
                                prefixIcon: Icon(Icons.person)
                            ),
                          ),
                      )
                      ,
                      Padding(
                        padding: EdgeInsets.symmetric(vertical: 2.0,horizontal: 30.0),
                        child: TextField(
                          controller: _passwordController,
                          cursorRadius: Radius.circular(20.0),
                          obscureText: true,
                          autofocus:true ,
                          focusNode: _passwordFocusNode,
                          decoration: InputDecoration(
                            border: outlineInputBorder,
                            focusedBorder: outlineInputBorder,
                            enabledBorder: outlineInputBorder,
                            fillColor:Colors.white ,
                            filled: true,
                            hintText: "密码",
                            prefixIcon: Icon(Icons.lock),
                          ),
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.symmetric(vertical: 2.0,horizontal: 30.0),
                        child:DecoratedBox(
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(40.0),
                            shape: BoxShape.rectangle,
                            color: Colors.white
                          ),
                          child: ConstrainedBox(
                            constraints:BoxConstraints(minWidth: double.infinity,minHeight: 60.0) ,
                            child: Padding(
                              padding: EdgeInsets.fromLTRB(46.0, 12.0, 40.0, 0.0),
                              child: DropdownButton<String>(
                                value:dropdownValue,
                                icon: const Icon(Icons.arrow_downward,color: Colors.black,),
                                iconSize: 24,
                                style: const TextStyle(color: Colors.black,
                                  fontSize: 16.0
                                ),
                                underline:Container(
                                  height: 0,
                                  color: Colors.deepPurpleAccent,
                                ) ,
                                onChanged: (String? newValue) {
                                  setState(() {
                                    print(newValue);
                                    dropdownValue = newValue!;
                                  });
                                },
                                items: wareList?.map<DropdownMenuItem<String>>((WareHouse value) {
                                  return DropdownMenuItem<String>(
                                    value: value.warehouseId,
                                    child: Text(value.warehouseId),
                                  );
                                }).toList(),
                              ),
                            )
                        )

                      )
                      ),
                      Padding(
                        padding: EdgeInsets.symmetric(vertical: 6.0),
                        child:ElevatedButton(
                          onPressed: _login,
                          style:ButtonStyle(
                            minimumSize: MaterialStateProperty.all<Size>(Size(150.0, 50.0)),
                            //背景色
                            backgroundColor: MaterialStateProperty.all<Color>(Colors.blueAccent),
                            //前景色 字体颜色
                            foregroundColor:MaterialStateProperty.all<Color>(Colors.white),
                            textStyle: MaterialStateProperty.all<TextStyle>(TextStyle(fontSize: 20.0)),
                            shape: MaterialStateProperty.all<OutlinedBorder>(RoundedRectangleBorder(borderRadius: BorderRadius.circular(40.0))),
                          ),
                          child: Text("登陆"),
                        ) ,)

                    ],
                  ),
                ),
                Expanded( // 1/3空间
                  flex: 1,
                  child: Row(

                  ),
                ),
              ],
            )
        ),import 'dart:collection';
import 'package:app_flutter/common/obj_util.dart';
import 'package:app_flutter/models/userinfo.dart';
import 'package:app_flutter/models/warehouse.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'common/global.dart';
import 'common/services.dart';
import 'models/function_obj.dart';

class LoginRoute extends StatefulWidget{
  const LoginRoute({Key? key}) : super(key: key);

  @override
  State<LoginRoute> createState() =>_LoginRouteState();
}

class _LoginRouteState extends State<LoginRoute>{

  //输入框控制器
  late TextEditingController _userController;
  late TextEditingController _passwordController;
  FocusNode _passwordFocusNode=FocusNode();
  String userId="";
  String password="";
  String? dropdownValue=null;
  List<WareHouse>? wareList= <WareHouse>[];


  //获取上次的登陆信息
  void _getLastUserInfo() async{
    SharedPreferences _prefs = await SharedPreferences.getInstance();
    userId= _prefs.get("userId")?.toString() ??"";
    password=_prefs.get("password")?.toString()  ??"";
    _userController.text=userId;
    _userController.selection=new TextSelection(baseOffset: 0, extentOffset: userId.length);
    _passwordController.text=password;

  }





   //根据用户名去获取仓库
  void _getWareHouse(String userId) async {
    //获取查询结果
    var _params=LinkedHashMap<String,dynamic>();
    _params['userId']=userId;
    _params['methodName']='getWareHouse';
    var _result =await Services.getWarehouse(_params);

    if(_result.code==Global.SUCCESS){
      setState(() {
          wareList=_result.data;
          dropdownValue=wareList?[0].warehouseId;
          FocusScope.of(context).requestFocus(_passwordFocusNode);
      });
    }else{
       Global.showCenterCodeToast(_result.code,_result.msg);
    }
  }

  //根据用户和密码进行登陆
  void _login() async{
    var _params=LinkedHashMap<String,dynamic>();

    if(_userController.text.isEmpty){//如果用户为空
      Global.showCenterToast("请输入账号");
    }else if(_passwordController.text.isEmpty){
      Global.showCenterToast("请输入密码");
    }else if(ObjUtil.isEmpty(dropdownValue)){
      Global.showCenterToast("请选择仓库");
    }

    _params['userId']=userId;
    _params['password']=_passwordController.text;
    _params['methodName']='doLogin';
    var _result =await Services.doLogin(_params);
    if(_result.code==Global.SUCCESS) {//查询成功了

      UserInfo? _userInfo=_result.data?[0];

      //存到持久化里面去 下次登陆可以用
      SharedPreferences _prefs = await SharedPreferences.getInstance();
      _prefs.setString('userId', _userInfo?.userId??'');
      _prefs.setString('password',_passwordController.text);
      Global.roleId=_userInfo?.roleId??'';
      Global.userId=userId;
      Global.warehouseId=dropdownValue??'';
      _getFunction();
    }else{//失败
       Global.showCenterCodeToast(_result.code,_result.msg);
    }

  }

   //获取权限
  void _getFunction() async{
    var _result =await Services.getFunction({'methodName':'getFunction','userID':userId});
    if(_result.code==Global.SUCCESS) { //查询成功了
      List<FunctionObj>? _functionList=_result.data;
       _functionList?.forEach((element) {
       Global.functionMap.addAll(element.toJson());//赋值给全局变量 之后可以用
      });
      Navigator.pushNamed(context, "home");
    }else{
      Global.showCenterCodeToast(_result.code,_result.msg);
    }
  }


  @override
  void initState() {
    super.initState();

    _userController = TextEditingController();
    _passwordController = TextEditingController();
    _userController.addListener(() {
      userId=_userController.text;
    });
    _getLastUserInfo();
  }

  @override
  void dispose() {
    _userController.dispose();
    _passwordController.dispose();
    super.dispose();
  }



  @override
  Widget build(BuildContext context) {

    //该界面输入框的外框样式(用户框,密码框)
    final  OutlineInputBorder outlineInputBorder=  OutlineInputBorder(borderRadius:  BorderRadius.circular(40.0),borderSide: BorderSide(
        color: Color(0xFFFFFFFF)
    ) );


    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: ConstrainedBox(
        constraints: BoxConstraints(
            minWidth:double.infinity,
            minHeight: double.infinity
        ),
        child: DecoratedBox(
            decoration: BoxDecoration(
              image: DecorationImage(
                  fit: BoxFit.fill ,
                  image: AssetImage("images/bg.jpg")
              ),
            ),
            child:Column(
              children: [
                Expanded( // 1/3空间
                  flex: 1,
                  child: Center(
                    child: Image.asset('images/hzlogo.png'),
                  ),
                ),
                Expanded( // 1/3空间
                  flex: 1,
                  child: Column(
                    children: [
                      Padding(
                          padding:EdgeInsets.symmetric(vertical: 2.0,horizontal: 30.0),
                          child:  TextField(
                            controller: _userController,
                            onChanged:(String value)=> {
                            setState( () {
                            wareList=<WareHouse>[];
                            dropdownValue=null;
                            _passwordController.clear();
                            })
                            } ,
                            onSubmitted: (String value)=>_getWareHouse(value),
                            autofocus:true,
                            decoration: InputDecoration(
                                border: outlineInputBorder,
                                focusedBorder: outlineInputBorder,
                                enabledBorder: outlineInputBorder,
                                fillColor:Colors.white ,
                                filled: true,
                                hintText: "用户名",
                                prefixIcon: Icon(Icons.person)
                            ),
                          ),
                      )
                      ,
                      Padding(
                        padding: EdgeInsets.symmetric(vertical: 2.0,horizontal: 30.0),
                        child: TextField(
                          controller: _passwordController,
                          cursorRadius: Radius.circular(20.0),
                          obscureText: true,
                          autofocus:true ,
                          focusNode: _passwordFocusNode,
                          decoration: InputDecoration(
                            border: outlineInputBorder,
                            focusedBorder: outlineInputBorder,
                            enabledBorder: outlineInputBorder,
                            fillColor:Colors.white ,
                            filled: true,
                            hintText: "密码",
                            prefixIcon: Icon(Icons.lock),
                          ),
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.symmetric(vertical: 2.0,horizontal: 30.0),
                        child:DecoratedBox(
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(40.0),
                            shape: BoxShape.rectangle,
                            color: Colors.white
                          ),
                          child: ConstrainedBox(
                            constraints:BoxConstraints(minWidth: double.infinity,minHeight: 60.0) ,
                            child: Padding(
                              padding: EdgeInsets.fromLTRB(46.0, 12.0, 40.0, 0.0),
                              child: DropdownButton<String>(
                                value:dropdownValue,
                                icon: const Icon(Icons.arrow_downward,color: Colors.black,),
                                iconSize: 24,
                                style: const TextStyle(color: Colors.black,
                                  fontSize: 16.0
                                ),
                                underline:Container(
                                  height: 0,
                                  color: Colors.deepPurpleAccent,
                                ) ,
                                onChanged: (String? newValue) {
                                  setState(() {
                                    print(newValue);
                                    dropdownValue = newValue!;
                                  });
                                },
                                items: wareList?.map<DropdownMenuItem<String>>((WareHouse value) {
                                  return DropdownMenuItem<String>(
                                    value: value.warehouseId,
                                    child: Text(value.warehouseId),
                                  );
                                }).toList(),
                              ),
                            )
                        )

                      )
                      ),
                      Padding(
                        padding: EdgeInsets.symmetric(vertical: 6.0),
                        child:ElevatedButton(
                          onPressed: _login,
                          style:ButtonStyle(
                            minimumSize: MaterialStateProperty.all<Size>(Size(150.0, 50.0)),
                            //背景色
                            backgroundColor: MaterialStateProperty.all<Color>(Colors.blueAccent),
                            //前景色 字体颜色
                            foregroundColor:MaterialStateProperty.all<Color>(Colors.white),
                            textStyle: MaterialStateProperty.all<TextStyle>(TextStyle(fontSize: 20.0)),
                            shape: MaterialStateProperty.all<OutlinedBorder>(RoundedRectangleBorder(borderRadius: BorderRadius.circular(40.0))),
                          ),
                          child: Text("登陆"),
                        ) ,)

                    ],
                  ),
                ),
                Expanded( // 1/3空间
                  flex: 1,
                  child: Row(

                  ),
                ),
              ],
            )
        ),
      )
    );

  }







}

BaseResult是用来接收所有返回结果的。主要是code 代码,msg 详细信息,data就是查询的结果。futter中泛型的使用方法https://blog.csdn.net/K_Hello/article/details/115525018

import 'package:json_annotation/json_annotation.dart';
part 'bas_result.g.dart';
@JsonSerializable(genericArgumentFactories: true)
class BaseResult<T>{
  int code;
  String msg;
  List<T>? data;
  BaseResult(this.code,this.msg,this.data);
  factory BaseResult.fromJson(Map<String, dynamic> json, T Function(dynamic json) fromJsonT) => _$BaseResultFromJson(json, fromJsonT);

  Map<String, dynamic> toJson(Object? Function(T value) toJsonT) =>
      _$BaseResultToJson(this, toJsonT);
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值