Flutter不会使用不同的参数重建相同的小部件

问题描述 投票:5回答:3

我正在使用底部导航和类似的子窗口小部件,其中只有参数被更改。只有当窗口小部件是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,因为里面有一个动态标签部分。

dart flutter flutter-layout
3个回答
1
投票

改变你的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)只创建了一次。所以在那之后你不能用新参数调用构造函数。但是您可以访问小部件的字段


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
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.