前言:

在原生的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](https://upload-images.jianshu.io/upload_images/6865547-2751f061ff0fbde3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

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

2具体实现

先实现登录界面的功能

![image](https://upload-images.jianshu.io/upload_images/6865547-8fa5f96a22ee14a1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

登录页面是两个输入框TextFiled  和一个RaisedButton 来实现请求后台来处理登录功能

通过Dio库来实现异步网络请求  然后  通过  factory BackBean.fromJson 来转换成对象

在登录成功后通过 SharedPreferences  来储存数据 如下图所示  在登录成功后调用sharedPreferences.setString ()方法来存数据

![image](https://upload-images.jianshu.io/upload_images/6865547-fd21e1e89d1e7467.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

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

```

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](https://upload-images.jianshu.io/upload_images/6865547-b5058492fef61188.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![image](https://upload-images.jianshu.io/upload_images/6865547-745c677a7ee1a208.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

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

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

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

![image](https://upload-images.jianshu.io/upload_images/6865547-694cc5acd8493dfc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

具体代码 (欢迎页面)

```

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](https://upload-images.jianshu.io/upload_images/6865547-9b9fce85ed9e1c50.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 最后总结  :

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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐