【问题标题】:Flutter is not rebuilding same widget with different parametersFlutter 不会使用不同的参数重建相同的小部件
【发布时间】:2019-08-09 18:07:47
【问题描述】:

我正在使用带有类似子小部件的底部导航,其中仅更改了参数。只有当小部件属于 StatefulWidget 时才会出现问题,否则没有问题,底部导航栏中的指示正在改变,但正文没有改变。

孩子 1:

孩子 2:

实际结果:

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,因为里面有一个动态标签部分。

【问题讨论】:

    标签: dart flutter flutter-layout


    【解决方案1】:

    通过添加新的 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

    【讨论】:

    • 非常感谢,今天遇到同样的问题。我想,如果其中一个参数被更改,Widget 将被重建,但不是,initState() 没有被调用。 UniqKey() 工作正常!
    【解决方案2】:

    更改您的 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;
        }
      }
    }
    

    State (Tabs) 仅创建一次。所以在那之后你不能用新参数调用构造函数。但是您可以访问小部件的字段

    【讨论】:

      【解决方案3】:

      你在“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;
          }
        }
      }
      

      【讨论】:

      • 感谢@abdalmonem,您的回答是正确的,但在我的情况下,我正在 Tabs 类中加载选项卡,因此无法使用您的选项卡,而是添加了一个键作为参数,如上所述。你的回答对我来说是一个新信息。
      猜你喜欢
      • 2020-12-29
      • 2019-12-09
      • 2020-10-01
      • 2021-03-03
      • 1970-01-01
      • 2023-03-04
      • 2018-12-02
      • 2021-08-23
      • 1970-01-01
      相关资源
      最近更新 更多