当前位置:网站首页>Flutter custom component
Flutter custom component
2022-06-30 17:36:00 【One leaf floating boat】
Share a big guy's custom components demo.
more demo Please move github:
Quantity pedometer NumberStepper

//...
NumberStepper(
minValue: 1,
maxValue: 1000,
stepValue: 100,
iconSize: 60,
value: 1000,
color: Colors.blue,
style: NumberStepperStyle.system,
block: (value){
DDLog(value);
},
),
SizedBox(height: 20,),
NumberStepper(
minValue: 1,
maxValue: 1000,
stepValue: 100,
iconSize: 40,
value: 1000,
color: Colors.blue,
style: NumberStepperStyle.outlined,
block: (value){
DDLog(value);
},
),
//...
If it doesn't open , Here is the source code :
//
// NumberStepper.dart
// flutter_templet_project
//
// Created by shang on 6/13/21 6:23 AM.
// Copyright 6/13/21 shang. All rights reserved.
//
// ignore: must_be_immutable
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_templet_project/extensions/ddlog.dart';
enum NumberStepperStyle {
system,
outlined,
textfield,
}
/// Custom value increase / decrease Stepper
class NumberStepper extends StatefulWidget {
NumberStepper({
required this.minValue,
required this.maxValue,
required this.stepValue,
this.iconSize = 24,
required this.value,
this.color = Colors.blue,
this.style = NumberStepperStyle.system,
this.radius = 5.0,
this.wraps = true,
required this.block,
});
final int minValue;
final int maxValue;
final int stepValue;
final double iconSize;
int value;
final bool wraps;
final Color color;
final NumberStepperStyle style;
final double radius;
void Function(int value) block;
@override
_NumberStepperState createState() => _NumberStepperState();
}
class _NumberStepperState extends State<NumberStepper> {
// controller
final _textController = TextEditingController();
// The focus of
final focusNode1 = FocusNode();
@override
void initState() {
// TODO: implement initState
_textController.text = "${widget.value}";
ddlog(_textController.text);
super.initState();
}
@override
Widget build(BuildContext context) {
// return buildOther(context);
switch (widget.style) {
case NumberStepperStyle.outlined:
return buildOutlinedStyle(context);
break;
case NumberStepperStyle.textfield:
return buildTexfieldStyle(context);
default:
break;
}
return buildSystemStyle(context);
}
Widget buildSystemStyle(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: widget.iconSize,
height: widget.iconSize,
decoration: BoxDecoration(
color: widget.color,
borderRadius: BorderRadius.circular(widget.radius),
border: Border.all(color: widget.color, width: 1), // Edge color and edge width
),
child: IconButton(
icon: Icon(Icons.remove, size: widget.iconSize),
// iconSize: widget.iconSize,
padding: EdgeInsets.zero,
color: Colors.white,
onPressed: () {
go(-widget.stepValue);
},
),
),
Container(
width: widget.value.toString().length*18*widget.iconSize/30,
// width: widget.iconSize + 20,
child: Text('${widget.value}',
style: TextStyle(
fontSize: widget.iconSize * 0.8,
),
textAlign: TextAlign.center,
),
),
Container(
width: widget.iconSize,
height: widget.iconSize,
decoration: BoxDecoration(
color: widget.color,
borderRadius: BorderRadius.circular(widget.radius),
border: Border.all(color: widget.color, width: 1), // Edge color and edge width
),
child: IconButton(
icon: Icon(Icons.add, size: widget.iconSize,),
// iconSize: widget.iconSize,
padding: EdgeInsets.zero,
color: Colors.white,
onPressed: () {
setState(() {
go(widget.stepValue);
});
},
),
),
],
);
}
Widget buildOutlinedStyle(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: widget.iconSize,
height: widget.iconSize,
// color: Theme.of(context).primaryColor,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(widget.radius),
border: Border.all(color: widget.color, width: 1), // Edge color and edge width
),
child: IconButton(
icon: Icon(Icons.remove, size: widget.iconSize),
// iconSize: widget.iconSize,
padding: EdgeInsets.zero,
color: widget.color,
onPressed: () {
go(-widget.stepValue);
},
),
),
Container(
width: widget.value.toString().length*18*widget.iconSize/30,
// width: widget.iconSize + 20,
child: Text('${widget.value}',
style: TextStyle(
fontSize: widget.iconSize * 0.8,
),
textAlign: TextAlign.center,
),
),
Container(
width: widget.iconSize,
height: widget.iconSize,
// color: Theme.of(context).primaryColor,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(widget.radius),
border: Border.all(color: widget.color, width: 1), // Edge color and edge width
),
child: IconButton(
icon: Icon(Icons.add, size: widget.iconSize),
// iconSize: widget.iconSize,
padding: EdgeInsets.zero,
color: widget.color,
onPressed: () {
setState(() {
go(widget.stepValue);
});
},
),
),
],
);
}
Widget buildTexfieldStyle(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: TextField(
enableInteractiveSelection: false,
toolbarOptions: ToolbarOptions(
copy:false,
paste: false,
cut: false,
selectAll: false,
//by default all are disabled 'false'
),
controller: _textController,
decoration: InputDecoration(
// labelText: " Please enter the content ",// Prompt content when there is no text in the input box , When there is content, it will automatically float above the content
// helperText: " Just type in words or numbers ", // Auxiliary descriptive text at the bottom of the input box
prefixIcon:IconButton(
icon: Icon(
Icons.remove,
size: widget.iconSize,
),
onPressed: (){
// go(-widget.stepValue);
setState(() {
go(-widget.stepValue);
_textController.text = "${widget.value}";
});
},
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4.0) // Fillet size
),
suffixIcon: IconButton(
icon: Icon(
Icons.add,
size: widget.iconSize,
),
onPressed: (){
// go(widget.stepValue);
setState(() {
// FocusScope.of(context).requestFocus(FocusNode());
go(widget.stepValue);
_textController.text = "${widget.value}";
});
},
),
contentPadding: const EdgeInsets.only(bottom:8)
),
keyboardType: TextInputType.number,
),
),
],
);
}
void go(int stepValue) {
setState(() {
if (stepValue < 0 && (widget.value == widget.minValue || widget.value + stepValue < widget.minValue)) {
ddlog("it's minValue!");
if (widget.wraps) widget.value = widget.maxValue;
widget.block(widget.value);
return;
}
if (stepValue > 0 && (widget.value == widget.maxValue || widget.value + stepValue > widget.maxValue)) {
ddlog("it's maxValue!");
if (widget.wraps) widget.value = widget.minValue;
widget.block(widget.value);
return;
}
widget.value += stepValue;
});
widget.block(widget.value);
}
}LineSegmentControl / Line indicator segment component

//...
SizedBox(height: 15),
buildLineSegmentControl(null, lineColor: Colors.blue),
SizedBox(height: 15),
buildLineSegmentControl(Colors.white, lineColor: Colors.blue),
SizedBox(height: 15),
buildLineSegmentControl(Colors.black87, lineColor: Colors.white),
//...
Widget buildLineSegmentControl(Color? backgroundColor, {required Color lineColor}) {
final Map<int, Widget> children = const <int, Widget>{
0: Text("Item 111", style: TextStyle(fontSize: 15), textAlign: TextAlign.center,),
1: Text("Item 222", style: TextStyle(fontSize: 15), textAlign: TextAlign.center,),
2: Text("Item 333", style: TextStyle(fontSize: 15), textAlign: TextAlign.center,),
};
if (backgroundColor != null) {
return LineSegmentControl(
groupValue: groupValue,
children: children,
backgroundColor: backgroundColor,
lineColor: lineColor,
onValueChanged: (i){
setState(() {
groupValue = int.parse("$i");
});
DDLog(groupValue);
},
);
}
return LineSegmentControl(
groupValue: groupValue,
children: children,
// backgroundColor: backgroundColor,
lineColor: lineColor,
onValueChanged: (i){
setState(() {
groupValue = int.parse("$i");
});
DDLog(groupValue);
},
);
}
//
// LineSegmentWidget.dart
// fluttertemplet
//
// Created by shang on 6/14/21 8:47 AM.
// Copyright 6/14/21 shang. All rights reserved.
//
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:fluttertemplet/dartExpand/DDLog.dart';
enum LineSegmentStyle {
top,
bottom,
}
/// Line indicator segment component
class LineSegmentControl<T> extends StatefulWidget {
final Map<T, Widget> children;
T? groupValue;
final EdgeInsetsGeometry padding;
final EdgeInsetsGeometry margin;
final LineSegmentStyle style;
final Color? backgroundColor;
final Color lineColor;
final double height;
final Radius radius;
void Function(T value) onValueChanged;
LineSegmentControl({
Key? key,
required this.children,
required this.groupValue,
this.style = LineSegmentStyle.bottom,
this.backgroundColor = CupertinoColors.tertiarySystemFill,
this.lineColor = Colors.blue,
this.height = 36,
this.padding = const EdgeInsets.symmetric(horizontal: 0),
this.margin = const EdgeInsets.symmetric(horizontal: 15),
this.radius = const Radius.circular(4),
required this.onValueChanged,
}) : super(key: key);
@override
_LineSegmentControlState createState() => _LineSegmentControlState();
}
class _LineSegmentControlState extends State<LineSegmentControl> {
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double contentWidth = screenWidth - widget.margin.horizontal - widget.padding.horizontal;
double itemWidth = contentWidth / widget.children.values.length;
return Container(
margin: widget.margin,
padding: widget.padding,
decoration: BoxDecoration(
color: widget.backgroundColor,
borderRadius: BorderRadius.all(widget.radius),
),
child: Stack(
children: [
Row(
children: widget.children.values.map((e) => Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
height: widget.height,
width: itemWidth,
child: TextButton(
child: e,
onPressed: (){
DDLog(e);
setState(() {
widget.groupValue = widget.children.values.toList().indexOf(e);
});
widget.onValueChanged(widget.groupValue);
},
),
),
],
),
).toList(),
),
AnimatedPositioned(
duration: Duration(milliseconds: 200),
top: widget.style == LineSegmentStyle.top ? 0 : widget.height - 2,
left: widget.groupValue*itemWidth,
child: Container(
height: 2,
width: itemWidth,
color: widget.lineColor,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(4),
// color: widget.lineColor,
// ),
),
),
],
),
);
}
}
边栏推荐
- canvas云朵形状动画
- 构建基本buildroot文件系统
- Key to understanding the trend of spot Silver
- Canvas cloud shape animation
- Map collection
- Interview shock 60: what will cause MySQL index invalidation?
- [C language] explain threads - start two threads
- [C language] explain threads - thread separation function pthread_ detach
- flutter 音乐 录音 播放 audioplayers
- leetcode:1042. 不邻接植花【随机填入符合要求的 + 后面不会形成矛盾 + set.pop】
猜你喜欢
随机推荐
Canvas cloud shape animation
送受伤婴儿紧急就医,滴滴司机连闯五个红灯
Canvas mouse control gravity JS effect
leetcode:1042. Do not plant flowers adjacent to each other [randomly fill in qualified + no contradiction will be formed behind + set.pop]
Solution: STM32 failed to parse data using cjson
解决方法:STM32使用cJSON解析数据失败
24: Chapter 3: develop pass service: 7: user defined exceptions (to represent errors in the program); Create graceexceptionhandler to handle exceptions globally and uniformly (build JSON data of corre
Exch: database integrity checking
Booking UI effect implemented by svg
Exploration and practice of "flow batch integration" in JD
流批一体在京东的探索与实践
Exch:修复丢失的系统邮箱
Key to understanding the trend of spot Silver
5g has been in business for three years. Where will innovation go in the future?
parker变量柱塞泵PV092R1K1T1NMMC
ROC-RK3566-PC使用10.1寸IPS触摸屏显示
The new version of Shangding cloud | favorites function has been launched to meet personal use needs
万卷书 - 欧洲的门户 [The Gates of Europe]
博士毕业去县城工作,如何是你,怎么选?
开发那些事儿:如何在视频中添加文字水印?
https://github.com/shang1219178163/flutter_templet_projec








