_loadingText
的方法作为对话框参数。当我单击“开始运行”按钮时,_loadingText
方法将被调用两次。 showAboutDialog
,一切正常。_loadingText
也将被调用一次。这需要我一天!
感谢您的帮助。预先感谢...
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:view_animation/loading_dialog.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
StreamController<String> _streamController;
TextEditingController _inputController;
@override
void initState() {
super.initState();
_streamController = StreamController<String>.broadcast();
_inputController = TextEditingController();
_inputController.addListener(() {
_streamController.add(_inputController.text);
});
}
@override
void dispose() {
super.dispose();
_streamController.close();
}
String _loadingText() {
print('===== 2. Method run OVER =====');
return 'Loading...';
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_inputContainer(),
SizedBox(
height: 20,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(26),
),
child: StreamBuilder(
stream: _streamController.stream.map((text) => text.length > 4),
builder: (context, snap) {
return FlatButton(
color: Color(0xFFFFAC0B),
disabledColor: Colors.black12,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26),
),
padding: EdgeInsets.symmetric(vertical: 15, horizontal: 12.5),
onPressed: snap.data != null && snap.data
? () {
print('===== 1. show dialog =====');
showDialog(
context: context,
builder: (BuildContext context) {
return LoadingDialog(
loadingText: _loadingText(),
);
});
// showAboutDialog(context: context, applicationName: _loadingText());
}
: null,
child: Text(
'GO RUN',
style: TextStyle(fontSize: 12, color: Colors.white),
),
);
},
),
),
],
)),
);
}
Widget _inputContainer() {
return Container(
width: 200,
padding: EdgeInsets.only(left: 20, right: 20),
decoration: BoxDecoration(
color: Color(0xFFFFAC0B),
borderRadius: BorderRadius.circular(36.0),
),
child: TextField(
controller: _inputController,
keyboardType: TextInputType.number,
maxLines: 1,
cursorColor: Colors.orange,
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Let's GO",
hintStyle: TextStyle(color: Colors.white54, fontSize: 20),
),
),
);
}
}
import 'package:flutter/material.dart';
class LoadingDialog extends StatefulWidget {
final String loadingText;
final bool outsideDismiss;
final Function dismissCallback;
final Future<dynamic> requestCallback;
LoadingDialog(
{Key key,
this.loadingText = "Loading...",
this.outsideDismiss = true,
this.dismissCallback,
this.requestCallback,
})
: super(key: key);
@override
_LoadingDialogState createState() => _LoadingDialogState();
}
class _LoadingDialogState extends State<LoadingDialog> {
void _dismissDialog(){
if(widget.dismissCallback != null) {
widget.dismissCallback();
}
Navigator.of(context).pop();
}
@override
void initState() {
print('===== 3. loading init =====');
if (widget.requestCallback != null) {
widget.requestCallback.then((_) => Navigator.of(context).pop());
}
super.initState();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: widget.outsideDismiss ? _dismissDialog : null,
child: Material(
type: MaterialType.transparency,
child: Center(
child: SizedBox(
width: 120.0,
height: 120.0,
child: Container(
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0)
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new CircularProgressIndicator(),
new Padding(
padding: const EdgeInsets.only(
top: 20.0,
),
child: new Text(
widget.loadingText,
style: new TextStyle(fontSize: 12.0),
),
),
],
),
),
),
),
),
);
}
}
答案 0 :(得分:0)
那是因为,当您第一次点击按钮时,您的TextField仍然处于活动状态,这意味着出现了新状态,并且flutter会重新构建。当您第二次点击按钮时,您的文本字段处于非活动状态。
答案 1 :(得分:0)
要点是,当您将函数传递给 onTap 小部件时,它将在构建状态并调用函数而不点击时调用:
因此,请不要尝试将类似方法传递给 OnTap :
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () widget.outsideDismiss ? ()
{
this._dismissDialog();
} : null,
...