所以我正在创建我的第一个Flutter应用程序,并且在登录屏幕上我使用了一个带动画的自定义按钮小部件(我把它变成了一个类,所以我可以在我的应用程序中多次使用它) . 我的自定义按钮小部件基于this Tutorial . 我的问题是,我试图通过在我将要传递给widget类的方法中使用setState()方法来调用文本验证 . 由于它是在一个完全不同的类上,我无法调用setState()方法 .
我尽可能多地搜索SO,但我似乎无法找到适用于我的用例的任何有用的问题 . 我想要做的是,一旦用户按下自定义小部件按钮,自定义小部件按钮的onPressed()方法应该调用validateTextField()方法并使用setState()相应地设置TexFormField的errorText参数(文本字段在登录中)小工具类) .
PS:这是我的第一个问题,所以如果我犯了任何错误,请耐心等待,如果我需要编辑这个问题的任何部分,我只会评论它 . 如果您需要更多代码,请询问,谢谢 .
这是我的代码:
我的自定义小部件类:
class LoginProgressButton extends StatefulWidget {
final Color successButtonColor;
final Color buttonColor;
final Color splashColor;
@required
final bool onPressed;
@required
final VoidCallback navigator;
const LoginProgressButton({
Key key,
this.onPressed,
this.successButtonColor,
this.buttonColor,
this.splashColor,
this.navigator,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _LoginProgressButton();
}
class _LoginProgressButton extends State<LoginProgressButton>
with TickerProviderStateMixin {
int _state = 0;
double _width = 240.0;
Animation _animation;
AnimationController _controller;
GlobalKey _globalKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Container(
key: _globalKey,
alignment: Alignment.center,
height: 60.0,
width: _width,
child: ButtonTheme(
height: 60.0,
minWidth: _width,
shape: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
child: RaisedButton(
onPressed: () => onPressed(),
color: _state == 2 ? widget.successButtonColor : widget.buttonColor,
child: loginState(),
splashColor: widget.splashColor,
onHighlightChanged: null,
),
),
);
}
Widget loginState() {
if (_state == 2) {
return Icon(
Icons.check,
color: Colors.white,
);
} else if (_state == 1) {
return SizedBox(
height: 30.0,
width: 30.0,
child: CircularProgressIndicator(
value: null,
backgroundColor: Colors.white,
strokeWidth: 3.0,
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
);
} else {
return Text('Connect',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
));
}
}
void animateButton() {
print(_state);
double initialWidth = _globalKey.currentContext.size.width;
_controller =
AnimationController(duration: Duration(milliseconds: 300), vsync: this);
_animation = Tween(begin: 0.0, end: 1.0).animate(_controller)
..addListener(() {
setState(() {
_width = initialWidth - ((initialWidth - 60.0) * _animation.value);
//this reduces the width by 48.0 for each frame, thus showing a smooth transition
});
});
_controller.forward(); //the forward function starts the animation
//starting with the default state
setState(() => _state = 1);
Timer(Duration(milliseconds: 3600), () => setState(() => _state = 2));
Timer(Duration(milliseconds: 4200), () => widget.navigator());
Timer(Duration(milliseconds: 4400), () => reset());
}
void reset() {
_width = 240.0;
_state = 0;
}
@override
void dispose() {
super.dispose();
}
void onPressed() {
if (widget.onPressed) {
setState(() {
if (_state == 0) {
animateButton();
} else if (_state == 2) {
reset();
}
});
} else {}
}
}
Login Widget类调用Custom Widget:
LoginProgressButton(
buttonColor: Theme.of(context).buttonColor,
splashColor: Theme.of(context).splashColor,
onPressed: _validateTextField(_pageHostLink),
navigator: _navigation,
successButtonColor: Colors.greenAccent,
),
On Pressed方法传递给Custom Widget:
void _validateField() {
String value = _pageHostLink;
setState(() {
_fieldValidated = value == null ? false : value.isNotEmpty;
});
print("value is $value of datatype ${value.runtimeType}");
setState(() => _errorText =
_fieldValidated ? null : 'This field cannot be left empty');
}
bool _validateTextField(String value) {
print("value is $value of datatype ${value.runtimeType}");
_validateField();
return value == null ? false : value.isNotEmpty;
}
如果验证成功,则导航器功能会推送下一个路径
void _navigation() {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => LoginPage(
pageHostLink: _pageHostLink,
),
),
);
}
1 回答
有几种方法可以更改另一个小部件的状态 . 最简单的是传递回调函数 . 其他选项是使用InheritedWidhets,因此您可以从应用程序的任何位置获取AppState . 有关不同体系结构示例的更多信息,请参阅here .
对于你的情况,我会在
LoginProgressButton
类中将bool onPressed
更改为ValidationFunction onPressed
,其中ValidationFunction是你创建了你的课程