zoukankan      html  css  js  c++  java
  • flutter 通过用户信息配置路由拦截 shared_preferences

     环境:

    flutter  sdk

      [√] Flutter (Channel stable, 2.2.3, on Microsoft Windows [Version 10.0.19042.1110], locale zh-CN)

    shared_preferences  缓存

      shared_preferences: ^2.0.6

    文件目录   类似vue的目录

    common 存放全局的用户信息

     Global.dart

    //
    // http请求配置
    // 1107949255@qq.com
    // ただ爽子のFANだけど
    //
    
    import 'package:shared_preferences/shared_preferences.dart';
    
    class Global {
      static SharedPreferences _prefs;
    
      //初始化全局信息,会在APP启动时执行
      static Future<String> init() async {
        if (_prefs == null) {
          _prefs = await SharedPreferences.getInstance();
    
        }
        return 'ok';
      }
    
      get token {
        print(_prefs);
        return _prefs.getString('token');
      }
    
      set token(value) {
        _prefs.setString("token", value);
      }
    
      get username {
        print(_prefs);
        return _prefs.getString('username');
      }
    
      set username(value) {
        _prefs.setString("username", value);
      }
    
      get nickname {
        print(_prefs);
        return _prefs.getString('nickname');
      }
    
      set nickname(value) {
        _prefs.setString("nickname", value);
      }
    }

    定义了几个set get方法, 直接用过new  Global().token 获取信息。

    routers 存放路由文件  

    index.dart 配置路由信息

    //
    // http请求配置
    // 1107949255@qq.com
    // ただ爽子のFANだけど
    //
    import 'package:flutter/material.dart';
    import 'dart:core';
    import '../views/app.dart';
    import '../views/derivative/goods/goods.dart';
    import '../views/derivative/singles/singles.dart';
    import '../views/user/login.dart';
    import '../views/user/photos.dart';
    import '../views/user/userCenter.dart';
    import '../views/derivative/map/map.dart';
    import '../views/loading.dart';
    import '../common/Global.dart';
    
    // 钩子函数获取token信息
    routeBeforeHook(RouteSettings settings) {
      /// Global.prefs 是全局的 SharedPreferences 实例
      /// SharedPreferences 是常用的本地存储的插件
      if (settings.name == '/loading' || settings.name == '/login')
        return settings.name;
      if (checkToken() == false) {
        return '/login';
      } else {
        return settings.name;
      }
    }
    
    checkToken() {
      var globalClass = new Global();
      bool isHaveToken = false;
      isHaveToken = globalClass.token !=null && globalClass.token != '' ? true : false;
      return isHaveToken;
    }
    
    // 路由配置
    Route<dynamic> onGenerateRoute(RouteSettings setting) {
      Map<String, Widget> routes = {
        '/app': new App(page: 0), //定义app路径
        '/goods': new Goods(), //定义goods路径
        '/singles': new Singles(), //定义goods_item路径
        '/login': new MyLogin(), //定义login路径
        '/photos': new MyPthotos(), //定义photos路径
        '/map': new MyMap(), //定义map路径
        '/uc': new UC(), //定义用户中心路径
        '/loading': new LoadingPage(), // 加载页面
      };
    
      String routerName = routeBeforeHook(setting);
      bool mathMap = false;
      Route<dynamic> mathWidget;
      routes.forEach((key, v) {
        if (key == routerName) {
          mathMap = true;
          mathWidget = MaterialPageRoute(builder: (BuildContext context) => v);
        }
      });
    
      if (mathMap) {
        return mathWidget;
      }
      return MaterialPageRoute(
          builder: (BuildContext context) => Container(
                child: Text('404'),
              ));
    }

    修改main.dart 

    //
    // http请求配置
    // 1107949255@qq.com
    // ただ爽子のFANだけど
    //
    import 'package:flutter/material.dart';
    import 'package:flutter_redux/flutter_redux.dart';
    import 'package:redux/redux.dart';
    import 'store/app_state.dart';
    import 'routers/index.dart' as router;  // 引入router
    import "common/Global.dart";
    import 'package:shared_preferences/shared_preferences.dart';
    
    void main() {
      SharedPreferences.setMockInitialValues({});   // 处理报错
      Store<AppState> store = new Store<AppState>(mainReducer,
          initialState: new AppState(
            auth: new AuthState(),
          ));
    
    //  Global.init().then((e) => runApp(MyApp(store: store)));
    //  Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
      WidgetsFlutterBinding.ensureInitialized(); //解决加载json错误
      Global.init().then((dynamic res) {
        print(res);
        if (res == 'ok') {
          runApp(MyApp(store: store));
        }
      });
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      final Store store;
      MyApp({this.store});
    
      @override
      Widget build(BuildContext context) {
        return StoreProvider(
            store: store, //绑定store
            child: MaterialApp(
              debugShowCheckedModeBanner: false, //去除右上角的Debug标签
              title: '君に届け',
              onGenerateRoute: router.onGenerateRoute,  // 显示router
              theme: pinkTheme,
              initialRoute: "/loading",
            ));
      }
    }
    
    // 定义一个喜欢的主题
    final ThemeData pinkTheme = new ThemeData(
        primaryColor: Colors.pink[200],
        primaryColorBrightness: Brightness.light,
        backgroundColor: Colors.amberAccent);

    演示:

    默认进入页为loading页

     点击关闭时默认进入主页,如下

    onPressed: () {
                  // 进入主页
                      Navigator.of(context).pushReplacementNamed("/app");
    }));

    但是加了路由验证之后,就会进入 routeBeforeHook 钩子函数里面,类似vue,判断用户信息(token)是否存在,存在就进入,否则就直接跳转到登录页(或者说直接加载登录页)

    输入用户名、密码后,需要保存全局token、username、nickname,直接赋值

    var globalClass = new Global();
    globalClass.username = username.text;
    globalClass.token = "dwq1d1123";
    globalClass.nickname = "ただ爽子のFANだけど";

    然后就跳到了中心页

    
    
    import 'package:shared_preferences/shared_preferences.dart';
    // 获取用户信息
    Future<Object> getUserInfo() async { Map userInfo =
    new Map(); SharedPreferences prefs = await SharedPreferences.getInstance(); var userName = prefs.getString('username'); var nickName = prefs.getString('nickname'); userInfo["username"] = userName; userInfo["nickname"] = nickName; return userInfo; } // 显示username nickename child: FutureBuilder<Object>( future: getUserInfo(), initialData: {}, builder: (BuildContext context, AsyncSnapshot snapshot) { return Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ new Text( snapshot.data["username"] == null ? '未登录' : snapshot.data["username"], style: TextStyle( fontSize: 18.0, color: Color(0xFF353535), ), ), new Text( (snapshot.data["nickname"] == null ? '' : snapshot.data["nickname"]), style: TextStyle( fontSize: 14.0, color: Color(0xFFa9a9a9), ), ), ]); }),

    之后再怎么跳转路由都是ok的,但是当你清除缓存信息后

    logout(context) async {
        SharedPreferences prefs = await SharedPreferences.getInstance();
        prefs.remove('username'); //删除指定键
        prefs.remove('token'); //删除指定键
    //    print('注销成功');
        Navigator.pushNamed(context, '/login');
      }

    后面再操作也会跳到登录页。

     

     对于这些问题,网络上的解决方法都是寥寥可数,要不就是copy过去copy过来,看的头疼,我也是不断地尝试,各种升级测试,才勉强搞出的解决办法,真希望有详细的文档。希望flutter后面越来越完善,ღ( ´・ᴗ・` )比心。

    今ならできます。
  • 相关阅读:
    javascript 注意事项汇总
    Object.prototype.toString方法
    PHPStorm使用心得
    JavaScript基于原型链的继承
    PHP重定向的3种方式
    Android应用与开发环境
    PHP时间处理
    cocos2dxna 游戏中如何控制后退键实现目的性跳转
    wp7 独立存储空间在真机和虚拟机测试的时候数据不一样
    c#获取交叉数组的行、列数
  • 原文地址:https://www.cnblogs.com/shuangzikun/p/flutter_router_userinfo.html
Copyright © 2011-2022 走看看