基础组件库
 
 
 
 
 

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