diff --git a/example/lib/example_button.dart b/example/lib/example_button.dart index 5c63dc7..34a8f20 100644 --- a/example/lib/example_button.dart +++ b/example/lib/example_button.dart @@ -9,21 +9,46 @@ class ExampleButton extends StatefulWidget { } class _ExampleButtonState extends State { + TextEditingController _EditingController = TextEditingController(); @override Widget build(BuildContext context) { return ASScaffold( title: 'Button', body: ListView( - children: [ ASButton.delete(title: '删除订单',onpressed: (){},), - ASButton.info(title: '删除订单',onpressed: (){},), - ASButton.warn(title: '删除订单',onpressed: (){},), - ASButton.opration(title: '删除订单',onpressed: (){},), + children: [ + ASButton.delete( + title: '删除订单', + onpressed: () {}, + ), + ASButton.info( + title: '删除订单', + onpressed: () {}, + ), + ASButton.warn( + title: '删除订单', + onpressed: () {}, + ), + ASButton.opration( + title: '删除订单', + onpressed: () {}, + ), SizedBox(height: 12.w), - ASLongButton.solid(title: '确认',onpressed: (){},), - ASLongButton.hollow(title: '确认',onpressed: (){},), + ASLongButton.solid( + title: '确认', + onpressed: () {}, + ), + ASLongButton.hollow( + title: '确认', + onpressed: () {}, + ), Padding( padding: EdgeInsets.symmetric(horizontal: 100.w), - child: ASLongButton.solid(title: 'null',onpressed:(){} ), + child: ASLongButton.solid(title: 'null', onpressed: () {}), + ), + ASNumericButton( + initValue: 1, + suffix: '个', + onChange: (value) {}, ), ], ), diff --git a/lib/ansu_ui.dart b/lib/ansu_ui.dart index 3753cd6..83ccb89 100644 --- a/lib/ansu_ui.dart +++ b/lib/ansu_ui.dart @@ -3,6 +3,7 @@ library ansu_ui; export 'buttons/as_button.dart'; export 'buttons/as_longbutton.dart'; export 'buttons/as_back_button.dart'; +export 'buttons/as_numeric_button.dart'; export 'scaffold/as_scaffold.dart'; export 'styles/as_colors.dart'; export 'bar/as_tabbar.dart'; diff --git a/lib/buttons/as_numeric_button.dart b/lib/buttons/as_numeric_button.dart new file mode 100644 index 0000000..6088dc0 --- /dev/null +++ b/lib/buttons/as_numeric_button.dart @@ -0,0 +1,177 @@ +import 'package:ansu_ui/ansu_ui.dart'; +import 'package:ansu_ui/painters/as_numeric_painter.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +///## 数量选择组件 +class ASNumericButton extends StatefulWidget { + ///初始值 + final int initValue; + + ///最小值 + /// + ///包含该值 + /// + ///default value : `0` + final int minValue; + + ///最大值 + /// + ///包含该值 + /// + ///default value : `9999` + final int maxValue; + + ///后缀 + final String suffix; + + ///达到最大值 + final Function(int value) reachMax; + + ///达到最小值 + final Function(int value) reachMin; + + /// + final Function(int value) onChange; + ASNumericButton({ + Key key, + @required this.initValue, + this.suffix, + this.minValue = 0, + this.maxValue = 9999, + this.reachMax, + this.reachMin, + @required this.onChange, + }) : super(key: key); + + @override + _ASNumericButtonState createState() => _ASNumericButtonState(); +} + +class _ASNumericButtonState extends State { + FocusNode _focusNode = FocusNode(); + TextEditingController _controller; + BorderSide _outline = BorderSide( + color: Color(0xFFD8D4D4), + width: 1.w, + ); + + int _displayValue; + + Widget _buildButton({ + @required CustomPainter painter, + @required VoidCallback onPressed, + @required BorderRadius borderRadius, + }) { + return Container( + height: 32.w, + width: 32.w, + decoration: BoxDecoration( + border: Border.all( + color: Color(0xFFD8D4D4), + width: 1.w, + ), + borderRadius: borderRadius, + color: kForegroundColor, + ), + child: MaterialButton( + onPressed: onPressed, + child: CustomPaint( + painter: painter, + ), + splashColor: kPrimaryColor, + highlightColor: kPrimaryColor.withOpacity(0.3), + shape: RoundedRectangleBorder( + borderRadius: borderRadius, + ), + ), + ); + } + + @override + void initState() { + super.initState(); + _displayValue = widget.initValue; + _controller = TextEditingController(text: widget.initValue.toString()); + } + + @override + Widget build(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + _buildButton( + painter: ASNUmericPainter.minus(), + onPressed: () { + _focusNode.unfocus(); + if (_displayValue > widget.minValue) { + _displayValue--; + widget.onChange(_displayValue); + _controller.text = _displayValue.toString(); + setState(() {}); + } else { + if (widget.reachMin != null) widget.reachMin(_displayValue); + } + }, + borderRadius: BorderRadius.horizontal(left: Radius.circular(16.w)), + ), + GestureDetector( + onTap: () { + _focusNode.requestFocus(); + }, + child: Container( + height: 32.w, + width: 98.w, + alignment: Alignment.center, + child: IntrinsicWidth( + child: TextField( + controller: _controller, + onChanged: (text) { + setState(() {}); + }, + focusNode: _focusNode, + style: TextStyle( + color: kTextColor, + fontSize: 14.sp, + ), + cursorColor: kPrimaryColor, + textAlign: TextAlign.center, + decoration: InputDecoration( + border: InputBorder.none, + isDense: true, + suffixText: widget.suffix, + suffixStyle: TextStyle( + color: Colors.black.withOpacity(0.32), + fontSize: 14.sp, + ), + ), + ), + ), + decoration: BoxDecoration( + border: Border( + top: _outline, + bottom: _outline, + ), + color: Color(0xFFF7F7F7), + ), + ), + ), + _buildButton( + painter: ASNUmericPainter.plus(), + onPressed: () { + _focusNode.unfocus(); + if (_displayValue < widget.maxValue) { + _displayValue++; + widget.onChange(_displayValue); + _controller.text = _displayValue.toString(); + setState(() {}); + } else { + if (widget.reachMax != null) widget.reachMax(_displayValue); + } + }, + borderRadius: BorderRadius.horizontal(right: Radius.circular(16.w)), + ), + ], + ); + } +} diff --git a/lib/painters/as_numeric_painter.dart b/lib/painters/as_numeric_painter.dart new file mode 100644 index 0000000..82e7c92 --- /dev/null +++ b/lib/painters/as_numeric_painter.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class ASNUmericPainter extends CustomPainter { + final bool plus; + ASNUmericPainter.minus() : this.plus = false; + ASNUmericPainter.plus() : this.plus = true; + @override + void paint(Canvas canvas, Size size) { + double halfWidth = size.width / 2; + double halfHeight = size.height / 2; + Paint paint = Paint() + ..color = Colors.black + ..style = PaintingStyle.stroke + ..strokeWidth = 1.w; + canvas.drawCircle(Offset(halfWidth, halfHeight), 16.w / 2, paint); + canvas.drawLine( + Offset(halfWidth - 3, halfHeight), + Offset(halfWidth + 3, halfHeight), + paint, + ); + if (plus) { + canvas.drawLine( + Offset(halfWidth, halfHeight - 3), + Offset(halfWidth, halfHeight + 3), + paint, + ); + } + } + + @override + bool shouldRepaint(ASNUmericPainter oldDelegate) => false; + + @override + bool shouldRebuildSemantics(ASNUmericPainter oldDelegate) => false; +}