Flutter32
];
List menuIcons = [
Icons.message,
Icons.print,
Icons.error,
Icons.phone,
Icons.send,
Icons.people,
Icons.person,
];
String userAvatar;
String userName;
@override
void initState() {
// TODO: implement initState
super.initState();
//尝试显示用户信息
_showUerInfo();
eventBus.on<LoginEvent>().listen((event) {
//TODO
//获取用户信息并显示
});
eventBus.on<LogoutEvent>().listen((event) {
//TODO
});
}
_showUerInfo() {
}
@override
Widget build(BuildContext context) {
return ListView.separated(
itemBuilder: (context, index) {
//My 界面的头部
if(index == 0){
//头像用 Container 装起来
return _buildHeader();
}
index -= 1;
return ListTile(
leading: Icon(menuIcons[index]),
title: Text(menuTitles[index]),
trailing: Icon(Icons.arrow_forward_ios),//尾巴
onTap: () {
_login();
},
);
},
//分割线
separatorBuilder: (context, index) {
return Divider();
},
itemCount: menuTitles.length + 1
);
}
_login() async {
final result = await Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => LoginWebPage()));
if (result != null
&& result == 'refresh') {
print('Debug profile page LoginEvent');
//登录成功
eventBus.fire(LoginEvent());
}
}
Container _buildHeader() {
return Container(
height: 150.0,
color: Color(AppColors.APP_THEME),
//头像的布局填充
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GestureDetector(
child: Container(
width: 60.0,
height: 60.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Color(0xffffffff),
width: 2.0,
),
image: DecorationImage(
//加载网路图片
image: AssetImage('assets/images/ic_avatar_default.png'),
fit: BoxFit.cover,
),
),
),
onTap: () {
//执行登录
_login();
},
),
SizedBox(
),
Text(
'点击头像登录',
style: TextStyle(color: Color(0xffffffff)),
),
],
),
),
);
}
}
login_web_page.dart 登录页面跳转逻辑,数据拼接组装校验,数据保存完成以后会调用 Navigator.pop(context, 'refresh');通过路由跳转到 My 的界面
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:flutterapp2/constants/Constants.dart';
import 'package:flutterapp2/utils/data_utils.dart';
import 'package:flutterapp2/utils/net_utils.dart';
class LoginWebPage extends StatefulWidget {
@override
_LoginWebPageState createState() => _LoginWebPageState();
}
class _LoginWebPageState extends State<LoginWebPage> {
FlutterWebviewPlugin _flutterWebviewPlugin = FlutterWebviewPlugin();
bool isLoading = true;
@override
void initState() {
// TODO: implement initState
super.initState();
//监听 url 的变化
_flutterWebviewPlugin.onUrlChanged.listen((url) {
print('Debug LoginWebPage onUrlChanged: $url');
if (mounted) {
setState(() {
isLoading = true;
});
}
if (url != null && url.length > 0 && url.contains('?code=')) {
//登录成功了
//提取授权码 code
String code = url.split('?')[1].split('&')[0].split('=')[1];
Map<String, dynamic> params = Map<String, dynamic>();
params['client_id'] = AppInfos.CLIENT_ID;
params['client_secret'] = AppInfos.CLIENT_SECRET;
params['grant_type'] = 'authorization_code';
params['redirect_uri'] = AppInfos.REDIRECT_URI;
params['code'] = '$code';
params['dataType'] = 'json';
NetUtils.get(AppUrls.OAUTH2_TOKEN, params).then((data) {
//{"access_token":"aa105aaf-ca4f-4458-822d-1ae6a1fa33f9","refresh_token":"daae8b80-3ca6-4514-a8ae-acb3a82c951c","uid":2006874,"token_type":"bearer","expires_in":510070}
//this is login_web_page: {"access_token":"d0e00aa3-4d43-4a05-ab76-546d351ce5d5","refresh_token":"555f4e8a-bccc-4976-9d7e-1d5183ef5798","uid":4571926,"token_type":"bearer","expires_in":604295}
print('Debug this is login_web_page: $data');
if (data != null) {
Map<String, dynamic> map = json.decode(data);
if (map != null && map.isNotEmpty) {
//保存 token 等信息
DataUtils.saveLoginInfo(map);
//弹出当前路由,并返回 refresh 通知我的界面刷新数据
Navigator.pop(context, 'refresh');
}
}
});
}
});
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_flutterWebviewPlugin.close();
}
@override
Widget build(BuildContext context) {
//authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https
List<Widget> _appBarTitle = [
Text(
'登录开源中国',
style: TextStyle(
color: Color(AppColors.APPBAR),
),
),
];
if(isLoading) {
_appBarTitle.add(SizedBox(
width: 10.0,
));
_appBarTitle.add(CupertinoActivityIndicator());
}
return WebviewScaffold(
url: AppUrls.OAUTH2_AUTHORIZE +
'?response_type=code&client_id=' +
AppInfos.CLIENT_ID +
'&redirect_uri=' +
AppInfos.REDIRECT_URI,
appBar: AppBar(
title: Row(
children: _appBarTitle,
),
),
withJavascript: true,//允许执行 js
withLocalStorage: true,//允许本地存储
withZoom: true,//允许网页缩放
);
}
}
net_utils.dart 网络数据的请求处理
import 'package:http/http.dart' as http;
class NetUtils{
//返回类型是 String,是一个 JSON
///authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri
static Future<String> get(String url, Map<String, dynamic> params) async{
if(url != null && params != null && params.isNotEmpty) {
//拼装参数
StringBuffer sb = StringBuffer('?');
params.forEach((key, value) {
sb.write('value&');
});
//去掉最后一个 &
String paramStr = sb.toString().substring(0, sb.length - 1);
url += paramStr;
}
print('Debug NetUtils : $url');
http.Response response = await http.get(url);
return response.body;
}
}
data_utils.dart 数据的封装和拼接
import 'package:shared_preferences/shared_preferences.dart';
class DataUtils{
static const String SP_ACCESS_TOKEN = 'access_token';
static const String SP_REFRESH_TOKEN = 'refresh_token';
static const String SP_UID = 'uid';
static const String SP_TOKEN_TYPE = 'token_type';
static const String SP_EXPIRES_IN = 'expires_in';
static const String SP_IS_LOGIN = 'is_login';
//存储数据
// {"access_token":"aa105aaf-ca4f-4458-822d-1ae6a1fa33f9","refresh_token":"daae8b80-3ca6-4514-a8ae-acb3a82c951c","uid":2006874,"token_type":"bearer","expires_in":510070}
static Future<void> saveLoginInfo(Map<String, dynamic> map) async {
if (map != null && map.isNotEmpty) {
SharedPreferences sp = await SharedPreferences.getInstance();
sp
..setString(SP_ACCESS_TOKEN, map[SP_ACCESS_TOKEN])
..setString(SP_REFRESH_TOKEN, map[SP_REFRESH_TOKEN])
..setInt(SP_UID, map[SP_UID])
..setString(SP_TOKEN_TYPE, map[SP_TOKEN_TYPE])
评论