我正在开发计算器类型的 flutter 应用程序。我想
这是主要的计算器课程
class Calculator extends StatefulWidget {
@override
_CalculatorState createState() => _CalculatorState();
}
class _CalculatorState extends State<Calculator> {
double soldPrice=0.00;
void printSoldPrice(){
print(soldPrice);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: BgColor ,
bottomNavigationBar: Container(
decoration: BoxDecoration(
borderRadius:BorderRadius.only(topLeft: Radius.circular(10), topRight:Radius.circular(10) ),
color:YellowBg,
),
alignment: Alignment.center,
height: 50,
child: Text('RESET',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
letterSpacing: 5,
),
),
),
body: SafeArea(
child: Column(
children: <Widget>[
SizedBox(height:10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
EcalLogo(logoSize: 30,),
],
),
SizedBox(height:10),
Padding(
padding:EdgeInsets.symmetric(horizontal:10.0),
child:FractionallySizedBox(
widthFactor: 0.9,
child: Container(
height:1.0,
width:130.0,
color:Colors.white,),
),),
SizedBox(height: 10,),
Expanded(
child:ListView(
children: <Widget>[
TextFieldContainer1(
title: 'SOLD PRICE',
tagLine: "SALE PRICE WITOHUT SHIPPING",
icon: Icons.check_circle,
),
],
))
],
),
)
);
}
}
这是子TextFieldContainer1类
class TextFieldContainer1 extends StatefulWidget {
final String title;
final String tagLine;
final IconData icon;
TextFieldContainer1({this.title,this.tagLine,this.icon});
@override
_TextFieldContainer1State createState() => _TextFieldContainer1State();
}
class _TextFieldContainer1State extends State<TextFieldContainer1> {
final controller1 = TextEditingController();
@override
Widget build(BuildContext context) {
return FractionallySizedBox(
widthFactor: 0.95,
child: Container(
padding: EdgeInsets.symmetric(horizontal:20, vertical:5),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: tileBackground,
),
height: 57,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:<Widget>[
Container(
child:Column(
children:<Widget>[
Row(
children:<Widget>[
Icon(widget.icon,
color: Colors.white,
size:27.5
),
SizedBox(width:5),
Text(widget.title,
style: TextStyle(
fontSize: 20,
color:Colors.white,
fontWeight: FontWeight.w500
),
)
]
),
Text(widget.tagLine,
style: TextStyle(
color:Color.fromRGBO(255, 255, 255, 0.5),
fontSize: 12
),
)
]
)
),
Container(
padding: EdgeInsets.symmetric(horizontal: 15,vertical: 5),
decoration: BoxDecoration(
color: Color.fromRGBO(252, 205, 0, 0.2),
borderRadius: BorderRadius.all(Radius.circular(10)
)
),
height: 40,
width: 92,
child: TextField(
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20
),
autofocus: false,
decoration:InputDecoration(
focusColor: YellowBg,
fillColor: YellowBg,
hoverColor: YellowBg,
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: YellowBg),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: YellowBg),)
) ,
keyboardType: TextInputType.number,
controller: controller1,
),
)
],
),
),
);
}
}
我想使用TextFieldContainer1类中的 controller1 数据(文本字段中的数据)来更新计算器类中的 soldPrice 变量,并在触发textField onChanged时仅打印该变量。 该怎么做?
答案 0 :(得分:1)
完整的工作代码:
添加
final Function(String) onChange;
到 TextFieldContainer1
添加
onChanged: widget.onChange,
到 文本域 (并删除Controller)
添加
onChange: (val) => setState(() {
soldPrice = double.parse(val);
print(val);
})
在计算器中调用TextFieldContainer1。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(child: Calculator()),
),
);
}
}
Color BgColor = Colors.white;
Color YellowBg = Colors.yellow;
Color tileBackground = Colors.black;
class Calculator extends StatefulWidget {
@override
_CalculatorState createState() => _CalculatorState();
}
class _CalculatorState extends State<Calculator> {
double soldPrice=0.00;
void printSoldPrice(){
print(soldPrice);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: BgColor ,
bottomNavigationBar: Container(
decoration: BoxDecoration(
borderRadius:BorderRadius.only(topLeft: Radius.circular(10), topRight:Radius.circular(10) ),
color:YellowBg,
),
alignment: Alignment.center,
height: 50,
child: Text('RESET',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
letterSpacing: 5,
),
),
),
body: SafeArea(
child: Column(
children: <Widget>[
SizedBox(height:10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlutterLogo(size: 30,),
],
),
SizedBox(height:10),
Padding(
padding:EdgeInsets.symmetric(horizontal:10.0),
child:FractionallySizedBox(
widthFactor: 0.9,
child: Container(
height:1.0,
width:130.0,
color:Colors.white,),
),),
SizedBox(height: 10,),
Expanded(
child:ListView(
children: <Widget>[
TextFieldContainer1(
title: 'SOLD PRICE',
tagLine: "SALE PRICE WITOHUT SHIPPING",
icon: Icons.check_circle,
onChange: (val) => setState(() {
soldPrice = double.parse(val);
print(val);
})
),
],
)),
Text("$soldPrice")
],
),
)
);
}
}
class TextFieldContainer1 extends StatefulWidget {
final String title;
final String tagLine;
final IconData icon;
final Function(String) onChange;
TextFieldContainer1({this.title,this.tagLine,this.icon, this.onChange});
@override
_TextFieldContainer1State createState() => _TextFieldContainer1State();
}
class _TextFieldContainer1State extends State<TextFieldContainer1> {
@override
Widget build(BuildContext context) {
return FractionallySizedBox(
widthFactor: 0.95,
child: Container(
padding: EdgeInsets.symmetric(horizontal:20, vertical:5),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: tileBackground,
),
height: 57,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:<Widget>[
Container(
child:Column(
children:<Widget>[
Row(
children:<Widget>[
Icon(widget.icon,
color: Colors.white,
size:27.5
),
SizedBox(width:5),
Text(widget.title,
style: TextStyle(
fontSize: 20,
color:Colors.white,
fontWeight: FontWeight.w500
),
)
]
),
Text(widget.tagLine,
style: TextStyle(
color:Color.fromRGBO(255, 255, 255, 0.5),
fontSize: 12
),
)
]
)
),
Container(
padding: EdgeInsets.symmetric(horizontal: 15,vertical: 5),
decoration: BoxDecoration(
color: Color.fromRGBO(252, 205, 0, 0.2),
borderRadius: BorderRadius.all(Radius.circular(10)
)
),
height: 40,
width: 92,
child: TextField(
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20
),
autofocus: false,
decoration:InputDecoration(
focusColor: YellowBg,
fillColor: YellowBg,
hoverColor: YellowBg,
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: YellowBg),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: YellowBg),)
) ,
keyboardType: TextInputType.number,
onChanged: widget.onChange,
),
)
],
),
),
);
}
}
答案 1 :(得分:0)
使文本字段类构造函数接受一个函数,然后在onChange
中使用该函数,如下所示:
@override
_TextFieldContainer1State createState() => _TextFieldContainer1State();
}
class _TextFieldContainer1State extends State<TextFieldContainer1> {
final controller1 = TextEditingController();
final Function onChange;
@override
Widget build(BuildContext context) {
return FractionallySizedBox(
widthFactor: 0.95,
child: Container(
padding: EdgeInsets.symmetric(horizontal:20, vertical:5),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: tileBackground,
),
height: 57,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:<Widget>[
Container(
child:Column(
children:<Widget>[
Row(
children:<Widget>[
Icon(widget.icon,
color: Colors.white,
size:27.5
),
SizedBox(width:5),
Text(widget.title,
style: TextStyle(
fontSize: 20,
color:Colors.white,
fontWeight: FontWeight.w500
),
)
]
),
Text(widget.tagLine,
style: TextStyle(
color:Color.fromRGBO(255, 255, 255, 0.5),
fontSize: 12
),
)
]
)
),
Container(
padding: EdgeInsets.symmetric(horizontal: 15,vertical: 5),
decoration: BoxDecoration(
color: Color.fromRGBO(252, 205, 0, 0.2),
borderRadius: BorderRadius.all(Radius.circular(10)
)
),
height: 40,
width: 92,
child: TextField(
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20
),
onChange: widget.onChange,
autofocus: false,
decoration:InputDecoration(
focusColor: YellowBg,
fillColor: YellowBg,
hoverColor: YellowBg,
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: YellowBg),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: YellowBg),)
) ,
keyboardType: TextInputType.number,
controller: controller1,
),
)
],
),
),
);
}
}
现在在计算器类中使用它时,您将像这样使用它:
TextFieldContainer1(
title: 'SOLD PRICE',
tagLine: "SALE PRICE WITOHUT SHIPPING",
icon: Icons.check_circle,
onChanga: (value) => print(value);
// now you have access to your text field value inside your calculator class
),
您可能还想将文本字段类设为Stateless
,因为您没有在任何地方使用setState
。
答案 2 :(得分:0)
为textField创建自定义类非常简单。以下是实现此目的的两个步骤。第一步是为文本字段创建有状态窗口小部件。
RCTextField({
@required this.hintText,
@required this.labelText,
@required this.prefixIcon,
@required this.suffixIcon,
@required this.kType,
@required this.kAction,
@required this.validatorFunction,
@required this.onChange,
});
final String hintText;
final String labelText;
final String prefixIcon;
final String suffixIcon;
final TextInputType kType;
final TextInputAction kAction;
final Function validatorFunction;
final Function(String) onChange;
@override
_RCTextFieldState createState() => _RCTextFieldState();
}
class _RCTextFieldState extends State<RCTextField> {
FocusNode myFocusNode;
get validatorFunction => null;
get textFieldValue => null;
get onChange => null;
@override
void initState() {
super.initState();
myFocusNode = FocusNode();
myFocusNode.addListener(_onOnFocusNodeEvent);
}
_onOnFocusNodeEvent() {
setState(() {
// Re-renders
});
}
@override
void dispose() {
// Clean up the focus node when the Form is disposed.
myFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
// margin: EdgeInsets.fromLTRB(20, 20, 20, 0),
child: TextFormField(
onEditingComplete: () => FocusScope.of(context).nextFocus(),
textInputAction: widget.kAction,
cursorColor: Colors.black,
style: new TextStyle(color: _getInputTextColor()),
focusNode: myFocusNode,
validator: validatorFunction,
decoration: InputDecoration(
// focusColor: Colors.red,
// fillColor: Colors.blueGrey,
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: kInactiveTextFieldColour),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: kActiveTextFieldColour),
),
border: UnderlineInputBorder(),
filled: false,
prefixIcon: Padding(
padding: EdgeInsets.all(14.0),
child: SvgPicture.asset(
'images/' + widget.prefixIcon + '.svg',
semanticsLabel: 'Acme Logo',
color: myFocusNode.hasFocus
? kActiveTextFieldColour
: kInactiveTextFieldColour,
),
),
hintText: widget.hintText,
labelText: widget.labelText,
labelStyle: TextStyle(
color: myFocusNode.hasFocus
? kActiveTextFieldColour
: kInactiveTextFieldColour),
),
keyboardType: widget.kType,
onChanged: widget.onChange,
),
);
}
Color _getInputTextColor() {
return myFocusNode.hasFocus ? Colors.black : Colors.black;
}
}
下面是使用此类的最后一步。
RCTextField(
hintText: 'Enter your text',
labelText: 'Text',
prefixIcon: 'plus',
suffixIcon: null,
kType: TextInputType.visiblePassword,
kAction: TextInputAction.done,
onChange: (val) => setState(() {
print(val);
}),
),
如果您遇到任何麻烦,请告诉我。