From f2d006a84c4a1fbbdb724d8dcb4065bb36bdd6ef Mon Sep 17 00:00:00 2001 From: laiiihz Date: Fri, 18 Dec 2020 16:35:41 +0800 Subject: [PATCH] add cam view add 2datePicker --- example/lib/example_picker.dart | 15 +++- example/lib/main.dart | 2 + example/pubspec.lock | 7 ++ lib/ansu_ui.dart | 6 +- lib/buttons/as_button.dart | 2 +- lib/pickers/as_two_date_picker.dart | 124 ++++++++++++++++++++++++++-- lib/styles/as_colors.dart | 1 + lib/toast/as_toast.dart | 7 ++ lib/utils/camera_util.dart | 16 +++- lib/utils/camera_view.dart | 63 ++++++++++++++ pubspec.lock | 7 ++ pubspec.yaml | 1 + 12 files changed, 238 insertions(+), 13 deletions(-) create mode 100644 lib/toast/as_toast.dart create mode 100644 lib/utils/camera_view.dart diff --git a/example/lib/example_picker.dart b/example/lib/example_picker.dart index 2934433..4fe9217 100644 --- a/example/lib/example_picker.dart +++ b/example/lib/example_picker.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:ansu_ui/ansu_ui.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -56,7 +58,18 @@ class _ExamplePickerState extends State { trailing: ASButton( title: '时间区间选择器', onPressed: () async { - show2DatePicker(context); + RangeDate dates = await show2DatePicker(context); + ASToast.show('${dates.start}-${dates.end}'); + }, + ), + ), + ListTile( + title: Text('图片选择器'), + subtitle: Text('ImagePicker'), + trailing: ASButton( + title: '图片选择器', + onPressed: () async { + File file = await camView(context); }, ), ), diff --git a/example/lib/main.dart b/example/lib/main.dart index 95d5e84..ebaec21 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -16,6 +16,8 @@ class MyApp extends StatelessWidget { return GetMaterialApp( title: 'Flutter Demo', home: _ScreenAdapter(), + builder: BotToastInit(), + navigatorObservers: [BotToastNavigatorObserver()], localizationsDelegates: [ GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, diff --git a/example/pubspec.lock b/example/pubspec.lock index 3a19683..bbd4d67 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -22,6 +22,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.0-nullsafety.1" + bot_toast: + dependency: transitive + description: + name: bot_toast + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.5" characters: dependency: transitive description: diff --git a/lib/ansu_ui.dart b/lib/ansu_ui.dart index 6f094d9..c70bcf9 100644 --- a/lib/ansu_ui.dart +++ b/lib/ansu_ui.dart @@ -10,9 +10,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_easyrefresh/easy_refresh.dart'; import 'package:image_picker/image_picker.dart'; +import 'package:bot_toast/bot_toast.dart'; export 'package:flutter_screenutil/flutter_screenutil.dart'; export 'package:flutter_easyrefresh/easy_refresh.dart'; +export 'package:bot_toast/bot_toast.dart'; //buttons part 'buttons/as_button.dart'; @@ -34,6 +36,8 @@ part 'bar/as_navigation_item.dart'; part 'drawer/as_drawer.dart'; +part 'toast/as_toast.dart'; + part 'pickers/as_date_picker.dart'; part 'pickers/as_picker_box.dart'; part 'pickers/as_city_picker.dart'; @@ -60,7 +64,7 @@ part 'divider/as_divider.dart'; part 'text_field/as_search_text_field.dart'; part 'utils/screen_adapter.dart'; -part 'utils/camera_util.dart'; +part 'utils/camera_util.dart';part 'utils/camera_view.dart'; part 'extension/num_extension.dart'; part 'extension/list_extension.dart'; diff --git a/lib/buttons/as_button.dart b/lib/buttons/as_button.dart index b68d40a..e6deba9 100644 --- a/lib/buttons/as_button.dart +++ b/lib/buttons/as_button.dart @@ -165,7 +165,7 @@ class _ASButtonState extends State { : BorderSide.none, borderRadius: BorderRadius.circular(widget.radius ?? 15.5.w)), color: widget.bgcolor ?? kForegroundColor, - splashColor: widget.splashColor??ColorTool.getSplashColor(kPrimaryColor), + splashColor: widget.splashColor, highlightColor: widget.splashColor?.withOpacity(0.3), elevation: 0, focusElevation: 0, diff --git a/lib/pickers/as_two_date_picker.dart b/lib/pickers/as_two_date_picker.dart index ad296e7..961606a 100644 --- a/lib/pickers/as_two_date_picker.dart +++ b/lib/pickers/as_two_date_picker.dart @@ -7,12 +7,12 @@ class AS2DatePicker extends StatefulWidget { _AS2DatePickerState createState() => _AS2DatePickerState(); } -class _AS2DatePickerState extends State - with TickerProviderStateMixin { +class _AS2DatePickerState extends State { int _selectedDay = 0; DateTime get now => DateTime.now(); - TabController _tabController; + DateTime _selectedDate; + PageController _pageController; DateTimeRange get singleHour => DateTimeRange( start: now, @@ -27,7 +27,14 @@ class _AS2DatePickerState extends State highlightElevation: 0, hoverElevation: 0, color: sameDay ? kForegroundColor : kForegroundColor.withOpacity(0), - onPressed: () => setState(() => _selectedDay = index), + onPressed: () { + _pageController?.animateToPage( + index, + duration: Duration(milliseconds: 300), + curve: Curves.easeInOutCubic, + ); + setState(() => _selectedDay = index); + }, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, height: 70.w, child: title.text.black @@ -43,18 +50,100 @@ class _AS2DatePickerState extends State color: kSecondaryColor, borderRadius: 7.radius, ), - child: Icon(Icons.check, size: 12.w), + child: Icon( + Icons.check, + size: 12.w, + color: kLightTextColor, + ), ); + Widget _renderButton(String title, VoidCallback onPressed, bool selected) { + return MaterialButton( + onPressed: onPressed, + height: 46.w, + shape: RoundedRectangleBorder(borderRadius: 23.radius), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + child: Row( + children: [ + 30.wb, + AnimatedDefaultTextStyle( + child: title.text, + style: TextStyle().size(16).copyWith( + color: selected ? kSecondaryColor : kTextColor, + ), + duration: Duration(milliseconds: 300), + ), + Spacer(), + AnimatedOpacity( + opacity: selected ? 1 : 0, + duration: Duration(milliseconds: 300), + child: _renderCheckBox, + ), + 30.wb, + ], + ), + ); + } + + Widget _buildTodayList() { + int startHour = now.hour; + int hourCount = 24 - startHour; + return ListView.builder( + padding: 8.edge, + itemBuilder: (context, index) { + bool sameItem = now.day == _selectedDate.day && + _selectedDate.hour == startHour + index; + if (index == 0) + return _renderButton( + '一小时内', + () => setState(() => _selectedDate = now), + sameItem, + ); + return _renderButton( + '${startHour + index}:00-${startHour + index + 1}:00', + () => setState(() => _selectedDate = DateTime( + now.year, + now.month, + now.day, + startHour + index, + )), + sameItem, + ); + }, + itemCount: hourCount, + ); + } + + Widget _buildOtherDayList(int offsetDay) { + return ListView.builder( + padding: 8.edge, + itemBuilder: (context, index) { + bool sameItem = (now.day + offsetDay) == _selectedDate.day && + _selectedDate.hour == index; + return _renderButton( + '$index\:00-${index + 1}:00', + () => setState(() => _selectedDate = DateTime( + now.year, + now.month, + now.day + offsetDay, + index, + )), + sameItem, + ); + }, + itemCount: 24, + ); + } @override void initState() { super.initState(); - _tabController = TabController(length: 3, vsync: this); + _pageController = PageController(); + _selectedDate = now; } @override void dispose() { - _tabController?.dispose(); + _pageController?.dispose(); super.dispose(); } @@ -81,7 +170,17 @@ class _AS2DatePickerState extends State ), ), ), - Expanded(child: SizedBox()), + Expanded( + child: PageView( + scrollDirection: Axis.vertical, + children: [ + _buildTodayList(), + _buildOtherDayList(1), + _buildOtherDayList(2), + ], + controller: _pageController, + ), + ), ], ).expanded, Container( @@ -91,7 +190,14 @@ class _AS2DatePickerState extends State ), child: ASLongButton.solid( title: '确认', - onPressed: () {}, + onPressed: () { + Navigator.pop( + context, + RangeDate( + start: _selectedDate, + end: _selectedDate.add(Duration(hours: 1)), + )); + }, ), ), ], diff --git a/lib/styles/as_colors.dart b/lib/styles/as_colors.dart index f9b8b3f..aa0a845 100644 --- a/lib/styles/as_colors.dart +++ b/lib/styles/as_colors.dart @@ -38,6 +38,7 @@ const Color kSecondaryColor = Color(0xFFE50112); class ColorTool { static Color getSplashColor(Color color) { + if (color == null) return Colors.transparent; int r = color.red; int g = color.green; int b = color.blue; diff --git a/lib/toast/as_toast.dart b/lib/toast/as_toast.dart new file mode 100644 index 0000000..8915c50 --- /dev/null +++ b/lib/toast/as_toast.dart @@ -0,0 +1,7 @@ +part of ansu_ui; + +class ASToast { + static show(String text) { + BotToast.showText(text: text); + } +} diff --git a/lib/utils/camera_util.dart b/lib/utils/camera_util.dart index 68b095f..5abf660 100644 --- a/lib/utils/camera_util.dart +++ b/lib/utils/camera_util.dart @@ -1,7 +1,7 @@ part of ansu_ui; ///获取相机文件 -Future camFile({double maxHeight = 3000,double maxWidth = 3000}) async { +Future camFile({double maxHeight = 3000, double maxWidth = 3000}) async { var pickedFile = await ImagePicker().getImage( source: ImageSource.camera, maxHeight: maxHeight, @@ -10,3 +10,17 @@ Future camFile({double maxHeight = 3000,double maxWidth = 3000}) async { if (pickedFile == null) return null; return File(pickedFile.path); } + +Future camView(BuildContext context, + {double maxHeight = 3000, double maxWidth = 3000}) async { + File file = await camFile(maxHeight: maxHeight, maxWidth: maxWidth); + if (file == null) return null; + return await Navigator.push(context, PageRouteBuilder( + pageBuilder: (context, animation, secondAnimation) { + return FadeTransition( + opacity: animation, + child: CameraView(file: file, title: '照片选择器'), + ); + }, + )); +} diff --git a/lib/utils/camera_view.dart b/lib/utils/camera_view.dart new file mode 100644 index 0000000..17a2d6e --- /dev/null +++ b/lib/utils/camera_view.dart @@ -0,0 +1,63 @@ +part of ansu_ui; + +class CameraView extends StatefulWidget { + final File file; + final String title; + CameraView({Key key, this.file, this.title}) : super(key: key); + + @override + _CameraViewState createState() => _CameraViewState(); +} + +class _CameraViewState extends State { + _buildButton({String title, Color color = kTextColor, onPressed}) { + return MaterialButton( + child: title.text.bold.size(18).copyWith(color: color), + onPressed: onPressed, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + height: 48.w, + ); + } + + @override + Widget build(BuildContext context) { + return ASScaffold( + title: widget.title, + body: Image.file(widget.file, fit: BoxFit.cover), + bottomNavigationBar: Material( + color: kForegroundColor, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildButton( + title: '重拍', + onPressed: () async { + File file = await camFile(); + if (file == null) Navigator.pop(context); + Navigator.pushReplacement(context, PageRouteBuilder( + pageBuilder: (context, animation, secondAnimation) { + return FadeTransition( + opacity: animation, + child: CameraView(file: file, title: widget.title), + ); + }, + )); + }, + ), + _buildButton( + title: '删除', + color: kDangerColor, + onPressed: () => Navigator.pop(context), + ), + _buildButton( + title: '确认', + onPressed: () => Navigator.pop(context, widget.file), + ), + ].sepWidget(separate: ASDivider()), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 26b62ca..0d92dea 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -15,6 +15,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.1.0-nullsafety.1" + bot_toast: + dependency: "direct main" + description: + name: bot_toast + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.5" characters: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index bf407af..ecd77c9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,6 +14,7 @@ dependencies: flutter_easyrefresh: ^2.1.6 lpinyin: ^1.1.0 image_picker: ^0.6.7+15 + bot_toast: ^3.0.5 dev_dependencies: flutter_test: