Performance 颤振小部件不返回值并聚焦下一个/上一个元素

Performance 颤振小部件不返回值并聚焦下一个/上一个元素,performance,flutter,dart,flutter-layout,Performance,Flutter,Dart,Flutter Layout,我有一个OTP小部件,它使示例文本字段组合并返回结果。为什么在我的情况下,FocusScope和onSuccess功能不在控制台上返回任何响应或打印响应 代码: import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @

我有一个OTP小部件,它使示例文本字段组合并返回结果。为什么在我的情况下,
FocusScope
onSuccess
功能不在控制台上返回任何响应或打印响应

代码

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Home(),
    );
  }
}

class Home extends StatelessWidget {
  void onFinish(res, code) {
    print(code);
    print(res);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: Center(
        child: Container(
          margin: EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text("Enter confirm code"),
              SizedBox(height: 35.0),
              OtpWidget(onFinish),
            ],
          ),
        ),
      ),
    );
  }
}

class OtpWidget extends StatefulWidget {
  final Function onSuccess;

  OtpWidget(this.onSuccess);

  @override
  _OtpWidgetState createState() => _OtpWidgetState();
}

class _OtpWidgetState extends State<OtpWidget> {
  final code = {
    'first': null,
    'second': null,
    'third': null,
    'fourth': null,
  };

  bool checkResult() {
    return code['first'] != null &&
        code['second'] != null &&
        code['third'] != null &&
        code['fourth'] != null;
  }

  void firstVal(value) {
    setState(() {
      code['first'] = value;
    });
    print(code);
    widget.onSuccess(checkResult(), code);
  }

  void secondVal(value) {
    setState(() {
      code['second'] = value;
    });
    print(code);
    widget.onSuccess(checkResult(), code);
  }

  void thirdVal(value) {
    setState(() {
      code['third'] = value;
    });
    print(code);
    widget.onSuccess(checkResult(), code);
  }

  void fourthVal(value) {
    setState(() {
      code['fourth'] = value;
    });
    print(code);
    widget.onSuccess(checkResult(), code);
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.transparent,
      child: Container(
        padding: EdgeInsets.symmetric(horizontal: 25),
        child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              OtpTextField(first: true, last: false, onChange: firstVal),
              OtpTextField(first: false, last: false, onChange: secondVal),
              OtpTextField(first: false, last: false, onChange: thirdVal),
              OtpTextField(first: false, last: true, onChange: fourthVal),
            ],
          )
        ]),
      ),
    );
  }
}

class OtpTextField extends StatelessWidget {
  final bool first;
  final bool last;
  final Function onChange;
  const OtpTextField(
      {Key key, @required this.first, @required this.last, this.onChange})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 60.0,
      width: 60.0,
      child: AspectRatio(
        aspectRatio: 1.0,
        child: TextField(
          autofocus: true,
          onChanged: (value) {
            this.onChange(value);
            if (value.length == 1 && last == false) {
              FocusScope.of(context).nextFocus();
            }
            if (value.length == 0 && first == false) {
              FocusScope.of(context).previousFocus();
            }
          },
          showCursor: true,
          readOnly: false,
          textAlign: TextAlign.center,
          keyboardType: TextInputType.number,
          maxLength: 1,
          decoration: InputDecoration(
            counter: Offstage(),
          ),
        ),
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
视觉密度:视觉密度。自适应平台密度,
),
home:home(),
);
}
}
类Home扩展了无状态小部件{
无效onFinish(res,code){
打印(代码);
印刷品(res);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“主页”),
),
正文:中(
子:容器(
边距:所有边缘集(16.0),
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
文本(“输入确认代码”),
尺寸箱(高度:35.0),
OtpWidget(onFinish),
],
),
),
),
);
}
}
类OtpWidget扩展StatefulWidget{
最终功能成功;
OtpWidget(this.onSuccess);
@凌驾
_OtpWidgetState createState()=>OtpWidgetState();
}
类_OtpWidgetState扩展状态{
最终代码={
“first”:null,
'second':null,
“第三”:空,
“第四”:空,
};
bool checkResult(){
返回代码['first']!=null&&
代码['second']!=null&&
代码['third']!=null&&
代码['fourth']!=null;
}
void firstVal(值){
设置状态(){
代码['first']=值;
});
打印(代码);
onSuccess(checkResult(),代码);
}
void secondVal(值){
设置状态(){
代码['second']=值;
});
打印(代码);
onSuccess(checkResult(),代码);
}
第三次无效(价值){
设置状态(){
代码['third']=值;
});
打印(代码);
onSuccess(checkResult(),代码);
}
无效第四值(值){
设置状态(){
代码['fourth']=值;
});
打印(代码);
onSuccess(checkResult(),代码);
}
@凌驾
小部件构建(构建上下文){
退货(
颜色:颜色。透明,
子:容器(
填充:边缘组。对称(水平:25),
子项:列(mainAxisAlignment:mainAxisAlignment.center,子项:[
划船(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
儿童:[
OtpTextField(第一个:true,最后一个:false,onChange:firstVal),
OtpTextField(第一个:false,最后一个:false,一次更改:secondVal),
OtpTextField(第一个:false,最后一个:false,onChange:thirdVal),
OtpTextField(第一个:false,最后一个:true,onChange:fourthVal),
],
)
]),
),
);
}
}
类OtpTextField扩展了无状态小部件{
最后的布尔第一;
最后一场比赛;
最终功能改变;
常数OtpTextField(
{Key Key,@required this.first,@required this.last,this.onChange})
:super(key:key);
@凌驾
小部件构建(构建上下文){
返回容器(
身高:60.0,
宽度:60.0,
孩子:AspectRatio(
aspectRatio:1.0,
孩子:TextField(
自动对焦:对,
一旦更改:(值){
这个。onChange(值);
if(value.length==1&&last==false){
FocusScope.of(context.nextFocus();
}
if(value.length==0&&first==false){
FocusScope.of(context.previousFocus();
}
},
是的,
只读:false,
textAlign:textAlign.center,
键盘类型:TextInputType.number,
最大长度:1,
装饰:输入装饰(
计数器:后台(),
),
),
),
);
}
}
问题是:

final code = {
    'first': null,
    'second': null,
    'third': null,
    'fourth': null,
};
如果您不提供特定类型,Dart引擎将根据值提供类型。在这种情况下,
code
的类型是
Map
,因此,即使您尝试更改每个项目的值,其值也将为空

给出如下所示的特定类型:

final Map<String, String> code = {
    'first': null,
    'second': null,
    'third': null,
    'fourth': null,
};
对于上述代码,您应按如下方式更改checkResult函数:

bool checkResult() {
    return code['first'].length != 0 &&
    code['second'].length != 0 &&
    code['third'].length != 0 &&
    code['fourth'].length != 0;
}
bool checkResult() {
    return code['first'].length != 0 &&
    code['second'].length != 0 &&
    code['third'].length != 0 &&
    code['fourth'].length != 0;
}