Showing
9 changed files
with
492 additions
and
14 deletions
lib/pages/my/contant_left_page.dart
0 → 100644
| 1 | +import 'package:flutter/material.dart'; | ||
| 2 | +import 'package:flutter_easyrefresh/easy_refresh.dart'; | ||
| 3 | +import 'package:flutter_screenutil/flutter_screenutil.dart'; | ||
| 4 | +import 'package:one_key/constant/state.dart'; | ||
| 5 | +import 'package:one_key/provider/contant_show_model.dart'; | ||
| 6 | +import 'package:one_key/provider/user_model.dart'; | ||
| 7 | +import 'package:one_key/res/colors.dart'; | ||
| 8 | + | ||
| 9 | +import 'package:one_key/widgets/page_exception.dart'; | ||
| 10 | +import 'package:one_key/widgets/v_empty_view.dart'; | ||
| 11 | +import 'package:provider/provider.dart'; | ||
| 12 | + | ||
| 13 | +class ContantLeftPage extends StatefulWidget { | ||
| 14 | + ContantLeftPage({Key key}) : super(key: key); | ||
| 15 | + | ||
| 16 | + @override | ||
| 17 | + _ContantLeftPageState createState() => _ContantLeftPageState(); | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +class _ContantLeftPageState extends State<ContantLeftPage> { | ||
| 21 | + EasyRefreshController _controller; | ||
| 22 | + ContantShowModel contantShowModel; | ||
| 23 | + | ||
| 24 | + @override | ||
| 25 | + void initState() { | ||
| 26 | + super.initState(); | ||
| 27 | + _controller = EasyRefreshController(); | ||
| 28 | + | ||
| 29 | + WidgetsBinding.instance.addPostFrameCallback((_) { | ||
| 30 | + _getContantData(); | ||
| 31 | + }); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + _getContantData() async { | ||
| 35 | + Map<String, String> params = { | ||
| 36 | + "sid": Provider.of<UserModel>(context, listen: false).user.sellerid, | ||
| 37 | + }; | ||
| 38 | + await contantShowModel.getUserHistorys(context, params); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + @override | ||
| 42 | + Widget build(BuildContext context) { | ||
| 43 | + contantShowModel = Provider.of<ContantShowModel>(context, listen: true); | ||
| 44 | + return Expanded( | ||
| 45 | + child: Consumer<ContantShowModel>( | ||
| 46 | + builder: (context, model, _) { | ||
| 47 | + if (model.pageStateLeft != PageState.Success) { | ||
| 48 | + return ExceptionPage( | ||
| 49 | + pageState: model.pageStateLeft, | ||
| 50 | + callback: () { | ||
| 51 | + // offset = 0; | ||
| 52 | + // getMessages(); | ||
| 53 | + _getContantData(); | ||
| 54 | + }, | ||
| 55 | + emptyMsg: "暂时没有联系人哦", | ||
| 56 | + emptyImg: "empty_search", | ||
| 57 | + showMsg: "加载中,请稍后...", | ||
| 58 | + ); | ||
| 59 | + } else { | ||
| 60 | + return EasyRefresh.custom( | ||
| 61 | + controller: _controller, | ||
| 62 | + slivers: [ | ||
| 63 | + SliverList(delegate: SliverChildBuilderDelegate( | ||
| 64 | + (BuildContext context, int index) { | ||
| 65 | + return Container( | ||
| 66 | + padding: EdgeInsets.symmetric( | ||
| 67 | + horizontal: ScreenUtil().setWidth(40), | ||
| 68 | + vertical: ScreenUtil().setWidth(30)), | ||
| 69 | + height: ScreenUtil().setWidth(74 * 2), | ||
| 70 | + decoration: BoxDecoration( | ||
| 71 | + border: Border( | ||
| 72 | + bottom: BorderSide( | ||
| 73 | + width: ScreenUtil().setWidth(2), | ||
| 74 | + color: MyColours.color_E0E0E0))), | ||
| 75 | + child: Column( | ||
| 76 | + crossAxisAlignment: CrossAxisAlignment.start, | ||
| 77 | + children: [ | ||
| 78 | + Text(model.userHistorys[index].rname, | ||
| 79 | + style: TextStyle( | ||
| 80 | + color: MyColours.color_333333, | ||
| 81 | + fontSize: ScreenUtil().setSp(32))), | ||
| 82 | + VEmptyView(10), | ||
| 83 | + Text(model.userHistorys[index].phone, | ||
| 84 | + style: TextStyle( | ||
| 85 | + color: MyColours.color_999999, | ||
| 86 | + fontSize: ScreenUtil().setSp(30))) | ||
| 87 | + ], | ||
| 88 | + ), | ||
| 89 | + ); | ||
| 90 | + })) | ||
| 91 | + ], | ||
| 92 | + // onRefresh: () async { | ||
| 93 | + // // offset = 0; | ||
| 94 | + // // getMessages(showLoading: false); | ||
| 95 | + // }, | ||
| 96 | + // onLoad: () async { | ||
| 97 | + // // offset++; | ||
| 98 | + // // getMessages(showLoading: false); | ||
| 99 | + // }, | ||
| 100 | + ); | ||
| 101 | + } | ||
| 102 | + }, | ||
| 103 | + ), | ||
| 104 | + ); | ||
| 105 | + } | ||
| 106 | +} |
lib/pages/my/contant_page.dart
0 → 100644
| 1 | +import 'package:flutter/material.dart'; | ||
| 2 | +import 'package:flutter/services.dart'; | ||
| 3 | + | ||
| 4 | +import 'package:contacts_service/contacts_service.dart'; | ||
| 5 | +import 'package:flutter_screenutil/screenutil.dart'; | ||
| 6 | +import 'package:intl/intl.dart'; | ||
| 7 | +import 'package:one_key/pages/my/contant_left_page.dart'; | ||
| 8 | +import 'package:one_key/provider/contant_show_model.dart'; | ||
| 9 | +import 'package:one_key/res/colors.dart'; | ||
| 10 | +import 'package:one_key/widgets/custom_tab_indicator.dart'; | ||
| 11 | +import 'package:one_key/widgets/system_app_bar.dart'; | ||
| 12 | +import 'package:provider/provider.dart'; | ||
| 13 | + | ||
| 14 | +class ContactListPage extends StatefulWidget { | ||
| 15 | + @override | ||
| 16 | + _ContactListPageState createState() => _ContactListPageState(); | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +class _ContactListPageState extends State<ContactListPage> { | ||
| 20 | + List<Contact> _contacts; | ||
| 21 | + List _tabBarTitle; | ||
| 22 | + | ||
| 23 | + @override | ||
| 24 | + void initState() { | ||
| 25 | + _tabBarTitle = ['预订联系人', '手机联系人']; | ||
| 26 | + super.initState(); | ||
| 27 | + refreshContacts(); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + Future<void> refreshContacts() async { | ||
| 31 | + // Load without thumbnails initially. | ||
| 32 | + var contacts = (await ContactsService.getContacts( | ||
| 33 | + withThumbnails: false, iOSLocalizedLabels: false)) | ||
| 34 | + .toList(); | ||
| 35 | +// var contacts = (await ContactsService.getContactsForPhone("8554964652")) | ||
| 36 | +// .toList(); | ||
| 37 | + setState(() { | ||
| 38 | + _contacts = contacts; | ||
| 39 | + }); | ||
| 40 | + | ||
| 41 | + // Lazy load thumbnails after rendering initial contacts. | ||
| 42 | + for (final contact in contacts) { | ||
| 43 | + ContactsService.getAvatar(contact).then((avatar) { | ||
| 44 | + if (avatar == null) return; // Don't redraw if no change. | ||
| 45 | + setState(() => contact.avatar = avatar); | ||
| 46 | + }); | ||
| 47 | + } | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + void updateContact() async { | ||
| 51 | + Contact ninja = _contacts | ||
| 52 | + .toList() | ||
| 53 | + .firstWhere((contact) => contact.familyName.startsWith("Ninja")); | ||
| 54 | + ninja.avatar = null; | ||
| 55 | + await ContactsService.updateContact(ninja); | ||
| 56 | + | ||
| 57 | + refreshContacts(); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + _openContactForm() async { | ||
| 61 | + try { | ||
| 62 | + var contact = | ||
| 63 | + await ContactsService.openContactForm(iOSLocalizedLabels: false); | ||
| 64 | + refreshContacts(); | ||
| 65 | + } on FormOperationException catch (e) { | ||
| 66 | + switch (e.errorCode) { | ||
| 67 | + case FormOperationErrorCode.FORM_OPERATION_CANCELED: | ||
| 68 | + case FormOperationErrorCode.FORM_COULD_NOT_BE_OPEN: | ||
| 69 | + case FormOperationErrorCode.FORM_OPERATION_UNKNOWN_ERROR: | ||
| 70 | + default: | ||
| 71 | + print(e.errorCode); | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + @override | ||
| 77 | + Widget build(BuildContext context) { | ||
| 78 | + return Scaffold( | ||
| 79 | + backgroundColor: MyColours.color_ffffff, | ||
| 80 | + appBar: SystemAppBar('联系人'), | ||
| 81 | + body: SafeArea( | ||
| 82 | + child: DefaultTabController( | ||
| 83 | + length: 2, | ||
| 84 | + child: Stack( | ||
| 85 | + children: <Widget>[ | ||
| 86 | + TabBarView( | ||
| 87 | + physics: NeverScrollableScrollPhysics(), | ||
| 88 | + children: <Widget>[ | ||
| 89 | + ChangeNotifierProvider<ContantShowModel>( | ||
| 90 | + create: (_) => ContantShowModel(), | ||
| 91 | + child: ContantLeftPage()), | ||
| 92 | + Container() | ||
| 93 | + ], | ||
| 94 | + ), | ||
| 95 | + Positioned( | ||
| 96 | + child: Container( | ||
| 97 | + padding: | ||
| 98 | + EdgeInsets.only(bottom: ScreenUtil().setWidth(10)), | ||
| 99 | + margin: EdgeInsets.symmetric( | ||
| 100 | + horizontal: ScreenUtil().setWidth(30)), | ||
| 101 | + child: TabBar( | ||
| 102 | + indicator: CustomTabIndicator( | ||
| 103 | + radius: 0, | ||
| 104 | + ), | ||
| 105 | + indicatorColor: MyColours.color_199095, | ||
| 106 | + indicatorSize: TabBarIndicatorSize.tab, | ||
| 107 | + // indicatorPadding: EdgeInsets.symmetric( | ||
| 108 | + // horizontal: ScreenUtil().setWidth(12)), | ||
| 109 | + labelColor: MyColours.color_199095, | ||
| 110 | + labelStyle: TextStyle( | ||
| 111 | + fontSize: ScreenUtil().setSp(32), | ||
| 112 | + fontWeight: FontWeight.bold), | ||
| 113 | + labelPadding: EdgeInsets.zero, | ||
| 114 | + unselectedLabelStyle: | ||
| 115 | + TextStyle(fontWeight: FontWeight.normal), | ||
| 116 | + unselectedLabelColor: MyColours.color_999999, | ||
| 117 | + tabs: _tabBarTitle.map((value) { | ||
| 118 | + return Tab( | ||
| 119 | + child: Text(value), | ||
| 120 | + ); | ||
| 121 | + }).toList()), | ||
| 122 | + )) | ||
| 123 | + ], | ||
| 124 | + )))); | ||
| 125 | + } | ||
| 126 | +} |
| @@ -268,20 +268,6 @@ class MyPageState extends State<MyPage> with WidgetsBindingObserver { | @@ -268,20 +268,6 @@ class MyPageState extends State<MyPage> with WidgetsBindingObserver { | ||
| 268 | // ], | 268 | // ], |
| 269 | // ), | 269 | // ), |
| 270 | VEmptyView(40), | 270 | VEmptyView(40), |
| 271 | - | ||
| 272 | - // MyItem( | ||
| 273 | - // title: "我的员工", | ||
| 274 | - // content: "", | ||
| 275 | - // callback: () { | ||
| 276 | - // Utils.goMiniProgramZm(context, "roomtype/roomtype"); | ||
| 277 | - // }, | ||
| 278 | - // ), | ||
| 279 | - // MyDivider( | ||
| 280 | - // double.infinity, | ||
| 281 | - // ScreenUtil().setHeight(1), | ||
| 282 | - // color: MyColours.color_f3f3f3, | ||
| 283 | - // ), | ||
| 284 | - | ||
| 285 | MyItem( | 271 | MyItem( |
| 286 | title: "线上券创建", | 272 | title: "线上券创建", |
| 287 | content: '', | 273 | content: '', |
| @@ -289,11 +275,23 @@ class MyPageState extends State<MyPage> with WidgetsBindingObserver { | @@ -289,11 +275,23 @@ class MyPageState extends State<MyPage> with WidgetsBindingObserver { | ||
| 289 | NavigatorUtil.goCouponPage(context); | 275 | NavigatorUtil.goCouponPage(context); |
| 290 | }, | 276 | }, |
| 291 | ), | 277 | ), |
| 278 | + | ||
| 292 | MyDivider( | 279 | MyDivider( |
| 293 | double.infinity, | 280 | double.infinity, |
| 294 | ScreenUtil().setHeight(1), | 281 | ScreenUtil().setHeight(1), |
| 295 | color: MyColours.color_f3f3f3, | 282 | color: MyColours.color_f3f3f3, |
| 296 | ), | 283 | ), |
| 284 | + | ||
| 285 | + MyItem( | ||
| 286 | + title: "联系人", | ||
| 287 | + content: "", | ||
| 288 | + callback: () { | ||
| 289 | + // Utils.goMiniProgramZm(context, "roomtype/roomtype"); | ||
| 290 | + NavigatorUtil.goMyContantPage(context); | ||
| 291 | + }, | ||
| 292 | + ), | ||
| 293 | + | ||
| 294 | + VEmptyView(40), | ||
| 297 | MyItem( | 295 | MyItem( |
| 298 | title: "短信管理", | 296 | title: "短信管理", |
| 299 | content: | 297 | content: |
lib/provider/contant_show_model.dart
0 → 100644
| 1 | +import 'package:flutter/material.dart'; | ||
| 2 | +import 'package:one_key/constant/constant.dart'; | ||
| 3 | +import 'package:one_key/constant/error.dart'; | ||
| 4 | +import 'package:one_key/constant/state.dart'; | ||
| 5 | +import 'package:one_key/models/user_history_entity.dart'; | ||
| 6 | +import 'package:one_key/net/base_resp.dart'; | ||
| 7 | +import 'package:one_key/net/dio_util.dart'; | ||
| 8 | +import 'package:one_key/net/http_url.dart'; | ||
| 9 | + | ||
| 10 | +class ContantShowModel extends ChangeNotifier { | ||
| 11 | + PageState pageStateLeft = PageState.Loading; | ||
| 12 | + List<UserHistoryEntity> userHistorys = []; //历史录入 | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + //获取历史录入 | ||
| 17 | + getUserHistorys(BuildContext context, Map<String, String> params) async { | ||
| 18 | + BaseResp<List> baseResp = await DioUtil() | ||
| 19 | + .request<List>(context, Method.get, HttpUrl.get_reserve_user, | ||
| 20 | + data: params, showLoading: false) | ||
| 21 | + .catchError((error) { | ||
| 22 | + print(error.toString()); | ||
| 23 | + if (error is MyError) { | ||
| 24 | + switch (error.type) { | ||
| 25 | + case 1: | ||
| 26 | + pageStateLeft = PageState.ConnectivityError; | ||
| 27 | + break; | ||
| 28 | + case 2: | ||
| 29 | + pageStateLeft = PageState.ConnectivityTimeOut; | ||
| 30 | + break; | ||
| 31 | + default: | ||
| 32 | + pageStateLeft = PageState.ConnectivityError; | ||
| 33 | + break; | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + notifyListeners(); | ||
| 37 | + }); | ||
| 38 | + if (baseResp != null && baseResp.code == Constant.status_success) { | ||
| 39 | + userHistorys = baseResp.data.map<UserHistoryEntity>((value) { | ||
| 40 | + return UserHistoryEntity.fromJson(value); | ||
| 41 | + }).toList(); | ||
| 42 | + if (userHistorys.length == 0) { | ||
| 43 | + pageStateLeft = PageState.Empty; | ||
| 44 | + } else { | ||
| 45 | + pageStateLeft = PageState.Success; | ||
| 46 | + } | ||
| 47 | + notifyListeners(); | ||
| 48 | + } | ||
| 49 | + } | ||
| 50 | +} |
| @@ -301,4 +301,10 @@ class NavigatorUtil { | @@ -301,4 +301,10 @@ class NavigatorUtil { | ||
| 301 | "${Routes.my_integral_page}?sunModel=${FluroConvertUtils.object2string(sunModel)}", | 301 | "${Routes.my_integral_page}?sunModel=${FluroConvertUtils.object2string(sunModel)}", |
| 302 | replace: replace); | 302 | replace: replace); |
| 303 | } | 303 | } |
| 304 | + | ||
| 305 | + /// 我的联系人页面 | ||
| 306 | + static Future<dynamic> goMyContantPage(BuildContext context, | ||
| 307 | + {replace = false, IntegralSunModel sunModel}) { | ||
| 308 | + return _navigateTo(context, "${Routes.my_contant_page}", replace: replace); | ||
| 309 | + } | ||
| 304 | } | 310 | } |
| @@ -34,6 +34,7 @@ import 'package:one_key/pages/login/web_page.dart'; | @@ -34,6 +34,7 @@ import 'package:one_key/pages/login/web_page.dart'; | ||
| 34 | import 'package:one_key/pages/message/message_order_menu.dart'; | 34 | import 'package:one_key/pages/message/message_order_menu.dart'; |
| 35 | import 'package:one_key/pages/my/base_info.dart'; | 35 | import 'package:one_key/pages/my/base_info.dart'; |
| 36 | import 'package:one_key/pages/my/book_time_set.dart'; | 36 | import 'package:one_key/pages/my/book_time_set.dart'; |
| 37 | +import 'package:one_key/pages/my/contant_page.dart'; | ||
| 37 | import 'package:one_key/pages/my/my_integral_page.dart'; | 38 | import 'package:one_key/pages/my/my_integral_page.dart'; |
| 38 | import 'package:one_key/pages/my/receive_orders_time_set.dart'; | 39 | import 'package:one_key/pages/my/receive_orders_time_set.dart'; |
| 39 | import 'package:one_key/pages/my/remark_manager_page.dart'; | 40 | import 'package:one_key/pages/my/remark_manager_page.dart'; |
| @@ -436,3 +437,13 @@ var myIntegralPageHandler = new Handler( | @@ -436,3 +437,13 @@ var myIntegralPageHandler = new Handler( | ||
| 436 | return ChangeNotifierProvider<MyModel>( | 437 | return ChangeNotifierProvider<MyModel>( |
| 437 | create: (_) => MyModel(), child: MyIntegralPage(sunModel: sunModel)); | 438 | create: (_) => MyModel(), child: MyIntegralPage(sunModel: sunModel)); |
| 438 | }); | 439 | }); |
| 440 | +///我的联系人 | ||
| 441 | +var myContantPageHandler = new Handler( | ||
| 442 | + handlerFunc: (BuildContext context, Map<String, List<Object>> params) { | ||
| 443 | + // IntegralSunModel sunModel = IntegralSunModel.fromJson(json | ||
| 444 | + // .decode(FluroConvertUtils.fluroCnParamsDecode(params["sunModel"].first))); | ||
| 445 | + // String urlStr = FluroConvertUtils.fluroCnParamsDecode(params["urlStr"].first); | ||
| 446 | + | ||
| 447 | + return ContactListPage(); | ||
| 448 | +}); | ||
| 449 | + |
| @@ -42,6 +42,8 @@ class Routes { | @@ -42,6 +42,8 @@ class Routes { | ||
| 42 | static String enter_store_environment = "/enter_store_environment"; //店铺环境 | 42 | static String enter_store_environment = "/enter_store_environment"; //店铺环境 |
| 43 | static String complete_create_store = "/complete_create_store"; //创建店铺完成 | 43 | static String complete_create_store = "/complete_create_store"; //创建店铺完成 |
| 44 | static String my_integral_page = "/my_integral_page"; //我的积分 | 44 | static String my_integral_page = "/my_integral_page"; //我的积分 |
| 45 | + static String my_contant_page = "/my_contant_page"; //我的联系人 | ||
| 46 | + | ||
| 45 | 47 | ||
| 46 | static void configureRoutes(FluroRouter router) { | 48 | static void configureRoutes(FluroRouter router) { |
| 47 | router.notFoundHandler = new Handler( | 49 | router.notFoundHandler = new Handler( |
| @@ -92,6 +94,9 @@ class Routes { | @@ -92,6 +94,9 @@ class Routes { | ||
| 92 | handler: completeCreateStorePageHandler); | 94 | handler: completeCreateStorePageHandler); |
| 93 | router.define(my_integral_page, | 95 | router.define(my_integral_page, |
| 94 | handler: myIntegralPageHandler); | 96 | handler: myIntegralPageHandler); |
| 97 | + router.define(my_contant_page, | ||
| 98 | + handler: myContantPageHandler); | ||
| 99 | + | ||
| 95 | 100 | ||
| 96 | } | 101 | } |
| 97 | } | 102 | } |
lib/widgets/custom_tab_indicator.dart
0 → 100644
| 1 | +import 'package:flutter/material.dart'; | ||
| 2 | + | ||
| 3 | +import 'package:flutter/cupertino.dart'; | ||
| 4 | +import 'package:flutter/material.dart'; | ||
| 5 | +import 'package:flutter_screenutil/screenutil.dart'; | ||
| 6 | +import 'package:one_key/res/colors.dart'; | ||
| 7 | + | ||
| 8 | + | ||
| 9 | +class CustomTabIndicator extends Decoration { | ||
| 10 | + /// Create an underline style selected tab indicator. | ||
| 11 | + /// | ||
| 12 | + /// The [borderSide] and [insets] arguments must not be null. | ||
| 13 | + const CustomTabIndicator( | ||
| 14 | + {this.borderSide = const BorderSide(width: 2.0, color: Colors.white), | ||
| 15 | + this.insets = EdgeInsets.zero, | ||
| 16 | + this.width, | ||
| 17 | + this.radius, | ||
| 18 | + this.color}) | ||
| 19 | + : assert(borderSide != null), | ||
| 20 | + assert(insets != null); | ||
| 21 | + | ||
| 22 | + /// The color and weight of the horizontal line drawn below the selected tab. | ||
| 23 | + final BorderSide borderSide; | ||
| 24 | + | ||
| 25 | + final double radius; | ||
| 26 | + | ||
| 27 | + final double width; | ||
| 28 | + | ||
| 29 | + final Color color; | ||
| 30 | + | ||
| 31 | + /// Locates the selected tab's underline relative to the tab's boundary. | ||
| 32 | + /// | ||
| 33 | + /// The [TabBar.indicatorSize] property can be used to define the | ||
| 34 | + /// tab indicator's bounds in terms of its (centered) tab widget with | ||
| 35 | + /// [TabIndicatorSize.label], or the entire tab with [TabIndicatorSize.tab]. | ||
| 36 | + final EdgeInsetsGeometry insets; | ||
| 37 | + | ||
| 38 | + @override | ||
| 39 | + Decoration lerpFrom(Decoration a, double t) { | ||
| 40 | + if (a is CustomTabIndicator) { | ||
| 41 | + return CustomTabIndicator( | ||
| 42 | + borderSide: BorderSide.lerp(a.borderSide, borderSide, t), | ||
| 43 | + insets: EdgeInsetsGeometry.lerp(a.insets, insets, t), | ||
| 44 | + ); | ||
| 45 | + } | ||
| 46 | + return super.lerpFrom(a, t); | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + @override | ||
| 50 | + Decoration lerpTo(Decoration b, double t) { | ||
| 51 | + if (b is CustomTabIndicator) { | ||
| 52 | + return CustomTabIndicator( | ||
| 53 | + borderSide: BorderSide.lerp(borderSide, b.borderSide, t), | ||
| 54 | + insets: EdgeInsetsGeometry.lerp(insets, b.insets, t), | ||
| 55 | + ); | ||
| 56 | + } | ||
| 57 | + return super.lerpTo(b, t); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @override | ||
| 61 | + _UnderlinePainter createBoxPainter([VoidCallback onChanged]) { | ||
| 62 | + return _UnderlinePainter(this, onChanged); | ||
| 63 | + } | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +class _UnderlinePainter extends BoxPainter { | ||
| 67 | + _UnderlinePainter(this.decoration, VoidCallback onChanged) | ||
| 68 | + : assert(decoration != null), | ||
| 69 | + super(onChanged); | ||
| 70 | + | ||
| 71 | + final CustomTabIndicator decoration; | ||
| 72 | + | ||
| 73 | + BorderSide get borderSide => decoration.borderSide; | ||
| 74 | + EdgeInsetsGeometry get insets => decoration.insets; | ||
| 75 | + | ||
| 76 | + // Rect _indicatorRectFor(Rect rect, TextDirection textDirection) { | ||
| 77 | + // assert(rect != null); | ||
| 78 | + // assert(textDirection != null); | ||
| 79 | + // final Rect indicator = insets.resolve(textDirection).deflateRect(rect); | ||
| 80 | + | ||
| 81 | + // //取中间坐标 | ||
| 82 | + // double cw = (indicator.left + indicator.right) / 2; | ||
| 83 | + // return Rect.fromLTWH( | ||
| 84 | + // cw - decoration.width / 2, | ||
| 85 | + // indicator.bottom - borderSide.width, | ||
| 86 | + // decoration.width, | ||
| 87 | + // borderSide.width); | ||
| 88 | + // } | ||
| 89 | + Rect _indicatorRectFor(Rect rect, TextDirection textDirection) { | ||
| 90 | + assert(rect != null); | ||
| 91 | + assert(textDirection != null); | ||
| 92 | + final Rect indicator = insets.resolve(textDirection).deflateRect(rect); | ||
| 93 | + return Rect.fromLTWH( | ||
| 94 | + indicator.left, | ||
| 95 | + indicator.bottom - borderSide.width, | ||
| 96 | + indicator.width, | ||
| 97 | + borderSide.width, | ||
| 98 | + ); | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + // @override | ||
| 102 | + // void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { | ||
| 103 | + // assert(configuration != null); | ||
| 104 | + // assert(configuration.size != null); | ||
| 105 | + // final Rect rect = offset & configuration.size; | ||
| 106 | + // final TextDirection textDirection = configuration.textDirection; | ||
| 107 | + // final Rect indicator = | ||
| 108 | + // _indicatorRectFor(rect, textDirection).deflate(borderSide.width / 2.0); | ||
| 109 | + // final RRect rrect = | ||
| 110 | + // RRect.fromRectAndRadius(indicator, Radius.circular(40.0)); | ||
| 111 | + // Gradient gradient = LinearGradient(colors: [ | ||
| 112 | + // MyColours.color_3BBFF5, | ||
| 113 | + // MyColours.color_57a0ff, | ||
| 114 | + // ]); | ||
| 115 | + // final Paint paint = borderSide.toPaint()..strokeCap = StrokeCap.square; | ||
| 116 | + // canvas.drawLine(Offset(rrect.left, rrect.bottom), | ||
| 117 | + // Offset(rrect.right, rrect.bottom), paint); | ||
| 118 | + // canvas.drawRRect( | ||
| 119 | + // rrect, | ||
| 120 | + // Paint() | ||
| 121 | + // ..style = PaintingStyle.fill | ||
| 122 | + // ..shader = gradient.createShader(rect)); | ||
| 123 | + | ||
| 124 | + // // Gradient gradient = | ||
| 125 | + // // LinearGradient(colors: [Colors.red[200], Colors.red[800]]); | ||
| 126 | + // Gradient gradient = LinearGradient(colors: [ | ||
| 127 | + // MyColours.color_3BBFF5, | ||
| 128 | + // MyColours.color_57a0ff, | ||
| 129 | + // ]); | ||
| 130 | + // canvas.drawLine(rect.left, p2, paint) | ||
| 131 | + // canvas.drawRRect( | ||
| 132 | + // rrect, | ||
| 133 | + // Paint() | ||
| 134 | + // ..style = PaintingStyle.fill | ||
| 135 | + // ..shader = gradient.createShader(rect)); | ||
| 136 | + // } | ||
| 137 | + // void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { | ||
| 138 | + // assert(configuration != null); | ||
| 139 | + // assert(configuration.size != null); | ||
| 140 | + // final Rect rect = offset & configuration.size; | ||
| 141 | + // final TextDirection textDirection = configuration.textDirection; | ||
| 142 | + // Gradient gradient = LinearGradient(colors: [ | ||
| 143 | + // MyColours.color_3BBFF5, | ||
| 144 | + // MyColours.color_57a0ff, | ||
| 145 | + // ]); | ||
| 146 | + // final Rect indicator = _indicatorRectFor(rect, textDirection).deflate(borderSide.width / 2.0); | ||
| 147 | + // final Paint paint = borderSide.toPaint()..strokeCap = StrokeCap.square ..shader = gradient.createShader(rect); | ||
| 148 | + // canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint); | ||
| 149 | + // } | ||
| 150 | + | ||
| 151 | + @override | ||
| 152 | + void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { | ||
| 153 | + assert(configuration != null); | ||
| 154 | + assert(configuration.size != null); | ||
| 155 | + final Rect rect = offset & configuration.size; | ||
| 156 | + final RRect rRect = RRect.fromRectAndRadius( | ||
| 157 | + Rect.fromLTWH(rect.left + (rect.width - ScreenUtil().setWidth(48*2)) / 2, | ||
| 158 | + rect.top + rect.height - ScreenUtil().setWidth(20), ScreenUtil().setWidth(48*2), ScreenUtil().setWidth(6)), | ||
| 159 | + Radius.circular(decoration.radius)); | ||
| 160 | + Gradient gradient = LinearGradient( | ||
| 161 | + begin: Alignment.topLeft, | ||
| 162 | + end: Alignment.bottomRight, | ||
| 163 | + colors: [ | ||
| 164 | + MyColours.color_199095, | ||
| 165 | + MyColours.color_199095, | ||
| 166 | + ], | ||
| 167 | + ); | ||
| 168 | + canvas.drawRRect( | ||
| 169 | + rRect, | ||
| 170 | + Paint() | ||
| 171 | + ..style = PaintingStyle.fill | ||
| 172 | + ..shader = gradient.createShader(rect)); | ||
| 173 | + } | ||
| 174 | +} |
-
Please register or login to post a comment