网络请求
profile_page.dart对布局进行了填充,最上面的头像的布局和下面的条目的布局,_login()是网络请求相关的逻辑,使用WevView来实现
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutterapp2/constants/Constants.dart'; import 'login_web_page.dart'; /** * 主界面My */ class ProfilePage extends StatefulWidget { @override _ProfilePageState createState() => _ProfilePageState(); } class _ProfilePageState extends State<ProfilePage> { List menuTitles = [ '我的消息', '阅读记录', '我的博客', '我的问答', '我的活动', '我的团队', '邀请好友', ]; List menuIcons = [ Icons.message, Icons.print, Icons.error, Icons.phone, Icons.send, Icons.people, Icons.person, ]; String userAvatar; String userName; @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 { Navigator.of(context).push(MaterialPageRoute(builder: (context) => LoginWebPage())); } 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使用webview加载html相关的文件pubspec.yaml中需要增加webview相关的支持
引入flutter_webview_plugin: ^0.3.11 代码如下
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'; 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) { //https://www.oschina.net/action/oauth2/authorize?response_type=code&client_id=6i4Yu6IUqXnR64em0rsJ&redirect_uri=https://www.dongnaoedu.com/ print('LoginWebPage onUrlChanged: $url'); if (mounted) { setState(() { isLoading = true; }); } }); } @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,//允许网页缩放 ); } }Constants.dart相关的常量
abstract class AppColors{ //应用主题色 static const APP_THEME = 0xff63ca6c; static const APPBAR = 0xffffffff; } abstract class AppInfos { static const String CLIENT_ID = '6ZmjMJ4ZCW7YRhQ4sm42';//应用id static const String CLIENT_SECRET = 'sXWCxyV1KegoF2gethYuBZhI8WQI9fjk';//应用密钥 static const String REDIRECT_URI = 'https://www.dongnaoedu.com/';//回调地址 } abstract class AppUrls { static const String HOST = 'https://www.oschina.net'; //授权登录 ctrl shift u static const String OAUTH2_AUTHORIZE = HOST + '/action/oauth2/authorize'; //获取token static const String OAUTH2_TOKEN = HOST + '/action/openapi/token'; //获取用户信息 static const String OPENAPI_USER = HOST + '/action/openapi/user'; static const String MY_INFORMATION = HOST + '/action/openapi/my_information'; static const String MESSAGE_LIST = HOST + '/action/openapi/message_list'; static const String NEWS_LIST = HOST + '/action/openapi/news_list'; static const String NEWS_DETAIL = HOST + '/action/openapi/news_detail'; static const String TWEET_LIST = HOST + '/action/openapi/tweet_list'; static const String TWEET_PUB = HOST + '/action/openapi/tweet_pub'; }pubspec.yaml
name: flutterapp1 description: A new Flutter application. publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: sdk: ">=2.7.0 <3.0.0" dependencies: flutter: sdk: flutter cupertino_icons: ^0.1.3 http: ^0.12.1 flutter_webview_plugin: ^0.3.11 shared_preferences: ^0.5.7+3 event_bus: ^1.1.1 sensors: ^0.4.0+1 dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true assets: - assets/images/ic_nav_news_normal.png - assets/images/ic_nav_news_actived.png - assets/images/ic_nav_tweet_normal.png - assets/images/ic_nav_tweet_actived.png - assets/images/ic_nav_discover_normal.png - assets/images/ic_nav_discover_actived.png - assets/images/ic_nav_my_normal.png - assets/images/ic_nav_my_pressed.png #Drawer - assets/images/cover_img.jpg - #用户默认头像 - assets/images/ic_avatar_default.png - #摇一摇背景图 - assets/images/shake.pnglog输出如下:
I/flutter (19572): LoginWebPage onUrlChanged: https://www.oschina.net/action/oauth2/authorize?response_type=code&client_id=6ZmjMJ4ZCW7YRhQ4sm42&redirect_uri=https://www.dongnaoedu.com/效果如下图