当TextField专注于点击时,将触发build()函数。如果您运行以下应用程序,请注意底部的TextField。如果点击了TextField,它将导致build()运行并重建整个屏幕。无论如何,当此字段成为焦点时,阻止build()运行?
通常来说,是什么原因导致构建函数运行以及如何重组程序,以防止即使触发了构建也可以重绘整个屏幕?
class TestPad extends StatefulWidget {
_TestPadSate createState() => new _TestPadSate();
final Bloc _bloc = new Bloc();
}
class _TestPadSate extends State<TestPad>{
static final txtAreaController = TextEditingController();
@override
void initState() {
super.initState();
widget._bloc.fetchVal();
}
@override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
appBar: new AppBar(),
body: StreamBuilder(
stream: widget._bloc.getVal,
builder: (context, snapshot) {
if(snapshot.connectionState == ConnectionState.waiting){
return buildProgressIndicator(true, width: 50, height: 50);
}
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: new Container(
margin: EdgeInsets.only(
),
//height: MediaQuery.of(context).size.height - 210,
decoration: BoxDecoration(
color: Colors.white,
border: Border(top: BorderSide(color: Colors.grey))),
child: ListView(
reverse: true,
shrinkWrap: true,
children: List(),
),
)
),
Container(
margin: EdgeInsets.only(
top: 2.0,
),
decoration: new BoxDecoration(
color: Colors.white,
),
height: 72,
child: new Column(
children: <Widget>[
textAreaSection(context),
],
)),
],
);
}
)
)
);
}
Widget _postBtn() {
return IconButton(
icon: Icon(Icons.send, size: 22,),
);
}
Widget textAreaSection(context) {
return Row(
mainAxisSize: MainAxisSize.min,
//mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: textFormFieldScroller(),
),
_postBtn()
],
);
}
Widget textFormFieldScroller() {
return SingleChildScrollView(
physics: ClampingScrollPhysics(),
child: Form(
child: TextFormField(
controller: txtAreaController,
keyboardType: TextInputType.text,
style: new TextStyle(
//height: 0.5,
color: Colors.grey),
autofocus: false,
//initialValue: "What's on your mind?",
// maxLines: null,
decoration: new InputDecoration(
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
hintText: "What's on your mind?",
hintStyle: new TextStyle(
color: Colors.grey[600],
),
fillColor: Colors.white,
filled: true,
border: InputBorder.none,
),
)
),
);
}
Widget buildProgressIndicator(showIndicator,{double width, double height}) {
return new Padding(
padding: const EdgeInsets.all(8.0),
child: new Center(
child: new Opacity(
opacity: showIndicator ? 1.0 : 0.0,
child: Container(
width: width??10.0,
height: height??10.0,
child: new CircularProgressIndicator(
)),
),
),
);
}
}
class Bloc {
final _fetcher = BehaviorSubject<String>();
Observable<String> get getVal => _fetcher.stream;
fetchVal() async{
await Future.delayed(Duration(seconds: 2), (){
_fetcher.sink.add("test");
});
}
dispose() {
_fetcher.close();
}
}
答案 0 :(得分:0)
setState()导致重建。我相信Flutter团队不会考虑重建屏幕,因为它的速度非常快。但是,要做的是从重建中分离出数据集合(例如Select)。 IE浏览器对程序进行结构设计,以便在重新选择数据后将其与构建程序分开。如果需要重新选择数据并且需要重新绘制屏幕,则执行setState()。