基础库
 
 
 
 
 

407 lines
12 KiB

  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_bloc/flutter_bloc.dart';
  4. import 'package:provider/provider.dart';
  5. import 'package:zhiying_comm/pages/login_page/model/login_model.dart';
  6. import 'package:zhiying_comm/util/empty_util.dart';
  7. import 'package:zhiying_comm/util/mob_util/mob_util.dart';
  8. import 'package:zhiying_comm/zhiying_comm.dart';
  9. import 'bloc/bloc.dart';
  10. import 'bloc/login_invite_repository.dart';
  11. import 'model/login_invite_user.dart';
  12. ///
  13. /// 邀请页面
  14. ///
  15. class LoginInvitePage extends StatelessWidget {
  16. @override
  17. Widget build(BuildContext context) {
  18. return Scaffold(
  19. resizeToAvoidBottomInset: false,
  20. backgroundColor: HexColor.fromHex('#FFFFFF'),
  21. body: BlocProvider(
  22. create: (_) => LoginInviteBloc(repostitory: LoginInviteRepository())
  23. ..add(LoginInviteInitEvent()),
  24. child: LoginInvitePageContainer(),
  25. ),
  26. );
  27. }
  28. }
  29. ///
  30. /// 邀请
  31. class LoginInvitePageContainer extends StatefulWidget {
  32. @override
  33. _LoginInvitePageContainerState createState() =>
  34. _LoginInvitePageContainerState();
  35. }
  36. class _LoginInvitePageContainerState extends State<LoginInvitePageContainer> {
  37. TextEditingController _editingController;
  38. FocusNode _focusNode;
  39. bool _showInviteInfo = false;
  40. // 是否登录中
  41. bool _isLogging = false;
  42. /// 返回上一页
  43. void _openPop() {
  44. if (Navigator.canPop(context)) {
  45. Navigator.pop(context);
  46. }
  47. }
  48. /// 注册成功跳转
  49. void _successJump() {
  50. RouterUtil.hideKeyboard(context);
  51. Navigator.pushAndRemoveUntil(
  52. context,
  53. MaterialPageRoute(
  54. builder: (BuildContext context) =>
  55. PageFactory.create('homePage', null)),
  56. (Route<dynamic> route) => false,
  57. );
  58. }
  59. /// 输入框输入变化
  60. void _onChange(String string) {
  61. setState(() {
  62. _showInviteInfo = false;
  63. });
  64. print('$string');
  65. if (!EmptyUtil.isEmpty(string) && string.length >= 3) {
  66. _queryInviteInfo(string);
  67. }
  68. }
  69. /// 查询邀请人
  70. void _queryInviteInfo(String inviteNum) {
  71. if (!EmptyUtil.isEmpty(inviteNum) && inviteNum.length < 3) {
  72. return;
  73. }
  74. BlocProvider.of<LoginInviteBloc>(context)
  75. .add(LoginInviteQueryEvent(num: inviteNum));
  76. }
  77. /// 填写邀请啊吗
  78. void _submitOnClick(LoginInviteUser inviteUser) async {
  79. _focusNode.unfocus();
  80. /// 邀请码
  81. String inviteNum = inviteUser?.userId ?? '';
  82. /// 手机号
  83. UserInfoModel model =
  84. await Provider.of<UserInfoNotifier>(context, listen: false)
  85. ?.getUserInfoModel();
  86. String mobile = model?.mobile ?? '';
  87. if (!EmptyUtil.isEmpty(inviteNum) && !EmptyUtil.isEmpty(mobile)) {
  88. BlocProvider.of<LoginInviteBloc>(context)
  89. .add(LoginInviteSubmitEvent(mobile: mobile, num: inviteNum));
  90. }
  91. }
  92. @override
  93. void initState() {
  94. _editingController = TextEditingController();
  95. // SharedPreferencesUtil.setNetCacheResult(Constants.mobInvitedCode, tgid);
  96. MobUtil.getInvitedCode().then((value) {
  97. _editingController.text = value;
  98. _onChange(value);
  99. });
  100. _focusNode = FocusNode();
  101. super.initState();
  102. }
  103. @override
  104. void didChangeDependencies() {
  105. super.didChangeDependencies();
  106. }
  107. @override
  108. void dispose() {
  109. _editingController?.dispose();
  110. _focusNode?.unfocus();
  111. _focusNode?.dispose();
  112. super.dispose();
  113. }
  114. @override
  115. Widget build(BuildContext context) {
  116. return BlocConsumer<LoginInviteBloc, LoginInviteState>(
  117. listener: (context, state) {},
  118. buildWhen: (previous, current) {
  119. /// 提交失败
  120. if (current is LoginInviteSubmitErrorState) {
  121. return false;
  122. }
  123. /// 数据加载出错
  124. if (current is LoginInviteErrorState) {
  125. return false;
  126. }
  127. /// 查询邀请人失败
  128. if (current is LoginInviteQueryErrorState) {
  129. return false;
  130. }
  131. /// 邀请人查询成功
  132. if (current is LoginInviteQuerySuccessState) {
  133. _showInviteInfo = true;
  134. return true;
  135. }
  136. /// 邀请码成功 跳转
  137. if (current is LoginInviteSubmitSuccess) {
  138. // 缓存数据
  139. Provider.of<UserInfoNotifier>(context, listen: false)
  140. .setUserInfo(current.model);
  141. _successJump();
  142. return false;
  143. }
  144. return true;
  145. },
  146. builder: (context, state) {
  147. print(state);
  148. if (state is LoginInviteLoadedState) {
  149. return _getMainWidget(state.model, null);
  150. }
  151. if (state is LoginInviteQuerySuccessState) {
  152. return _getMainWidget(state.pageMdel, state.model);
  153. }
  154. /// 骨架屏
  155. return Container();
  156. },
  157. );
  158. }
  159. /// 主视图
  160. Widget _getMainWidget(LoginModel model, LoginInviteUser inviteUser) {
  161. return Column(
  162. children: <Widget>[
  163. /// appbar
  164. _getAppBar(model),
  165. /// 标题
  166. Padding(
  167. padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 40),
  168. child: _getTitleWidget(model)),
  169. /// 输入框
  170. Padding(
  171. padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 30),
  172. child: _getInviteInputWidget(model)),
  173. /// 邀请人信息
  174. Visibility(
  175. visible: inviteUser != null && _showInviteInfo,
  176. child: Padding(
  177. padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 8),
  178. child: _getInviteInfoWidget(inviteUser))),
  179. /// 按钮
  180. Padding(
  181. padding: const EdgeInsets.only(left: 27.5, right: 27.5, top: 30),
  182. child: _getSubmiBtnWidget(model, inviteUser)),
  183. ],
  184. );
  185. }
  186. /// appBar
  187. Widget _getAppBar(LoginModel model) {
  188. return AppBar(
  189. brightness: Brightness.light,
  190. backgroundColor: HexColor.fromHex('#FFFFFF'),
  191. elevation: 0,
  192. title: Text(
  193. model?.invite?.appBarTitle ?? '登录',
  194. style: TextStyle(
  195. color:
  196. HexColor.fromHex(model?.invite?.appBarTitleColor ?? '#333333')),
  197. ),
  198. centerTitle: true,
  199. leading: IconButton(
  200. icon: Icon(
  201. Icons.arrow_back_ios,
  202. size: 22,
  203. color: HexColor.fromHex('#333333'),
  204. ),
  205. onPressed: () => _openPop(),
  206. ),
  207. );
  208. }
  209. /// title
  210. Widget _getTitleWidget(LoginModel model) {
  211. return Align(
  212. alignment: Alignment.centerLeft,
  213. child: Text(
  214. model?.invite?.title ?? '输入邀请码',
  215. style: TextStyle(
  216. color: HexColor.fromHex(model?.invite?.titleColor ?? '#333333'),
  217. fontSize: 25),
  218. ));
  219. }
  220. /// 邀请码输入框
  221. Widget _getInviteInputWidget(LoginModel model) {
  222. return _getCustomInputWidget(
  223. hint: model?.invite?.inputInviteText ?? '请输入邀请码',
  224. controller: _editingController,
  225. focusNode: _focusNode,
  226. onChanged: _onChange,
  227. hintColor: model?.invite?.inputHintColor ?? '#999999',
  228. bgColor: model?.invite?.inputBgColor ?? '#F7F7F7',
  229. textColor: model?.invite?.inputInviteTextColor ?? '#333333',
  230. iconUrl: model?.invite?.inputInviteIcon ?? '');
  231. }
  232. /// 邀请人信息
  233. Widget _getInviteInfoWidget(LoginInviteUser model) {
  234. return Container(
  235. // height: 77.5,
  236. decoration: BoxDecoration(
  237. borderRadius: BorderRadius.circular(8),
  238. border: Border.all(color: HexColor.fromHex('#E8E8E8'), width: 0.5)),
  239. padding: const EdgeInsets.all(15),
  240. child: Row(
  241. children: <Widget>[
  242. /// 头像
  243. CircleAvatar(
  244. radius: 23.5,
  245. backgroundImage: CachedNetworkImageProvider(model?.avatar ?? ''),
  246. ),
  247. const SizedBox(width: 13),
  248. Column(
  249. mainAxisAlignment: MainAxisAlignment.spaceAround,
  250. crossAxisAlignment: CrossAxisAlignment.start,
  251. children: <Widget>[
  252. /// 名字
  253. Text(
  254. '${model?.nickname}',
  255. style: TextStyle(
  256. color: HexColor.fromHex(model?.nickNameColor),
  257. fontSize: 13),
  258. ),
  259. /// 邀请
  260. RichText(
  261. text: TextSpan(
  262. text: '邀请您进入',
  263. style: TextStyle(
  264. fontSize: 11,
  265. color: HexColor.fromHex(model?.nickNameColor)),
  266. children: [
  267. TextSpan(
  268. text: '${model?.appName}',
  269. style: TextStyle(
  270. fontSize: 11,
  271. color: HexColor.fromHex(model?.appNameColor)),
  272. ),
  273. ]),
  274. )
  275. ],
  276. )
  277. ],
  278. ),
  279. );
  280. }
  281. /// 按钮
  282. Widget _getSubmiBtnWidget(LoginModel model, LoginInviteUser inviteUser) {
  283. return Material(
  284. child: Container(
  285. height: 52,
  286. width: double.infinity,
  287. color: Colors.white,
  288. child: RaisedButton(
  289. child: Text(
  290. model?.invite?.btnSubmitText ?? '进入智莺生活',
  291. style: TextStyle(fontSize: 15),
  292. ),
  293. textColor:
  294. HexColor.fromHex(model?.invite?.btnSubmitTextColor ?? '#FFFFFF'),
  295. color: HexColor.fromHex(model?.invite?.btnSubmitBgColor ?? '#FF3939'),
  296. disabledColor:
  297. HexColor.fromHex(model?.invite?.btnBanBgColor ?? '#F5F5F5'),
  298. disabledTextColor:
  299. HexColor.fromHex(model?.invite?.btnBanTextColor ?? '#999999'),
  300. elevation: 5,
  301. shape: RoundedRectangleBorder(
  302. borderRadius: BorderRadius.circular(52 / 2)),
  303. onPressed: _showInviteInfo && inviteUser != null
  304. ? () => _submitOnClick(inviteUser)
  305. : null,
  306. ),
  307. ),
  308. );
  309. }
  310. /// 自定义输入框
  311. Widget _getCustomInputWidget({String hint,
  312. String hintColor,
  313. String bgColor,
  314. String textColor,
  315. String iconUrl,
  316. TextEditingController controller,
  317. ValueChanged<String> onChanged,
  318. FocusNode focusNode}) {
  319. var border = OutlineInputBorder(
  320. borderRadius: BorderRadius.circular(8),
  321. borderSide: BorderSide(color: HexColor.fromHex(bgColor), width: 0));
  322. return Container(
  323. height: 42,
  324. padding: const EdgeInsets.symmetric(horizontal: 15),
  325. decoration: BoxDecoration(
  326. color: HexColor.fromHex(bgColor),
  327. borderRadius: BorderRadius.circular(8),
  328. ),
  329. child: Row(
  330. mainAxisAlignment: MainAxisAlignment.start,
  331. crossAxisAlignment: CrossAxisAlignment.center,
  332. children: <Widget>[
  333. CachedNetworkImage(
  334. imageUrl: iconUrl ?? '',
  335. width: 10,
  336. ),
  337. Expanded(
  338. child: TextField(
  339. controller: controller,
  340. focusNode: focusNode,
  341. onChanged: onChanged,
  342. expands: false,
  343. style: TextStyle(color: HexColor.fromHex(textColor)),
  344. maxLines: 1,
  345. keyboardType: TextInputType.number,
  346. decoration: InputDecoration(
  347. contentPadding: EdgeInsets.only(top: 30, left: 7.5),
  348. hintText: hint,
  349. hintStyle:
  350. TextStyle(fontSize: 13, color: HexColor.fromHex(hintColor)),
  351. hintMaxLines: 1,
  352. filled: true,
  353. fillColor: Colors.transparent,
  354. border: border,
  355. focusedBorder: border,
  356. enabledBorder: border,
  357. disabledBorder: border,
  358. errorBorder: border,
  359. focusedErrorBorder: border,
  360. ),
  361. ),
  362. ),
  363. ],
  364. ),
  365. );
  366. }
  367. }