因此,我正在制作我的第一个Flutter应用程序,并且在登录屏幕上,我使用了带有动画的自定义按钮小部件(我将其设置为类,以便可以在我的应用程序中多次使用它)。我的自定义按钮小部件基于this Tutorial。我的问题是,我正在尝试通过将要传递给小部件类的方法中的setState()方法来调用文本验证。由于它位于完全不同的类上,因此我无法调用setState()方法。
我已经尽可能地搜索了SO,但是似乎找不到适用于我的用例的有用问题。 我要做的是,一旦用户按下了自定义窗口小部件按钮,自定义窗口小部件按钮的onPressed()方法应调用validateTextField()方法并使用setState()相应地设置TexFormField的errorText参数(文本字段位于“登录名”中)小部件类)。
PS:这是我的第一个SO问题,因此,如果我有任何错误,请与我包容,如果我需要编辑此问题的任何部分,请对此发表评论。如果您需要更多代码,只需询问,谢谢。
这是我的代码:
我的自定义小部件类:
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类正在调用的自定义Widget:
LoginProgressButton(
buttonColor: Theme.of(context).buttonColor,
splashColor: Theme.of(context).splashColor,
onPressed: _validateTextField(_pageHostLink),
navigator: _navigation,
successButtonColor: Colors.greenAccent,
),
传递给“自定义小部件”的On Pressed方法:
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,
),
),
);
}
答案 0 :(得分:0)
有几种方法可以更改另一个小部件的状态。最简单的是传递一个回调函数。另一个选择是使用InheritedWidhets,因此您可以从应用程序中的任何位置获取AppState。有关不同体系结构示例的更多信息,您可以找到here。
对于您的情况,我将bool onPressed
类中的ValidationFunction onPressed
更改为LoginProgressButton
,其中ValidationFunction是
typedef bool ValidationFunction();
您将创建类为
LoginProgressButton(
buttonColor: Theme.of(context).buttonColor,
splashColor: Theme.of(context).splashColor,
onPressed: () => _validateTextField(_pageHostLink),
navigator: _navigation,
successButtonColor: Colors.greenAccent,
),