Flutter 实现自动登录

前言:

在原生的andriod 和iOS app里面都会有自动登录的功能 今天我就用flutter 来给大家实现双端的自动登录功能 Android 端用的是 Sharedpreferences 来实现对于轻量级数据的缓存 , IOS端 通常使用NSUserDefaults 来实现轻量级数据的缓存
但是在flutter 有基于Android iOS 做支持的三方插件库 shared_preferences

  • 1准备工作

需要用的三方库

shared_preferences: ^0.5.3+4 (缓存数据)
dio: 2.1.0 (网络请求)
toast: ^0.1.5 (吐司文字类比 Android里面的toast)


image

在项目里面的pubspec.yaml 添加依赖 然后在项目根目录打开控制台输入 flutter pub get 命令回去下载相对应的依赖

  • 2具体实现

先实现登录界面的功能

image

登录页面是两个输入框TextFiled 和一个RaisedButton 来实现请求后台来处理登录功能
通过Dio库来实现异步网络请求 然后 通过 factory BackBean.fromJson 来转换成对象
在登录成功后通过 SharedPreferences 来储存数据 如下图所示 在登录成功后调用sharedPreferences.setString ()方法来存数据


image

下面是登录页面的具体实现

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:dio/dio.dart';
import 'tabs/Api.dart';
import 'entity/BackBean.dart';
import 'utils/ToastUtil.dart';
import 'Register.dart';
import 'My.dart';
/**

* 创建人:xuqing

* 创建时间:2019年12月22日19:28:56

* 类说明: 登录页面  业务需求通过 dio 网络请求库 和 shared_preferences  数据缓存库 来实现自动登录功能*

*/

class Loginextends StatefulWidget {

  Login({Key key}) :super(key: key);

    @override

      _LoginStatecreateState() {

      return _LoginState();

  }

}

class _LoginStateextends State {

    @override

      void initState() {

      super.initState();

  }

  @override

    void dispose() {

  super.dispose();

  }

  @override

  Widgetbuild(BuildContext context) {

// TODO: implement build

    return Scaffold(

        appBar:AppBar(

        title:Text("登录"), ),

       body:Layout(),

    );

  }

}

class Layoutextends StatefulWidget {

Layout({Key key}) :super(key: key);

  @override

  _LayoutStatecreateState() {

    return _LayoutState();

  }

}

class _LayoutStateextends State {

    var _username="";

    var _password="";

    @override

  void initState() {

  super.initState();

  }

@override

  void dispose() {

  super.dispose();

}

@override

  Widgetbuild(BuildContext context) {

// TODO: implement build

    return Column(

        children: [

          TextField(

          obscureText:false,

            decoration:InputDecoration(

            hintText:"请输入账号",

            ),

            onChanged: (value){

        setState(() {

        this._username=value;

         });

       },

  ),

  SizedBox(height:20,),

       TextField(

      obscureText:true,

      decoration:InputDecoration(

      hintText:"请输入密码",

          ),

          onChanged: (value){

        setState(() {

    this._password=value;

          });  

},

),

Container(

          width:300,

          child:RaisedButton(

          child:Text("登录"),

            color: Colors.blue,

            onPressed: ()async{

            Dio dio =new Dio();

              Response res=await  dio.get(Api.LOGIN_URL,

                  queryParameters: {"username":_username,

                    "password":_password});

              BackBean _backbean=BackBean.fromJson(res.data);

              String getmsg=_backbean.msg;

              int  getcode=_backbean.code;

              print(getmsg);

              print(getcode);

              if(getcode==200){

              //  print("登录成功");

                SharedPreferences sharedPreferences =await SharedPreferences.getInstance();

                sharedPreferences.setString('username', _username);

                sharedPreferences.setString('password', _password);

                ToastUtil.showinfo(context, getmsg);

                Navigator.of(context).push(

            new MaterialPageRoute(builder: (context) {

              //指定跳转的页面

                      return new My();

          },)

      );

  }else{

      ToastUtil.showinfo(context, getmsg);

    }

    print(res.data.toString());

       },

    ),

   ),

        RaisedButton(

    child:Text("注册账号"),

          color: Colors.red,

          textColor: Colors.white,

          onPressed: (){

    Navigator.of(context).push(

    new MaterialPageRoute(builder: (context) {

      //指定跳转的页面

                  return new Register();

                },)

      ) }, )],

    );  }

}

欢迎页(闪屏页面)的具体实现

image
image

在initState 初始化生命周期方法里面 我们做一个3秒钟的倒计时 3秒钟 后我们调用toLogin方法 在login方法里面 我们 做了处理 调用

sharedPreferences.getString('password');来读取缓存的里面的数据 做空判 如果没有缓存数据我们就去登陆页面 如果有数据我们之间调用

登陆接口 进行自动登录操作 登录完成后我们直接跳转到主页 欢迎页的具体代码实现 如下

image

具体代码 (欢迎页面)


import 'package:flutter/material.dart';

import 'Login.dart';

import 'package:shared_preferences/shared_preferences.dart';

import 'package:dio/dio.dart';

import 'utils/StingUtil.dart';

import 'tabs/Api.dart';

import 'entity/BackBean.dart';

import 'utils/ToastUtil.dart';

import 'dart:async';

import 'My.dart';

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

class MyAppextends StatelessWidget {

// This widget is the root of your application.

  @override

  Widgetbuild(BuildContext context) {

return MaterialApp(

    home:Scaffold(

    appBar:AppBar(

  title:Text("欢迎页"),  ),

   body:MyHomePage(),  )

      );

    }

}

/**

*

* 欢迎页面*

*/

class MyHomePageextends StatefulWidget {

MyHomePage({Key key}) :super(key: key);

  @override

  _MyHomePageStatecreateState() {

return _MyHomePageState();

  }

}

class _MyHomePageStateextends State {

var _getaname="";

  var  _getpsw="";

  @override

  void initState() {

super.initState();

    int count =0;

    const period =const Duration(seconds:1);

    print('currentTime='+DateTime.now().toString());

    Timer.periodic(period, (timer) {

//到时回调

      print('afterTimer='+DateTime.now().toString());

      count++;

      if (count >=3) {

//取消定时器,避免无限回调

        timer.cancel();

        timer =null;

        toLoing();

      }

});

  }

@override

  void dispose() {

super.dispose();

  }

void  toLoing()async{

SharedPreferences sharedPreferences =await SharedPreferences.getInstance();

    _getaname = sharedPreferences.getString('username');

    _getpsw = sharedPreferences.getString('password');

    if(!StringUtil.isEmpty(_getaname)&&!StringUtil.isEmpty(_getpsw)){

Dio dio =new Dio();

      Response res=await dio.get(Api.LOGIN_URL, queryParameters: {"username":_getaname, "password":_getpsw});

      BackBean _backbean=BackBean.fromJson(res.data);

      String getmsg=_backbean.msg;

      int  getcode=_backbean.code;

      if(getcode==200){

ToastUtil.showinfo(context, getmsg);

        Navigator.of(context).push(

new MaterialPageRoute(builder: (context) {

return new My();

            },)

);

      }

}else{

Navigator.of(context).push(

new MaterialPageRoute(builder: (context) {

return new Login ();

          },)  );

    }

}

@override

  Widgetbuild(BuildContext context) {

// TODO: implement build

    return  Container(

    child:Image.network("http://pic1.win4000.com/mobile/2019-05-31/5cf0dd648a143.jpg"),

    );

  }

}

其他你自己要跳转的主页 可以自己去拓展 这个demo的请求接口是自己用spring boot 实现的 最后也会附上代码链接地址

技术要点:

代码相对简单,思路也不复杂 会原生开发的同学应该很难容易看懂 基本跟Android 的Sharedpreferences 用法类似 但是flutter 在使用Shared_Preferences 插件库的时候 因为用了 await 关键字 所有必须是在异步的方法 (async )里面进行实现 存储和获取数据 ,其次就是json 解析也相对简单 在拿到res.data 直接通过 BackBean _backbean=BackBean.fromJson(res.data);来转成对象操作 我们只需要创建如图的bean类来 转换就行了


image

最后总结 :

我也是个初学 flutter 的新手 希望我平时写的一些基础功能能够帮助到大家,有兴趣的同学可以私下研究下。这里就不过多讲了 最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。有兴趣的同学麻烦给关注和star

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容