一、provider状态管理设置主题颜色
第一步:
安装依赖库
provider: ^4.3.2+3
第二步:
创建共享数据模型
import 'package:flutter/material.dart';
import 'package:privider_test/base/baseThemes.dart';
class ThemesViewmodel extends ChangeNotifier {
int _index = 0;
int get getColor {
return _index;
}
void SetColor(int value) {
if (value > themes.length - 1) return;
_index = value;
notifyListeners();
}
}
在main函数中引入共享模型
第三步:
创建base颜色数组
import 'package:flutter/material.dart';
List themes = [
Colors.green,
Colors.yellow,
Colors.purple,
Colors.orange,
Colors.cyan,
Colors.blue,
];

在主题中使用provider状态管理,由于想让颜色的值发生改变这里我们使用statefulWidget
mian.dart
import 'package:flutter/material.dart';
import 'package:privider_test/page/UserLoginpage.dart';
import 'package:provider/provider.dart';
import 'ViewModel/ThemesViewmodel.dart';
import 'base/baseThemes.dart';
void main() {
runApp(MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => ThemesViewmodel(),
)
],
child: MyApp(),
));
}
class MyApp extends StatefulWidget {
const MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: UserLoginpage(),
theme: ThemeData(
primarySwatch:
themes[Provider.of<ThemesViewmodel>(context).getColor]), //变换主题颜色
);
}
}
第四步:
画出ui,并添加点击事件
import 'package:flutter/material.dart';
import 'package:privider_test/ViewModel/ThemesViewmodel.dart';
import 'package:privider_test/base/baseThemes.dart';
import 'package:provider/provider.dart';
class UserLoginpage extends StatefulWidget {
const UserLoginpage({ Key key }) : super(key: key);
@override
_UserLoginpageState createState() => _UserLoginpageState();
}
class _UserLoginpageState extends State<UserLoginpage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("登录界面"),
),
body: Padding(
padding: EdgeInsets.all(10),
child: Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: themes.length,
itemBuilder: _itemBuilder,//如果加()就是执行这个方法,不加就是将这个返回
),
),
)
);
}
Widget _itemBuilder(BuildContext context,int index){
return GestureDetector(
onTap: ()async{
(context).read<ThemesViewmodel>().SetColor(index);
},
child: Container(
margin: EdgeInsets.symmetric(vertical: 8),
height: 50,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: themes[index]
),
),
);
}
}
二、flutter登录功能的实现
第一步:创建目录文件夹
第二步:
配置yaml文件依赖
provider: ^4.3.2+3
dio: ^4.0.0
tdui: 0.0.3
encrypt: ^5.0.1
# 提示框
flutter_easyloading: ^3.0.0
编写global.dart
import 'package:dio/dio.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
class Global {
static Global _instance;
Dio dio;
String token;
Map user;
static Global getInstance() {
if (_instance == null) _instance = new Global();
return _instance;
}
Global() {
dio = new Dio();
dio.options = BaseOptions(
baseUrl: "https://zxw.td0f7.cn/",
// baseUrl: "http://localhost:8080/",
connectTimeout: 5000,
sendTimeout: 5000,
receiveTimeout: 5000,
contentType: Headers.formUrlEncodedContentType,
responseType: ResponseType.json,
);
dio.interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) {
EasyLoading.show(status: "Loading...");
return handler.next(options); //continue
},
onResponse: (response, handler) {
EasyLoading.dismiss();
return handler.next(response); // continue
},
onError: (DioError e, handler) {
print(e.toString());
EasyLoading.dismiss();
String msg = "";
if (e.type == DioErrorType.connectTimeout) {
msg = "连接超时错误";
} else {
msg = "接口错误!";
}
EasyLoading.showError(msg);
},
));
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:myitem/router/route_handler.dart';
import 'package:myitem/view/UserLogin.dart';
import 'package:myitem/viewmodel/login_viewmodel.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => LoginViewmodel(),
)
],
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const UserLogin(),
onGenerateRoute: AppRouteManager.getInstance().onGenerateRoute,
debugShowCheckedModeBanner: false, //去掉默认标签
);
}
}
loginmodel.dart
//登录数据模型
import 'package:myitem/global/Global.dart';
import 'package:myitem/util/rsa_utils.dart';
Future loginModel(String user, String pass) async {//将登录的账号和密码传入
String pwd = await encodeString(pass);//使用rsa进行加密
return await Global.getInstance().dio.post("/zxw/user",queryParameters: {
"username":user,"password":pwd
});//调用实例对象后的dio接口dio接口采用接口文档中对应的接口方式get/post提交数据,文档中
//有固定传入参数两个主键请求的结果异步返回给viewmodel
}
/* view层调用viewmodel,viewmodel通知model层,model再
发送请求返回给viewmodel,viewmodel处理返回结果并刷新view*/
登录界面
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:myitem/base/view.dart';
import 'package:myitem/util/rsa_utils.dart';
import 'package:myitem/viewmodel/login_viewmodel.dart';
import 'package:tdui/tdui.dart';
import 'package:provider/provider.dart';
class UserLogin extends StatefulWidget {
const UserLogin({Key key}) : super(key: key);
@override
_UserLoginState createState() => _UserLoginState();
}
class _UserLoginState extends State<UserLogin> {
@override
void initState() {
super.initState();
}
// void loadData()async{
// var result = await encodeString("1");
// print(result);
// }
@override
void dispose() {
super.dispose();//节省资源
context.read<LoginViewmodel>().getPwd.dispose();
context.read<LoginViewmodel>().getUser.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: getAppBar("登录"),
body: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
// Image.asset(
// "images/login.jpg",
// width: double.infinity,
// fit: BoxFit.fill,
// ),
SizedBox(
height: 16,
),
TextField(
decoration: InputDecoration(
labelText: "账号",
hintText: "请输入账号",
prefix: Icon(Icons.person),
),
autofocus: true,
textInputAction: TextInputAction.next,
controller: Provider.of<LoginViewmodel>(context).getUser,
),
TextField(
controller: Provider.of<LoginViewmodel>(context).getPwd,
decoration: InputDecoration(
labelText: "密码", hintText: "请输入密码", prefix: Icon(Icons.lock)),
obscureText: true,
textInputAction: TextInputAction.send,
),
SizedBox(
height: 16,
),
GestureDetector(
child: Container(
width: double.infinity,
child: Text(
"找回密码",
style: TextStyle(color: Colors.blue),
textAlign: TextAlign.right,
),
),
onTap: () {
print("找回密码");
},
),
SizedBox(
height: 16,
),
TdButton(
'登录',
theme: TdButtonType.primary,
loading: Provider.of<LoginViewmodel>(context).getIsLogin,
onClick: () {
_login();
// loadData();
},
),
SizedBox(
height: 16,
),
TdButton(
'注册',
theme: TdButtonType.primary,
onClick: () {
_register();
},
)
],
),
),
);
}
void _login() {
// context.read<LoginViewmodel>().setIsLogin(true);
// new Timer(Duration(seconds: 3), () {
// context.read<LoginViewmodel>().setIsLogin(false);
// Navigator.of(context).pushNamed("/MenuPage");
// });
context.read<LoginViewmodel>().login(context);
}
void _register() {
// context.read<LoginViewmodel>().setIsLogin(false);
Navigator.of(context).pushNamed("/RegisterPage");
}
}
/* view层调用viewmodel,viewmodel通知model层,model再
发送请求返回给viewmodel,viewmodel处理返回结果并刷新view*/
login_viewmodel
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:myitem/model/login_model.dart';
import 'package:tdui/tdui.dart';
//创建登录状态管理
class LoginViewmodel extends ChangeNotifier {
bool _isLogin = false;
TextEditingController _userName; //创建controller进行全局状态管理
TextEditingController _password;
bool get getIsLogin {
//返回
return _isLogin;
}
TextEditingController get getUser {
_userName ??= TextEditingController();
//返回
return _userName;
}
TextEditingController get getPwd {
_password ??= TextEditingController(); //如果没有创建那么进行实例化
//返回
return _password;
}
// ignore: avoid_return_types_on_setters
void setIsLogin(bool value) {
_isLogin = value;
notifyListeners();
}
void login(BuildContext context) async {
setIsLogin(true); //先设置为true
if (getUser.text.isEmpty) {
//判断账号是否为空
TdToast.fail(context)(message: "账号不能为空");
setIsLogin(false); //如果为空那么就返回false
return;
} else if (getPwd.text.isEmpty) {
//如果密码为空,那么返回false
TdToast.fail(context)(message: "密码不能为空");
setIsLogin(false);
return;
}
//如果账号密码都不是空那么,用response接收账号和密码从viewmodel传值到数据模型
Response result = await loginModel(getUser.text, getPwd.text);
if (result.data["success"]) {
Navigator.of(context).popAndPushNamed("/MenuPage");
} else {
TdDialog.alert(context)(result.data["msg"],
theme: TdDialogTheme.android);
}
setIsLogin(false);
}
}

theme: ThemeData(primarySwatch: Colors.yellow),//变换主题颜色
实现开关功能


TdCell(
label: "出生日期",
align: Alignment.center,
content: Provider.of<RegisterViewModel>(context).getDateTime,
footer: Row(
children: [
TdSwitch(
checked:
Provider.of<RegisterViewModel>(context).getSolar == 0
? false
: true,
onChange: (v) {
setState(() {
(context).read<RegisterViewModel>().SetSolar(v ? 1 : 0);
});
},
),
SizedBox(
width: 8,
),
Text(Provider.of<RegisterViewModel>(context).getSolar == 0
? "阳历"
: "阴历")
],
),
onClick: () async {
DatePicker.showDatePicker(context,
showTitleActions: true,
minTime: DateTime(2010, 3, 5),
maxTime: DateTime(2122, 6, 7), onChanged: (date) {
print('change $date');
}, onConfirm: (date) {
(context).read<RegisterViewModel>().SetDateTime(date);
}, currentTime: DateTime.now(), locale: LocaleType.zh);
},
),
数据模型
import 'package:flutter/material.dart';
class RegisterViewModel extends ChangeNotifier{
DateTime _dateTime;
int _gender = 0;//0男 1=女
int _solar = 0;//0表阳历 1=阴历
String get getDateTime{
if(_dateTime == null)return "";
return _dateTime.year.toString() + "年" +_dateTime.month.toString() +"月"+_dateTime.day.toString()+"日";
}
void SetDateTime(DateTime dateTime){
_dateTime = dateTime;
notifyListeners();
}
int get getGender{
return _gender;
}
int get getSolar{
return _solar;
}
void SetGender(int gender){
_gender = gender;
}
void SetSolar(int solar){
_solar = solar;
}
}
三、flutter登录注册功能的实现
Register_viewmodel.dart
import 'dart:convert';
import 'package:myitem/util/rsa_utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:myitem/model/register_model.dart';
class RegisterViewModel extends ChangeNotifier {
DateTime _dateTime;
int _gender = 0; //0男 1=女
int _solar = 0; //0表阳历 1=阴历
bool _getloading = false;
bool get getloading {
//返回
return _getloading;
}
// ignore: avoid_return_types_on_setters
void setloading(bool value) {
_getloading = value;
notifyListeners();
}
String get getDateTime {
if (_dateTime == null) return "";
return _dateTime.year.toString() +
"-" +
_dateTime.month.toString() +
"-" +
_dateTime.day.toString();
}
void SetDateTime(DateTime dateTime) {
_dateTime = dateTime;
notifyListeners();
}
int get getGender {
return _gender;
}
int get getSolar {
return _solar;
}
void SetGender(int gender) {
_gender = gender;
}
void SetSolar(int solar) {
_solar = solar;
}
void login(
String user, String pwd, String name, String phone, String code) async {
setloading(true);
if (user == null || user.isEmpty) {
EasyLoading.showToast("用户名不能为空");
} else if (pwd == null || pwd.isEmpty) {
EasyLoading.showToast("密码不能为空");
} else if (phone == null || phone.isEmpty) {
EasyLoading.showToast("手机号不能为空");
} else if (code == null || code.isEmpty) {
EasyLoading.showToast("验证码不能为空");
}
String pass = await encodeString(pwd);//使用rsa进行加密
Response result = await RegisterModel(json.encode({
"username": user,
"password": pass,
"phone": phone,
"name": name,
"gender": _gender,
"birthday": getDateTime,
"solar": _solar,
}));
if (result.data["success"]) {
EasyLoading.showSuccess("success");
} else {
EasyLoading.showError(result.data["msg"]);
}
setloading(false);
return;
}
}
Register.dart
import 'package:flutter/material.dart';
import 'package:myitem/base/view.dart';
import 'package:myitem/viewmodel/Register_viewmodel.dart';
import 'package:provider/provider.dart';
import 'package:tdui/tdui.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
class RegisterPage extends StatefulWidget {
const RegisterPage({Key key}) : super(key: key);
@override
_RegisterPageState createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
TextEditingController _user = TextEditingController();
TextEditingController _pass = TextEditingController();
TextEditingController _phone = TextEditingController();
TextEditingController _code = TextEditingController();
TextEditingController _name = TextEditingController();
@override
void initState() {
super.initState();
_user = TextEditingController();
_pass = TextEditingController();
_phone = TextEditingController();
_code = TextEditingController();
_name = TextEditingController();
}
@override
void dispose() {
super.dispose();
_user.dispose();
_pass.dispose();
_phone.dispose();
_code.dispose();
_name.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: getAppBar("用户注册"),
body: Container(
child: Column(
children: [
SizedBox(
height: 16,
),
TdInput(
label: "登录账号",
hintText: "请输入登录用户名",
clearable: true,
textInputAction: TextInputAction.next,
onChange: (v) {
_user.text = v;
},
),
TdInput(
label: "手机号码",
hintText: "请输入手机号码",
textInputAction: TextInputAction.send,
type: TextInputType.phone,
footer: TdButton(
"获取验证码",
theme: TdButtonType.primary,
size: TdButtonSize.mini,
),
onChange: (v) {
_phone.text = v;
},
),
TdInput(
label: "验证码",
hintText: "请输入获取验证码",
textInputAction: TextInputAction.next,
type: TextInputType.number,
clearable: true,
onChange: (v) {
_code.text = v;
},
),
TdInput(
label: "登录密码",
hintText: "请输入获登录密码",
textInputAction: TextInputAction.next,
clearable: true,
obscureText: true,
onChange: (v) {
_pass.text = v;
},
),
TdInput(
label: "中文姓名",
hintText: "请输入中文姓名",
textInputAction: TextInputAction.next,
footer: Row(
children: [
TdSwitch(
checked:
Provider.of<RegisterViewModel>(context).getGender == 0
? false
: true,
onChange: (v) {
setState(() {
(context)
.read<RegisterViewModel>()
.SetGender(v ? 1 : 0);
});
},
),
SizedBox(
width: 8,
),
Text(Provider.of<RegisterViewModel>(context).getGender == 0
? "男"
: "女")
],
),
onChange: (v) {
_name.text = v;
},
),
TdCell(
label: "出生日期",
align: Alignment.center,
content: Provider.of<RegisterViewModel>(context).getDateTime,
footer: Row(
children: [
TdSwitch(
checked:
Provider.of<RegisterViewModel>(context).getSolar == 0
? false
: true,
onChange: (v) {
setState(() {
(context).read<RegisterViewModel>().SetSolar(v ? 1 : 0);
});
},
),
SizedBox(
width: 8,
),
Text(Provider.of<RegisterViewModel>(context).getSolar == 0
? "阳历"
: "阴历")
],
),
onClick: () async {
DatePicker.showDatePicker(context,
showTitleActions: true,
minTime: DateTime(2010, 3, 5),
maxTime: DateTime(2122, 6, 7), onChanged: (date) {
print('change $date');
}, onConfirm: (date) {
(context).read<RegisterViewModel>().SetDateTime(date);
}, currentTime: DateTime.now(), locale: LocaleType.zh);
},
),
Container(
margin: EdgeInsets.all(10),
child: TdButton(
"注册",
loading: Provider.of<RegisterViewModel>(context).getloading,
theme: TdButtonType.warn,
onClick: () {
(context).read<RegisterViewModel>().login(_user.text,
_pass.text, _name.text, _phone.text, _code.text);
},
),
)
],
),
),
);
}
}
register_model.dart
//登录数据模型
import 'package:myitem/global/Global.dart';
Future RegisterModel(String json) async {//将登录的账号和密码传入
return await Global.getInstance().dio.post("/zxw/user/register",queryParameters: {
"json":json,
});//调用实例对象后的dio接口dio接口采用接口文档中对应的接口方式get/post提交数据,文档中
//有固定传入参数两个主键请求的结果异步返回给viewmodel
}
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:myitem/router/route_handler.dart';
import 'package:myitem/view/User/UserLogin.dart';
import 'package:myitem/viewmodel/Register_viewmodel.dart';
import 'package:myitem/viewmodel/login_viewmodel.dart';
import 'package:myitem/viewmodel/theme_viewmodel.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'global/global_theme.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
void main() async {
//持久化处理背景颜色
WidgetsFlutterBinding.ensureInitialized();
SharedPreferences sp = await SharedPreferences.getInstance();
int color = await sp.getInt("color") ?? 0;
ThemViewmodel themeViewmodel = ThemViewmodel();
themeViewmodel.setColor(color);
//
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => LoginViewmodel(),
),
ChangeNotifierProvider(
create: (context) => themeViewmodel,
),
ChangeNotifierProvider(
create:(context)=>RegisterViewModel()
)
],
child: const MyApp(),
),
);
}
void loadData()async{
}
class MyApp extends StatefulWidget {
const MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
// initPlatformState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: themes[Provider.of<ThemViewmodel>(context).getColor],
buttonTheme: ButtonThemeData(
buttonColor: themes[Provider.of<ThemViewmodel>(context).getColor],
textTheme: ButtonTextTheme.primary,
),
),
home: UserLogin(),
onGenerateRoute: AppRouteManager.getInstance().onGenerateRoute,
debugShowCheckedModeBanner: false, //去掉默认标签
builder: EasyLoading.init(),
);
}
}

由于很多变量放在了状态管理中,会大量的消耗app的内存,所以进行了一些优化
Register_viewmodel.dart
import 'dart:convert';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:myitem/util/rsa_utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:myitem/model/register_model.dart';
class RegisterViewModel extends ChangeNotifier {
void login(String user, String pwd, String name, String phone, String code,
int _gender, int _solar, String getDateTime) async {
String pass = await encodeString(pwd); //使用rsa进行加密
Response result = await RegisterModel(json.encode({
"username": user,
"password": pass,
"phone": phone,
"name": name,
"gender": _gender,
"birthday": getDateTime,
"solar": _solar,
}));
if (result.data["success"]) {
EasyLoading.showToast("注册成功");
// Navigator.pop(navigatorKey.currentContext, {
// "user": user,
// "pass": pass,
// }
// );
} else {
EasyLoading.showError(result.data["msg"]);
}
return;
}
}
date_util.dart
//修改日期
String getDate(DateTime _dateTime) {
return _dateTime == null
? ""
: _dateTime.year.toString() +
"-" +
_dateTime.month.toString() +
"-" +
_dateTime.day.toString();
}
Register.dart
import 'package:flutter/material.dart';
import 'package:myitem/base/view.dart';
import 'package:myitem/util/date_util.dart';
import 'package:myitem/viewmodel/Register_viewmodel.dart';
import 'package:provider/provider.dart';
import 'package:tdui/tdui.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
class RegisterPage extends StatefulWidget {
const RegisterPage({Key key}) : super(key: key);
@override
_RegisterPageState createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
TextEditingController _user = TextEditingController();
TextEditingController _pass = TextEditingController();
TextEditingController _phone = TextEditingController();
TextEditingController _code = TextEditingController();
TextEditingController _name = TextEditingController();
DateTime _dateTime;
int _gender = 0; //0男 1=女
int _solar = 0; //0表阳历 1=阴历
@override
void initState() {
super.initState();
_user = TextEditingController();
_pass = TextEditingController();
_phone = TextEditingController();
_code = TextEditingController();
_name = TextEditingController();
}
@override
void dispose() {
super.dispose();
_user.dispose();
_pass.dispose();
_phone.dispose();
_code.dispose();
_name.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: getAppBar("用户注册"),
body: Container(
child: Column(
children: [
SizedBox(
height: 16,
),
TdInput(
label: "登录账号",
hintText: "请输入登录用户名",
clearable: true,
textInputAction: TextInputAction.next,
onChange: (v) {
_user.text = v;
},
),
TdInput(
label: "手机号码",
hintText: "请输入手机号码",
textInputAction: TextInputAction.send,
type: TextInputType.phone,
footer: TdButton(
"获取验证码",
theme: TdButtonType.primary,
size: TdButtonSize.mini,
),
onChange: (v) {
_phone.text = v;
},
),
TdInput(
label: "验证码",
hintText: "请输入获取验证码",
textInputAction: TextInputAction.next,
type: TextInputType.number,
clearable: true,
onChange: (v) {
_code.text = v;
},
),
TdInput(
label: "登录密码",
hintText: "请输入获登录密码",
textInputAction: TextInputAction.next,
clearable: true,
obscureText: true,
onChange: (v) {
_pass.text = v;
},
),
TdInput(
label: "中文姓名",
hintText: "请输入中文姓名",
textInputAction: TextInputAction.next,
footer: Row(
children: [
TdSwitch(
checked: _gender == 0 ? false : true,
onChange: (v) {
setState(() {
v ? _gender = 1 : _gender = 0;
});
},
),
SizedBox(
width: 8,
),
Text(_gender == 0 ? "男" : "女")
],
),
onChange: (v) {
_name.text = v;
},
),
TdCell(
label: "出生日期",
align: Alignment.center,
content: getDate(_dateTime),
footer: Row(
children: [
TdSwitch(
checked: _solar == 0 ? false : true,
onChange: (v) {
setState(() {
v ? _solar = 1 : _solar = 0;
});
},
),
SizedBox(
width: 8,
),
Text(_solar == 0 ? "阳历" : "阴历")
],
),
onClick: () async {
DatePicker.showDatePicker(context,
showTitleActions: true,
minTime: DateTime(2010, 3, 5),
maxTime: DateTime(2122, 6, 7),
onChanged: (date) {}, onConfirm: (date) {
setState(() {
_dateTime = date;
});
}, currentTime: DateTime.now(), locale: LocaleType.zh);
},
),
Container(
margin: EdgeInsets.all(10),
child: TdButton(
"注册",
theme: TdButtonType.warn,
onClick: () {
_register();
},
),
)
],
),
),
);
}
void _register() {
print("object");
if (_user.text == null || _user.text.isEmpty) {
EasyLoading.showToast("用户名不能为空");
} else if (_pass.text == null || _pass.text.isEmpty) {
EasyLoading.showToast("密码不能为空");
} else if (_phone.text == null || _phone.text.isEmpty) {
EasyLoading.showToast("手机号不能为空");
} else if (_code.text == null || _code.text.isEmpty) {
EasyLoading.showToast("验证码不能为空");
}
(context).read<RegisterViewModel>().login(_user.text, _pass.text,
_name.text, _phone.text, _code.text, _gender, _solar, getDate(_dateTime));
}
}
用路由传值返回对象,实现注册后,可以在登录界面保留注册账户信息
Register_viewmodel.dart
import 'dart:convert';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:myitem/main.dart';
import 'package:myitem/util/rsa_utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:myitem/model/register_model.dart';
class RegisterViewModel extends ChangeNotifier {
void login(String user, String pwd, String name, String phone, String code,
int _gender, int _solar, String getDateTime) async {
String pass = await encodeString(pwd); //使用rsa进行加密
Response result = await RegisterModel(json.encode({
"username": user,
"password": pass,
"phone": phone,
"name": name,
"gender": _gender,
"birthday": getDateTime,
"solar": _solar,
}));
if (result.data["success"]) {
Navigator.pop(navigatorKey.currentContext, {
"user": user,
"pass": pwd,
});
EasyLoading.showSuccess("注册成功");
} else {
EasyLoading.showError(result.data["msg"]);
}
return;
}
}

UserLogin_view.dart
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:myitem/base/view.dart';
import 'package:myitem/global/Global.dart';
import 'package:myitem/viewmodel/login_viewmodel.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tdui/tdui.dart';
import 'package:provider/provider.dart';
class UserLogin extends StatefulWidget {
const UserLogin({Key key}) : super(key: key);
@override
_UserLoginState createState() => _UserLoginState();
}
class _UserLoginState extends State<UserLogin> {
TextEditingController _userName; //创建controller进行全局状态管理
TextEditingController _password;
@override
void initState() {
super.initState();
_userName = TextEditingController();
_password = TextEditingController();
// loadData();
}
@override
void dispose() {
super.dispose(); //节省资源
_userName.dispose();
_password.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: getAppBar("登录"),
body: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: [
SizedBox(
height: 16,
),
TextField(
decoration: InputDecoration(
labelText: "账号",
hintText: "请输入账号",
prefix: Icon(Icons.person),
),
autofocus: true,
textInputAction: TextInputAction.next,
controller: _userName,
),
TextField(
controller: _password,
decoration: InputDecoration(
labelText: "密码", hintText: "请输入密码", prefix: Icon(Icons.lock)),
obscureText: true,
textInputAction: TextInputAction.send,
),
SizedBox(
height: 16,
),
GestureDetector(
child: Container(
width: double.infinity,
child: Text(
"找回密码",
style: TextStyle(color: Colors.blue),
textAlign: TextAlign.right,
),
),
onTap: () {
print("找回密码");
},
),
SizedBox(
height: 16,
),
TdButton(
'登录',
theme: TdButtonType.primary,
onClick: () {
_login();
},
),
SizedBox(
height: 16,
),
TdButton(
'注册',
theme: TdButtonType.primary,
onClick: () {
_register();
},
)
],
),
),
);
}
void _login() {
if (_userName.text.isEmpty) {
EasyLoading.showError("账号不能为空");
return;
} else if (_password.text.isEmpty) {
EasyLoading.showError("密码不能为空");
return;
}
context.read<LoginViewmodel>().login(_userName.text, _password.text);
}
void _register() async {
dynamic params = await Navigator.of(context).pushNamed("/RegisterPage");
if (params != null) {
setState(() {
_userName.text = params["user"];
_password.text = params["pass"];
});
}
}
void loadData() async {
SharedPreferences sp = await SharedPreferences.getInstance();
String token = await sp.getString("token");
print(token);
if (token != null) {
//将里面的token对象赋值到获取的token值
Global.getInstance().dio.options.headers["token"] = token;
context.read<LoginViewmodel>().tokenLogin(token);
}
}
}
/* view层调用viewmodel,viewmodel通知model层,model再
发送请求返回给viewmodel,viewmodel处理返回结果并刷新view*/

持久化管理,报错token值
login_viewmodel.dart
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:myitem/global/Global.dart';
import 'package:myitem/model/login_model.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../main.dart';
//创建登录状态管理
class LoginViewmodel extends ChangeNotifier {
void login(String user, String pass) async {
//持久化管理
SharedPreferences sp = await SharedPreferences.getInstance();
Response result = await loginModel(user, pass);
if (result.data["success"]) {
Global.getInstance().token = result.data["data"]["token"];
Global.getInstance().user = result.data["data"]["user"];
sp.setString("token", result.data["data"]["token"]);
Global.getInstance().dio.options.headers["token"] =
result.data["data"]["token"];
//下次验证token是不是过期了
EasyLoading.showSuccess("success");
Navigator.of(navigatorKey.currentContext).popAndPushNamed("/MenuPage");
} else {
EasyLoading.showError(result.data["msg"]);
}
}
void tokenLogin(String token) async {
SharedPreferences sp = await SharedPreferences.getInstance();
Response result = await tokenLoginModel();
if (result.data["success"]) {
//如果请求成功
Global.getInstance().user =
result.data["data"]; //将将请求结果中的data赋值为gobal中的user
Navigator.of(navigatorKey.currentContext).popAndPushNamed("/menu"); //跳转路由
} else {
sp.remove("token"); //如果不成功就移除持久化管理中创建的token对象
}
}
}

login_viewmodel.dart
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:myitem/global/Global.dart';
import 'package:myitem/model/login_model.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../main.dart';
//创建登录状态管理
class LoginViewmodel extends ChangeNotifier {
void login(String user, String pass) async {
//持久化管理
SharedPreferences sp = await SharedPreferences.getInstance();
Response result = await loginModel(user, pass);
if (result.data["success"]) {
Global.getInstance().token = result.data["data"]["token"];
Global.getInstance().user = result.data["data"]["user"];
sp.setString("token", result.data["data"]["token"]);
Global.getInstance().dio.options.headers["token"] =
result.data["data"]["token"];
//下次验证token是不是过期了
EasyLoading.showSuccess("success");
Navigator.of(navigatorKey.currentContext).popAndPushNamed("/MenuPage");
} else {
EasyLoading.showError(result.data["msg"]);
}
}
void tokenLogin(String token) async {
SharedPreferences sp = await SharedPreferences.getInstance();
Response result = await tokenLoginModel();
if (result.data["success"]) {
//如果请求成功
Global.getInstance().user =
result.data["data"]; //将将请求结果中的data赋值为gobal中的user
Navigator.of(navigatorKey.currentContext).popAndPushNamed("/menu"); //跳转路由
} else {
sp.remove("token"); //如果不成功就移除持久化管理中创建的token对象
}
}
}



版权声明:本文为qq_43547255原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。