| @@ -1,11 +1,12 @@ | |||
| import 'dart:async'; | |||
| import 'dart:convert' as convert; | |||
| import 'package:zhiying_base_widget/pages/withdraw_page/withdraw_model.dart'; | |||
| import 'package:zhiying_base_widget/pages/withdraw_page/models/withdraw_model.dart'; | |||
| import 'package:zhiying_comm/util/base_bloc.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| class WithdrawBloc extends BlocBase { | |||
| WithdrawModel model; | |||
| WithdrawModel _model; | |||
| StreamController<WithdrawModel> _dataController = | |||
| StreamController<WithdrawModel>(); | |||
| @@ -33,15 +34,18 @@ class WithdrawBloc extends BlocBase { | |||
| if (json == null || json.length == 0) { | |||
| return; | |||
| } | |||
| // List mods = json['mod_list']; | |||
| // if (mods.first != null) { | |||
| // json = Map<String, dynamic>.from(mods.first); | |||
| // String d = json['data']; | |||
| // Map<String, dynamic> da = | |||
| // Map<String, dynamic>.from(convert.jsonDecode(d)); | |||
| // _model = SecurityBindAlipayModel.fromJson(da); | |||
| // _dataController.add(_model); | |||
| // } | |||
| List mods = json['mod_list']; | |||
| if (mods.first != null) { | |||
| json = Map<String, dynamic>.from(mods.first); | |||
| String d = json['data']; | |||
| if (json.containsKey('data')) { | |||
| String d = json['data']; | |||
| Map<String, dynamic> da = | |||
| Map<String, dynamic>.from(convert.jsonDecode(d)); | |||
| _model = WithdrawModel.fromJson(da); | |||
| _dataController.add(_model); | |||
| } | |||
| } | |||
| } catch (err) { | |||
| Logger.error(err); | |||
| } | |||
| @@ -0,0 +1,166 @@ | |||
| class WithdrawModel { | |||
| String appBarName; | |||
| String appBarNameColor; | |||
| String appBarBgColor; | |||
| String appBarBgImg; | |||
| String appBarRightText; | |||
| String appBarRightTextColor; | |||
| String appBarRightIcon; | |||
| String availableCashOutText; | |||
| String availableCashOutTextColor; | |||
| String availableCashOutBgImg; | |||
| String unbindAlipayImg; | |||
| String bindAlipayImg; | |||
| String unbindAlipayText; | |||
| String bindAlipayText; | |||
| String unbindAlipayGotoText; | |||
| String bindAlipayGotoText; | |||
| String isCashOutType; | |||
| List<WithdrawDashbordItems> cashOutDashbordItems; | |||
| String cashOutDashbordItemsUnselectedColor; | |||
| String cashOutDashbordItemsSelectedColor; | |||
| String cashOutDashbordItemsSelectedBgColor; | |||
| String cashOutDashbordItemsUnselectedBgColor; | |||
| String cashOutBtnText; | |||
| String cashOutBtnTextAvailableColor; | |||
| String cashOutBtnTextAvailableBgColor; | |||
| String cashOutBtnTextUnavailableColor; | |||
| String cashOutBtnTextUnavailableBgColor; | |||
| String cashOutTips; | |||
| WithdrawModel( | |||
| {this.appBarName, | |||
| this.appBarNameColor, | |||
| this.appBarBgColor, | |||
| this.appBarBgImg, | |||
| this.appBarRightText, | |||
| this.appBarRightTextColor, | |||
| this.appBarRightIcon, | |||
| this.availableCashOutText, | |||
| this.availableCashOutTextColor, | |||
| this.availableCashOutBgImg, | |||
| this.unbindAlipayImg, | |||
| this.bindAlipayImg, | |||
| this.unbindAlipayText, | |||
| this.bindAlipayText, | |||
| this.unbindAlipayGotoText, | |||
| this.bindAlipayGotoText, | |||
| this.isCashOutType, | |||
| this.cashOutDashbordItems, | |||
| this.cashOutDashbordItemsUnselectedColor, | |||
| this.cashOutDashbordItemsSelectedColor, | |||
| this.cashOutDashbordItemsSelectedBgColor, | |||
| this.cashOutDashbordItemsUnselectedBgColor, | |||
| this.cashOutBtnText, | |||
| this.cashOutBtnTextAvailableColor, | |||
| this.cashOutBtnTextAvailableBgColor, | |||
| this.cashOutBtnTextUnavailableColor, | |||
| this.cashOutBtnTextUnavailableBgColor, | |||
| this.cashOutTips}); | |||
| WithdrawModel.fromJson(Map<String, dynamic> json) { | |||
| appBarName = json['app_bar_name']; | |||
| appBarNameColor = json['app_bar_name_color']; | |||
| appBarBgColor = json['app_bar_bg_color']; | |||
| appBarBgImg = json['app_bar_bg_img']; | |||
| appBarRightText = json['app_bar_right_text']; | |||
| appBarRightTextColor = json['app_bar_right_text_color']; | |||
| appBarRightIcon = json['app_bar_right_icon']; | |||
| availableCashOutText = json['available_cash_out_text']; | |||
| availableCashOutTextColor = json['available_cash_out_text_color']; | |||
| availableCashOutBgImg = json['available_cash_out_bg_img']; | |||
| unbindAlipayImg = json['unbind_alipay_img']; | |||
| bindAlipayImg = json['bind_alipay_img']; | |||
| unbindAlipayText = json['unbind_alipay_text']; | |||
| bindAlipayText = json['bind_alipay_text']; | |||
| unbindAlipayGotoText = json['unbind_alipay_goto_text']; | |||
| bindAlipayGotoText = json['bind_alipay_goto_text']; | |||
| isCashOutType = json['is_cash_out_type']; | |||
| if (json['cash_out_dashbord_items'] != null) { | |||
| cashOutDashbordItems = new List<WithdrawDashbordItems>(); | |||
| json['cash_out_dashbord_items'].forEach((v) { | |||
| cashOutDashbordItems.add(new WithdrawDashbordItems.fromJson(v)); | |||
| }); | |||
| } | |||
| cashOutDashbordItemsUnselectedColor = | |||
| json['cash_out_dashbord_items_unselected_color']; | |||
| cashOutDashbordItemsSelectedColor = | |||
| json['cash_out_dashbord_items_selected_color']; | |||
| cashOutDashbordItemsSelectedBgColor = | |||
| json['cash_out_dashbord_items_selected_bg_color']; | |||
| cashOutDashbordItemsUnselectedBgColor = | |||
| json['cash_out_dashbord_items_unselected_bg_color']; | |||
| cashOutBtnText = json['cash_out_btn_text']; | |||
| cashOutBtnTextAvailableColor = json['cash_out_btn_text_available_color']; | |||
| cashOutBtnTextAvailableBgColor = | |||
| json['cash_out_btn_text_available_bg_color']; | |||
| cashOutBtnTextUnavailableColor = | |||
| json['cash_out_btn_text_unavailable_color']; | |||
| cashOutBtnTextUnavailableBgColor = | |||
| json['cash_out_btn_text_unavailable_bg_color']; | |||
| cashOutTips = json['cash_out_tips']; | |||
| } | |||
| Map<String, dynamic> toJson() { | |||
| final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
| data['app_bar_name'] = this.appBarName; | |||
| data['app_bar_name_color'] = this.appBarNameColor; | |||
| data['app_bar_bg_color'] = this.appBarBgColor; | |||
| data['app_bar_bg_img'] = this.appBarBgImg; | |||
| data['app_bar_right_text'] = this.appBarRightText; | |||
| data['app_bar_right_text_color'] = this.appBarRightTextColor; | |||
| data['app_bar_right_icon'] = this.appBarRightIcon; | |||
| data['available_cash_out_text'] = this.availableCashOutText; | |||
| data['available_cash_out_text_color'] = this.availableCashOutTextColor; | |||
| data['available_cash_out_bg_img'] = this.availableCashOutBgImg; | |||
| data['unbind_alipay_img'] = this.unbindAlipayImg; | |||
| data['bind_alipay_img'] = this.bindAlipayImg; | |||
| data['unbind_alipay_text'] = this.unbindAlipayText; | |||
| data['bind_alipay_text'] = this.bindAlipayText; | |||
| data['unbind_alipay_goto_text'] = this.unbindAlipayGotoText; | |||
| data['bind_alipay_goto_text'] = this.bindAlipayGotoText; | |||
| data['is_cash_out_type'] = this.isCashOutType; | |||
| if (this.cashOutDashbordItems != null) { | |||
| data['cash_out_dashbord_items'] = | |||
| this.cashOutDashbordItems.map((v) => v.toJson()).toList(); | |||
| } | |||
| data['cash_out_dashbord_items_unselected_color'] = | |||
| this.cashOutDashbordItemsUnselectedColor; | |||
| data['cash_out_dashbord_items_selected_color'] = | |||
| this.cashOutDashbordItemsSelectedColor; | |||
| data['cash_out_dashbord_items_selected_bg_color'] = | |||
| this.cashOutDashbordItemsSelectedBgColor; | |||
| data['cash_out_dashbord_items_unselected_bg_color'] = | |||
| this.cashOutDashbordItemsUnselectedBgColor; | |||
| data['cash_out_btn_text'] = this.cashOutBtnText; | |||
| data['cash_out_btn_text_available_color'] = | |||
| this.cashOutBtnTextAvailableColor; | |||
| data['cash_out_btn_text_available_bg_color'] = | |||
| this.cashOutBtnTextAvailableBgColor; | |||
| data['cash_out_btn_text_unavailable_color'] = | |||
| this.cashOutBtnTextUnavailableColor; | |||
| data['cash_out_btn_text_unavailable_bg_color'] = | |||
| this.cashOutBtnTextUnavailableBgColor; | |||
| data['cash_out_tips'] = this.cashOutTips; | |||
| return data; | |||
| } | |||
| } | |||
| class WithdrawDashbordItems { | |||
| String name; | |||
| String value; | |||
| WithdrawDashbordItems({this.name, this.value}); | |||
| WithdrawDashbordItems.fromJson(Map<String, dynamic> json) { | |||
| name = json['name']; | |||
| value = json['value']; | |||
| } | |||
| Map<String, dynamic> toJson() { | |||
| final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
| data['name'] = this.name; | |||
| data['value'] = this.value; | |||
| return data; | |||
| } | |||
| } | |||
| @@ -1 +0,0 @@ | |||
| class WithdrawModel {} | |||
| @@ -1,7 +1,11 @@ | |||
| import 'package:flutter/cupertino.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter/services.dart'; | |||
| import 'package:zhiying_base_widget/pages/withdraw_page/bloc/withdraw_bloc.dart'; | |||
| import 'package:zhiying_base_widget/pages/withdraw_page/models/withdraw_model.dart'; | |||
| import 'package:zhiying_base_widget/pages/withdraw_page/withdraw_page_sk.dart'; | |||
| import 'package:zhiying_comm/util/base_bloc.dart'; | |||
| import 'package:zhiying_comm/zhiying_comm.dart'; | |||
| /*提现页面*/ | |||
| class WithdrawPage extends StatefulWidget { | |||
| @@ -16,12 +20,18 @@ class WithdrawPage extends StatefulWidget { | |||
| class _WithdrawPageState extends State<WithdrawPage> { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Scaffold( | |||
| appBar: _createNav(), | |||
| body: SafeArea( | |||
| child: BlocProvider<WithdrawBloc>( | |||
| bloc: WithdrawBloc(), | |||
| child: _WithdrawContainer(widget.data), | |||
| return GestureDetector( | |||
| onTap: () { | |||
| FocusScope.of(context).requestFocus(FocusNode()); | |||
| }, | |||
| child: Scaffold( | |||
| appBar: _createNav(), | |||
| backgroundColor: Colors.white, | |||
| body: SafeArea( | |||
| child: BlocProvider<WithdrawBloc>( | |||
| bloc: WithdrawBloc(), | |||
| child: _WithdrawContainer(widget.data), | |||
| ), | |||
| ), | |||
| ), | |||
| ); | |||
| @@ -76,6 +86,11 @@ class _WithdrawContainer extends StatefulWidget { | |||
| class _WithdrawContainerState extends State<_WithdrawContainer> { | |||
| WithdrawBloc _bloc; | |||
| int _currentIndex = 0; | |||
| TextEditingController _controller = TextEditingController(); | |||
| bool _submitable = false; | |||
| bool _inputable = false; | |||
| @override | |||
| void initState() { | |||
| _bloc = BlocProvider.of<WithdrawBloc>(context); | |||
| @@ -88,9 +103,269 @@ class _WithdrawContainerState extends State<_WithdrawContainer> { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return SingleChildScrollView( | |||
| child: StreamBuilder<WithdrawModel>( | |||
| stream: _bloc.outData, | |||
| builder: (BuildContext context, AsyncSnapshot snapshot) { | |||
| WithdrawModel model = snapshot.data; | |||
| if (model == null) { | |||
| return WithdrawPageSketelon(); | |||
| } | |||
| return Container( | |||
| margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 8), | |||
| child: Column( | |||
| children: <Widget>[ | |||
| _createHeader(model), | |||
| _createVerify(model), | |||
| _createPrice(model), | |||
| _createInput(model), | |||
| _createSubmit(model), | |||
| _createDesc(model), | |||
| ], | |||
| ), | |||
| ); | |||
| }), | |||
| // child: Column( | |||
| // children: <Widget>[], | |||
| // ), | |||
| ); | |||
| } | |||
| Widget _createHeader(WithdrawModel model) { | |||
| return Container( | |||
| width: double.infinity, | |||
| height: 97, | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, borderRadius: BorderRadius.circular(10)), | |||
| child: Stack( | |||
| children: <Widget>[ | |||
| Container( | |||
| width: double.infinity, | |||
| height: double.infinity, | |||
| child: CachedNetworkImage( | |||
| imageUrl: model.availableCashOutBgImg ?? '', | |||
| fit: BoxFit.fill, | |||
| ), | |||
| ), | |||
| Center( | |||
| child: Column( | |||
| mainAxisAlignment: MainAxisAlignment.center, | |||
| children: <Widget>[ | |||
| Text( | |||
| '¥0.03', | |||
| style: TextStyle( | |||
| color: Colors.white, | |||
| fontSize: 30, | |||
| ), | |||
| ), | |||
| Text( | |||
| '可提现总余额', | |||
| style: TextStyle( | |||
| color: Colors.white, | |||
| fontSize: 14, | |||
| ), | |||
| ), | |||
| ], | |||
| ), | |||
| ) | |||
| ], | |||
| ), | |||
| ); | |||
| } | |||
| Widget _createVerify(WithdrawModel model) { | |||
| return GestureDetector( | |||
| behavior: HitTestBehavior.opaque, | |||
| onTap: () { | |||
| Logger.debug('绑定支付宝'); | |||
| }, | |||
| child: Container( | |||
| margin: EdgeInsets.only(top: 8, bottom: 8), | |||
| child: Row( | |||
| children: <Widget>[ | |||
| CachedNetworkImage( | |||
| imageUrl: model.unbindAlipayImg, | |||
| height: 23, | |||
| ), | |||
| Expanded( | |||
| child: Padding( | |||
| padding: const EdgeInsets.only(left: 8, right: 8), | |||
| child: Text( | |||
| model.unbindAlipayText, | |||
| style: TextStyle(fontSize: 11, color: Color(0xff999999)), | |||
| ), | |||
| ), | |||
| ), | |||
| Icon( | |||
| Icons.arrow_forward_ios, | |||
| size: 12, | |||
| color: Color(0xff999999), | |||
| ) | |||
| ], | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| Widget _createPrice(WithdrawModel model) { | |||
| return GridView.builder( | |||
| shrinkWrap: true, | |||
| physics: NeverScrollableScrollPhysics(), | |||
| gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( | |||
| crossAxisCount: 3, | |||
| crossAxisSpacing: 10, | |||
| mainAxisSpacing: 10, | |||
| childAspectRatio: 2.5, | |||
| ), | |||
| itemCount: model?.cashOutDashbordItems?.length ?? 0, | |||
| itemBuilder: (BuildContext context, int index) { | |||
| WithdrawDashbordItems item = model.cashOutDashbordItems[index]; | |||
| return GestureDetector( | |||
| onTap: () { | |||
| _controller.text = item.value; | |||
| _currentIndex = index; | |||
| _inputable = item.value == null || item.value == ''; | |||
| _checkSubmit(item.value); | |||
| }, | |||
| child: Container( | |||
| decoration: BoxDecoration( | |||
| color: index == _currentIndex | |||
| ? HexColor.fromHex( | |||
| model.cashOutDashbordItemsSelectedBgColor ?? '') | |||
| : HexColor.fromHex( | |||
| model.cashOutDashbordItemsUnselectedBgColor ?? ''), | |||
| borderRadius: BorderRadius.circular(5), | |||
| border: Border.all( | |||
| color: index == _currentIndex | |||
| ? HexColor.fromHex( | |||
| model.cashOutDashbordItemsSelectedColor ?? '') | |||
| : HexColor.fromHex('#d2d2d2'), | |||
| ), | |||
| ), | |||
| child: Center( | |||
| child: Text( | |||
| item.name, | |||
| style: TextStyle( | |||
| fontSize: 14, | |||
| color: index == _currentIndex | |||
| ? HexColor.fromHex( | |||
| model.cashOutDashbordItemsSelectedColor ?? '') | |||
| : HexColor.fromHex( | |||
| model.cashOutDashbordItemsUnselectedColor ?? ''), | |||
| ), | |||
| ), | |||
| ), | |||
| ), | |||
| ); | |||
| }, | |||
| ); | |||
| } | |||
| Widget _createInput(WithdrawModel model) { | |||
| return Padding( | |||
| padding: const EdgeInsets.only(top: 8.0), | |||
| child: Column( | |||
| children: <Widget>[], | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| mainAxisAlignment: MainAxisAlignment.start, | |||
| children: <Widget>[ | |||
| Text( | |||
| '提现金额', | |||
| style: TextStyle( | |||
| fontWeight: FontWeight.bold, | |||
| color: Color(0xff333333), | |||
| ), | |||
| ), | |||
| Container( | |||
| width: double.infinity, | |||
| height: 50, | |||
| child: CupertinoTextField( | |||
| placeholder: '输入提现金额', | |||
| controller: _controller, | |||
| enabled: _inputable, | |||
| style: TextStyle( | |||
| fontSize: 30, | |||
| color: Color(0xff333333), | |||
| fontFamily: 'Din-Bold', | |||
| package: 'zhiying_base_widget', | |||
| ), | |||
| decoration: BoxDecoration(color: Colors.transparent), | |||
| keyboardType: TextInputType.numberWithOptions(decimal: true), | |||
| textInputAction: TextInputAction.done, | |||
| inputFormatters: [ | |||
| WhitelistingTextInputFormatter(RegExp("[0-9.]")), //只允许输入小数 | |||
| ], | |||
| prefix: Text( | |||
| '¥', | |||
| style: TextStyle(fontSize: 20), | |||
| ), | |||
| onChanged: (value) { | |||
| _checkSubmit(value); | |||
| }, | |||
| ), | |||
| ), | |||
| Container( | |||
| margin: EdgeInsets.only(top: 5, bottom: 20), | |||
| width: double.infinity, | |||
| height: 0.5, | |||
| color: Color(0xffe4e4e4), | |||
| ), | |||
| ], | |||
| ), | |||
| ); | |||
| } | |||
| Widget _createSubmit(WithdrawModel model) { | |||
| return Container( | |||
| height: 50, | |||
| decoration: BoxDecoration( | |||
| color: _submitable | |||
| ? HexColor.fromHex(model.cashOutBtnTextAvailableBgColor ?? '') | |||
| : HexColor.fromHex(model.cashOutBtnTextUnavailableBgColor ?? ''), | |||
| borderRadius: BorderRadius.circular(7.5), | |||
| ), | |||
| child: Center( | |||
| child: Text( | |||
| model.cashOutBtnText ?? '', | |||
| style: TextStyle( | |||
| fontSize: 15, | |||
| color: _submitable | |||
| ? HexColor.fromHex(model.cashOutBtnTextAvailableColor ?? '') | |||
| : HexColor.fromHex(model.cashOutBtnTextUnavailableColor ?? ''), | |||
| ), | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| Widget _createDesc(WithdrawModel model) { | |||
| return Column( | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| mainAxisAlignment: MainAxisAlignment.start, | |||
| children: <Widget>[ | |||
| Container( | |||
| width: double.infinity, | |||
| margin: EdgeInsets.only(top: 8), | |||
| child: Text( | |||
| '提现说明', | |||
| style: TextStyle( | |||
| fontWeight: FontWeight.bold, | |||
| color: Color(0xff333333), | |||
| ), | |||
| ), | |||
| ), | |||
| Text( | |||
| model.cashOutTips ?? '', | |||
| style: TextStyle( | |||
| color: Color(0xff999999), | |||
| fontSize: 14, | |||
| ), | |||
| ), | |||
| ], | |||
| ); | |||
| } | |||
| void _checkSubmit(String value) { | |||
| _submitable = value.length > 0; | |||
| setState(() {}); | |||
| } | |||
| } | |||
| @@ -0,0 +1,69 @@ | |||
| import 'package:flutter/cupertino.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:shimmer/shimmer.dart'; | |||
| class WithdrawPageSketelon extends StatelessWidget { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Shimmer.fromColors( | |||
| baseColor: Colors.grey[300], | |||
| highlightColor: Colors.grey[100], | |||
| child: Container( | |||
| margin: EdgeInsets.only(left: 12.5, right: 12.5, top: 8), | |||
| child: Column( | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| children: <Widget>[ | |||
| Container( | |||
| width: double.infinity, | |||
| height: 97, | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, borderRadius: BorderRadius.circular(10)), | |||
| ), | |||
| Container( | |||
| margin: EdgeInsets.only(top: 8, bottom: 8), | |||
| height: 20, | |||
| color: Colors.white, | |||
| width: 200, | |||
| ), | |||
| GridView.builder( | |||
| shrinkWrap: true, | |||
| physics: NeverScrollableScrollPhysics(), | |||
| gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( | |||
| crossAxisCount: 3, | |||
| crossAxisSpacing: 10, | |||
| mainAxisSpacing: 10, | |||
| childAspectRatio: 2.5, | |||
| ), | |||
| itemCount: 6, | |||
| itemBuilder: (BuildContext context, int index) { | |||
| return Container( | |||
| decoration: BoxDecoration( | |||
| color: Colors.white, | |||
| borderRadius: BorderRadius.circular(5)), | |||
| ); | |||
| }, | |||
| ), | |||
| Container( | |||
| margin: EdgeInsets.only(top: 28, bottom: 0), | |||
| height: 60, | |||
| color: Colors.white, | |||
| width: double.infinity, | |||
| ), | |||
| Container( | |||
| margin: EdgeInsets.only(top: 8, bottom: 0), | |||
| height: 20, | |||
| color: Colors.white, | |||
| width: 200, | |||
| ), | |||
| Container( | |||
| margin: EdgeInsets.only(top: 8, bottom: 0), | |||
| height: 20, | |||
| color: Colors.white, | |||
| width: 150, | |||
| ), | |||
| ], | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| } | |||