Flutter不会重建具有不同参数的相同小部件

时间:2019-03-19 09:11:00

标签: dart flutter flutter-layout

我正在使用类似的子窗口小部件进行底部导航,其中仅更改了参数。仅当小部件为 StatefulWidget 时,才会发生此问题,否则没有问题,bottomnavbar中的指示正在更改,但正文没有更改。

孩子1: enter image description here

孩子2: enter image description here

实际结果: enter image description here

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;

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

class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
Widget body;
@override
void initState() {
//    body = getBody(0);
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(
    title: Text(widget.title),
    elevation: 0,
  ),
  body: body,
  bottomNavigationBar: BottomNavigationBar(
    currentIndex: _counter,
    onTap: (index){
      _counter = index;
      setState(() {
        body = getBody(index);
      });
    },items: [
    BottomNavigationBarItem(icon: Icon(Icons.language),title: 
 Text('HELLO')),
    BottomNavigationBarItem(icon: Icon(Icons.security),title: 
Text('BYE'))
  ]),
 );
}
Widget getBody(int pos){
if(pos==0){
//      return new Mx(category: 'ALPHA',type: '@',);
  return new MyTAbs(category: 'ALPHA',type: '@',);
}
else{
//      return new Mx(category:'BETA',type: '#',);
  return new MyTAbs(category:'BETA',type: '#',);
  }
 }
}
class Mx extends StatelessWidget{
final String type,category;
Mx({this.type,this.category});
@override
Widget build(BuildContext context) {
 return new Scaffold(
  backgroundColor: getColor(),
  body: new Center(
    child: Text(category+' '+type),
  ),
 );
}
Color getColor(){
if(category=='ALPHA'){
  return Colors.red;
}
else{
  return Colors.green;
  }
 }
}
class MyTAbs extends StatefulWidget{
final String type,category;
MyTAbs({this.type,this.category});
Tabs createState() => new Tabs(title: category,type: type);
}
class Tabs extends State<MyTAbs>{
final String title,type;
Tabs({this.title,this.type});
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
  backgroundColor: getColor(),
  appBar: AppBar(
    title: Text(title+' '+type),
  ),
);
}
Color getColor(){
if(title=='ALPHA'){
  return Colors.red;
}
else{
  return Colors.green;
  }
 }
}

,而且我不能使用 statelessWidget ,因为其中有一个动态标签页。

3 个答案:

答案 0 :(得分:1)

“ MyTAbs”传递参数类中的问题

修改后,现在可以正常工作

您不需要将日期从“状态”类传递到“状态”,只需在状态中使用“ widget.parameterName”进行调用 编辑后的代码:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  Widget body;
  @override
  void initState() {
//    body = getBody(0);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        elevation: 0,
      ),
      body: body,
      bottomNavigationBar: BottomNavigationBar(
          currentIndex: _counter,
          onTap: (index){
            _counter = index;
            setState(() {
              body = getBody(index);
            });
          },items: [
        BottomNavigationBarItem(icon: Icon(Icons.language),title:
        Text('HELLO')),
        BottomNavigationBarItem(icon: Icon(Icons.security),title:
        Text('BYE'))
      ]),
    );
  }
  Widget getBody(int pos){
    if(pos==0){
//      return new Mx(category: 'ALPHA',type: '@',);
      return new MyTAbs(category: 'ALPHA',type: '@',);
    }
    else{

//      return new Mx(category:'BETA',type: '#',);
      return new MyTAbs(category:'BETA',type: '#',);
    }
  }
}
class Mx extends StatelessWidget{
  final String type,category;
  Mx({this.type,this.category});
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      backgroundColor: getColor(),
      body: new Center(
        child: Text(category+' '+type),
      ),
    );
  }
  Color getColor(){
    if(category=='ALPHA'){
      return Colors.red;
    }
    else{
      return Colors.green;
    }
  }
}
class MyTAbs extends StatefulWidget{
  final String type,category;
  MyTAbs({this.type,this.category});
  Tabs createState() => new Tabs();
}
class Tabs extends State<MyTAbs>{


  @override
  Widget build(BuildContext context) {
    print(widget.type);
// TODO: implement build
    return new Scaffold(
      backgroundColor: getColor(),
      appBar: AppBar(
        title: Text(widget.category+' '+widget.type),
      ),
    );
  }
  Color getColor(){
    if(widget.category=='ALPHA'){
      return Colors.red;
    }
    else{
      return Colors.green;
    }
  }
}

答案 1 :(得分:0)

更改您的Tabs班级

class Tabs extends State<MyTAbs> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      backgroundColor: getColor(),
      appBar: AppBar(
        title: Text(widget.category + ' ' + widget.type),
      ),
    );
  }

  Color getColor() {
    if (widget.category == 'ALPHA') {
      return Colors.red;
    } else {
      return Colors.green;
    }
  }
}

StateTabs)仅创建一次。因此,之后就无法使用新参数调用构造函数。但是您可以访问小部件的字段

答案 2 :(得分:0)

通过添加新的Key作为参数并传递了 UniqueKey 解决了此问题 喜欢

return new MyTAbs(category: 'ALPHA',type: '@',key: UniqueKey(),);

MyTAbs类

class MyTAbs extends StatefulWidget{
  final String type,category;
  final Key key;
  MyTAbs({@required this.key,this.type,this.category});
  Tabs createState() => new Tabs(title: category,type: type,key: key);
}

标签类

class Tabs extends State<MyTAbs>{
  final String title,type;
  final Key key;
  Tabs({this.title,this.type,@required this.key});
  @override
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      backgroundColor: getColor(),
      appBar: AppBar(
        title: Text(title+' '+type),
      ),
    );
  }
  Color getColor(){
    if(title=='ALPHA'){
      return Colors.red;
    }
    else{
      return Colors.green;
    }
  }
}

关于密钥

您可以使用键来控制在重建小部件时框架与其他小部件匹配的小部件。默认情况下,框架会根据它们的runtimeType和它们显示的顺序来匹配当前版本和先前版本中的窗口小部件。对于键,框架要求两个小部件具有相同的键和相同的runtimeType。 more in flutter docs