基础库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

login_page.dart 9.1 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/gestures.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter_bloc/flutter_bloc.dart';
  6. import 'package:zhiying_comm/pages/login_page/account/login_account_page.dart';
  7. import 'package:zhiying_comm/util/empty_util.dart';
  8. import 'package:zhiying_comm/util/mob_util/mob_util.dart';
  9. import 'package:zhiying_comm/zhiying_comm.dart';
  10. import 'bloc/bloc.dart';
  11. import 'bloc/login_repository.dart';
  12. import 'login_page_sk.dart';
  13. import 'model/login_model.dart';
  14. ///
  15. /// 登陆页面
  16. ///
  17. class LoginPage extends StatelessWidget {
  18. const LoginPage({Key key}) : super(key: key);
  19. @override
  20. Widget build(BuildContext context) {
  21. return Scaffold(
  22. backgroundColor: HexColor.fromHex('#FFFFFF'),
  23. body: BlocProvider<LoginBloc>(
  24. create: (_) => LoginBloc(repository: LoginRepository())..add(LoginInitEvent()),
  25. child: LoginPageContainer(),
  26. ),
  27. );
  28. }
  29. }
  30. class LoginPageContainer extends StatefulWidget {
  31. @override
  32. _LoginPageContainerState createState() => _LoginPageContainerState();
  33. }
  34. class _LoginPageContainerState extends State<LoginPageContainer> {
  35. /// 微信or手机登陆
  36. void _loginClick(String type, LoginModel model) {
  37. print('登陆$type');
  38. RouterUtil.hideKeyboard(context);
  39. if (type == 'mobile') {
  40. if (model?.flashLoginEnable == '1') {
  41. // QuickLoginUtil.getInstance().openQuickLogin(context, model?.quick);
  42. MobUtil.openQuickLoginPage(context, model?.quick);
  43. } else {
  44. Navigator.push(context, CupertinoPageRoute(builder: (_) => LoginAccountPage(null)));
  45. }
  46. }
  47. }
  48. /// 返回上一页
  49. void _openPop() {
  50. if (Navigator.canPop(context)) {
  51. Navigator.pop(context);
  52. }
  53. }
  54. /// 第三方登陆
  55. void _otherLoginClick(BottomIcons model) {
  56. print('第三方登陆${model.type}');
  57. }
  58. /// 跳到用户协议
  59. void _jumpUserAgreement(String url) {
  60. if (!EmptyUtil.isEmpty(url)) {
  61. print('协议');
  62. RouterUtil.openWebview(url, context);
  63. }
  64. }
  65. /// 展开关闭其它登陆
  66. void _showOrColoseOtherLogin() {
  67. setState(() {
  68. _showOther = !_showOther;
  69. });
  70. }
  71. final _sizedHeight50 = const SizedBox(height: 50);
  72. final _sizedHeight9 = const SizedBox(height: 9);
  73. final _sizedHeight18 = const SizedBox(height: 18);
  74. final _sizedHeight21 = const SizedBox(height: 21);
  75. bool _showOther = true;
  76. @override
  77. Widget build(BuildContext context) {
  78. return BlocConsumer<LoginBloc, LoginState>(
  79. listener: (context, state) {
  80. // Fluttertoast.showToast(msg: '网络异常');
  81. },
  82. buildWhen: (prev, current) {
  83. if (current is LoginErrorState) {
  84. return false;
  85. }
  86. return true;
  87. },
  88. builder: (context, state) {
  89. if (state is LoginCacheState) {
  90. return _getMainWidget(state.model);
  91. }
  92. if (state is LoginLoadedState) {
  93. return _getMainWidget(state.model);
  94. }
  95. return LoginPageSkeleton(); // 骨架屏幕
  96. },
  97. );
  98. }
  99. /// 主视图
  100. Widget _getMainWidget(LoginModel model) {
  101. return Column(
  102. children: <Widget>[
  103. /// 头部
  104. _headWidget(model),
  105. _sizedHeight50,
  106. /// 按钮
  107. _buttonsWidget(model),
  108. _sizedHeight9,
  109. /// 协议
  110. _protocolWidget(model),
  111. /// 其它登陆方式
  112. _otherLoginWidget(model),
  113. ],
  114. );
  115. }
  116. /// 头部Widget
  117. Widget _headWidget(LoginModel model) {
  118. return Container(
  119. height: 228 + MediaQuery.of(context).padding.top,
  120. width: double.infinity,
  121. decoration: BoxDecoration(
  122. image: DecorationImage(
  123. image: CachedNetworkImageProvider(model?.main?.backgroundImg ?? ''),
  124. fit: BoxFit.fill,
  125. ),
  126. ),
  127. child: Stack(
  128. alignment: Alignment.center,
  129. children: <Widget>[
  130. AppBar(
  131. backgroundColor: Colors.transparent,
  132. elevation: 0,
  133. leading: IconButton(
  134. icon: Icon(
  135. Icons.arrow_back_ios,
  136. size: 22,
  137. color: HexColor.fromHex('#333333'),
  138. ),
  139. onPressed: () => _openPop(),
  140. ),
  141. ),
  142. Column(
  143. crossAxisAlignment: CrossAxisAlignment.center,
  144. mainAxisAlignment: MainAxisAlignment.center,
  145. children: <Widget>[
  146. /// logo
  147. Container(
  148. margin: EdgeInsets.only(bottom: 12, top: MediaQuery.of(context).padding.top),
  149. decoration: BoxDecoration(
  150. borderRadius: BorderRadius.circular(14),
  151. boxShadow: [
  152. BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0), blurRadius: 10.0, spreadRadius: 1.0),
  153. BoxShadow(color: Colors.grey[300], offset: Offset(0.0, 0.0)),
  154. ],
  155. ),
  156. height: 80,
  157. width: 80,
  158. child: CachedNetworkImage(imageUrl: model?.logoImg ?? ''),
  159. ),
  160. /// logo 名字
  161. CachedNetworkImage(
  162. imageUrl: model?.main?.appNameImg ?? '',
  163. width: 90,
  164. ),
  165. ],
  166. ),
  167. ],
  168. ),
  169. );
  170. }
  171. /// 按钮
  172. Widget _buttonsWidget(LoginModel model) {
  173. return Container(
  174. padding: const EdgeInsets.symmetric(horizontal: 27.5),
  175. child: Column(
  176. children: model.main.importanceLogin.map((item) {
  177. return Padding(
  178. padding: const EdgeInsets.only(bottom: 8),
  179. child: _customButton(
  180. height: 40,
  181. text: item?.btnText,
  182. iconUrl: item?.btnMobileIcon ?? '',
  183. textColor: item?.btnTextColor,
  184. bgColor: item?.btnBgColor,
  185. borderColor: item?.btnBorderColor,
  186. onTap: () => _loginClick(item?.type, model)),
  187. );
  188. }).toList(),
  189. ),
  190. );
  191. }
  192. /// 协议
  193. Widget _protocolWidget(LoginModel model) {
  194. return RichText(
  195. text: TextSpan(
  196. text: '',
  197. children: model.main.agreements.map((item) {
  198. return TextSpan(
  199. text: item?.text,
  200. style: TextStyle(color: HexColor.fromHex(item?.textColor), fontSize: 10),
  201. recognizer: TapGestureRecognizer()
  202. ..onTap = () {
  203. _jumpUserAgreement(item?.url);
  204. });
  205. }).toList()),
  206. );
  207. }
  208. /// 其它登陆方式
  209. Widget _otherLoginWidget(LoginModel model) {
  210. return Expanded(
  211. child: Column(
  212. mainAxisAlignment: MainAxisAlignment.end,
  213. children: <Widget>[
  214. _getOtherLoginTitle(model),
  215. _sizedHeight18,
  216. Visibility(visible: _showOther, child: _getOtherLoginIcons(model)),
  217. Visibility(visible: _showOther, child: _sizedHeight21),
  218. ],
  219. ),
  220. );
  221. }
  222. /// 其它登陆方式的title
  223. Widget _getOtherLoginTitle(LoginModel model) {
  224. return GestureDetector(
  225. behavior: HitTestBehavior.opaque,
  226. onTap: () => _showOrColoseOtherLogin(),
  227. child: Row(
  228. mainAxisAlignment: MainAxisAlignment.center,
  229. crossAxisAlignment: CrossAxisAlignment.center,
  230. children: <Widget>[
  231. Text('${model?.main?.otherIconsTitle}', style: TextStyle(fontSize: 13, color: HexColor.fromHex(model?.main?.otherIconsTitleColor))),
  232. SizedBox(width: 5.5),
  233. RotatedBox(
  234. quarterTurns: _showOther ? 0 : 2,
  235. child: CachedNetworkImage(imageUrl: model?.main?.otherExpansionIcon ?? '', width: 12),
  236. ),
  237. ],
  238. ),
  239. );
  240. }
  241. /// 其它登陆方式的按钮
  242. Widget _getOtherLoginIcons(LoginModel model) {
  243. return Row(
  244. mainAxisAlignment: MainAxisAlignment.center,
  245. children: model.main.bottomIcons.map((item) {
  246. return GestureDetector(
  247. behavior: HitTestBehavior.opaque,
  248. onTap: () => _otherLoginClick(item),
  249. child: Container(
  250. width: 30,
  251. margin: const EdgeInsets.symmetric(horizontal: 20),
  252. child: CachedNetworkImage(imageUrl: item?.img ?? ''),
  253. ),
  254. );
  255. }).toList(),
  256. );
  257. }
  258. /// 自定义按钮
  259. Widget _customButton({double height, String text, String iconUrl, String textColor, String bgColor, String borderColor, GestureTapCallback onTap}) {
  260. return GestureDetector(
  261. onTap: onTap,
  262. child: Container(
  263. width: double.infinity,
  264. height: height ?? 0,
  265. decoration: BoxDecoration(
  266. border: Border.all(color: HexColor.fromHex(borderColor), width: 0.5),
  267. borderRadius: BorderRadius.circular(height ?? 0 / 2),
  268. color: HexColor.fromHex(bgColor),
  269. ),
  270. child: Row(
  271. mainAxisAlignment: MainAxisAlignment.center,
  272. crossAxisAlignment: CrossAxisAlignment.center,
  273. children: <Widget>[
  274. // icon
  275. CachedNetworkImage(imageUrl: iconUrl, width: 12),
  276. SizedBox(width: 8),
  277. // text
  278. Text(text, style: TextStyle(color: HexColor.fromHex(textColor), fontSize: 15))
  279. ],
  280. ),
  281. ),
  282. );
  283. }
  284. }