基础库
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 

298 Zeilen
8.6 KiB

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