您可以通过多种方式分离小部件逻辑和表示。我见过的(你提到的)是使用 WidgetView 模式。你可以在没有任何依赖的情况下做到这一点:
- 创建一个抽象类,其中包含所有 WidgetView 应实现的逻辑:
对于无状态小部件:
abstract class StatelessView<T1> extends StatelessWidget {
final T1 widget;
const StatelessView(this.widget, {Key key}) : super(key: key);
@override
Widget build(BuildContext context);
}
对于有状态的小部件:
abstract class WidgetView<T1, T2> extends StatelessWidget {
final T2 state;
T1 get widget => (state as State).widget as T1;
const WidgetView(this.state, {Key key}) : super(key: key);
@override
Widget build(BuildContext context);
}
- 正常创建小部件:
// Note it's a StatefulWidget because accountNumber mutates
class NewAccountComponent extends StatefulWidget {
@override
_NewAccountComponentState createState() => _NewAccountComponentState();
}
class _NewAccountComponentState extends State<NewAccountComponent> {
String accountNumber;
bool existsAccountNumber;
final TextEditingController controller = TextEditingController();
clearTextFormField() {
controller.text = '';
accountNumber = '';
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Enter a Unique Account Number'),
titlePadding: EdgeInsets.all(20.0),
content: TextFormField(
controller: controller,
onSaved: (value) => clearTextFormField(),
),
);
}
}
- 如果小部件是
Stateful
class NewAccountComponent extends StatefulWidget {
@override
_NewAccountComponentController createState() => _NewAccountComponentController();
}
// State suffix renamed to Controller
// This class has all widget logic
class _NewAccountComponentController extends State<NewAccountComponent> {
String accountNumber;
bool existsAccountNumber;
final TextEditingController controller = TextEditingController();
clearTextFormField() {
controller.text = '';
accountNumber = '';
}
// In build, returns a new instance of your view, sending the current state
@override
Widget build(BuildContext context) => _NewAccountComponentView(this);
}
// View extends of WidgetView and has a current state to access widget logic
// with widget you can access to StatefulWidget parent
class _NewAccountComponentView
extends WidgetView<NewAccountComponent, _NewAccountComponentController> {
_NewAccountComponentView(_NewAccountComponentController state): super(state);
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Enter a Unique Account Number'),
titlePadding: EdgeInsets.all(20.0),
content: TextFormField(
controller: state.controller,
onSaved: (value) => state.clearTextFormField(),
),
);
}
}
- 如果它是无状态的,则更改为:
class MyStatelessWidget extends StatelessWidget {
final String textContent = "Hello!";
const MyStatelessWidget({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Text(textContent),
);
}
}
到:
// Widget and logic controller are unit
class MyStatelessWidget extends StatelessWidget {
final String textContent = "Hello!";
const MyStatelessWidget({Key key}) : super(key: key);
@override
Widget build(BuildContext context) => _MyStatelessView(this);
}
// The view is separately
class _MyStatelessView extends StatelessView<MyStatelessWidget> {
_MyStatelessView(MyStatelessWidget widget) : super(widget);
@override
Widget build(BuildContext context) {
return Container(
child: Text(widget.textContent),
);
}
}
参考资料:
Flutter: WidgetView — A Simple Separation of Layout and Logic