首页 > 解决方案 > flutter 更新列表,setstate 不起作用

问题描述

视频:https ://drive.google.com/file/d/1Nh49PxHeCak4YkaCHVec8hQCzgTN7Kr-/view?usp=sharing

子组件点击回调函数,不能通过改变list的值来改变子组件的背景颜色

我尝试使用深拷贝,但仍然无法正常工作。如何更改代码以切换背景颜色?

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      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> {
  List<bool> tabsActive = [true,false,false,false,false];

  void changeTabs(int view) {
    print("view:$view");
    for(int i = 0;i < tabsActive.length;i++) {
      tabsActive[i] = false;
    }

    setState(() {
      tabsActive[view-1] = true;
    });
    print(tabsActive);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body:Center(
        child: Row(
          children: <Widget>[
            GameTabs("tab1",1,tabsActive[0],changeTabs),
            GameTabs("tab2",2,tabsActive[1],changeTabs),
            GameTabs("tab3",3,tabsActive[2],changeTabs),
            GameTabs("tab4",4,tabsActive[3],changeTabs),
            GameTabs("tab5",5,tabsActive[4],changeTabs),
          ],
        ),
      )
    );
  }
}
typedef CallIntFun = void Function(int);
class GameTabs extends StatefulWidget {
  final String title;
  final int view;
  final bool active;
  CallIntFun changeTabs;
  GameTabs(this.title,this.view,this.active,this.changeTabs);
  @override
  _GameTabsState createState() => _GameTabsState(title,view,active,changeTabs);
}

class _GameTabsState extends State<GameTabs> with SingleTickerProviderStateMixin {
  AnimationController _controller;
  final String title;
  final int view;
  final bool active;
  Color bgColor;
  CallIntFun changeTabs;


  _GameTabsState(this.title,this.view,this.active,this.changeTabs);



  @override
  Widget build(BuildContext context) {
    if (active) {
      return ActiveGameTabs(title);
    }
    return Expanded(
        child: GestureDetector(
          onTap: (){
            changeTabs(view);
          },
          child: Container(
            height: 56,
            padding: EdgeInsets.fromLTRB(0, 6, 0, 0),
            decoration: BoxDecoration(
              color: Color.fromRGBO(235, 235, 235, 1),
              border: Border.all(
                  color: Colors.green,
                  width: 3.0,
                  style: BorderStyle.none
              ),
            ),
            child: Text(
              title,
              textAlign: TextAlign.center,
            ),
          ),
        )
    );
  }
}


class ActiveGameTabs extends StatelessWidget {
  final String title;
  ActiveGameTabs(this.title);
  @override
  Widget build(BuildContext context) {
    return Expanded(
        child: Container(
          height: 56,
          padding: EdgeInsets.fromLTRB(0, 6, 0, 0),
          decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(
                color: Colors.green,
                width: 3.0,
                style: BorderStyle.none
            ),
          ),
          child: Text(
            title,
            textAlign: TextAlign.center,
          ),
        )
    );
  }
}

标签: flutter

解决方案


当第一次创建状态时,您将值从小部件传递到状态。所以当这些属性中的任何一个发生变化时它不会改变(因为不会每次都创建状态)。您想像这样更改您的 GameTab 实现:

class GameTabs extends StatefulWidget {
  final String title;
  final int view;
  final bool active;
  CallIntFun changeTabs;
  GameTabs(this.title,this.view,this.active,this.changeTabs);
  @override
  _GameTabsState createState() => _GameTabsState();
}

class _GameTabsState extends State<GameTabs> with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  Widget build(BuildContext context) {
    if (widget.active) {
      return ActiveGameTabs(widget.title);
    }
    return Expanded(
        child: GestureDetector(
          onTap: (){
            widget.changeTabs(widget.view);
          },
          child: Container(
            height: 56,
            padding: EdgeInsets.fromLTRB(0, 6, 0, 0),
            decoration: BoxDecoration(
              color: Color.fromRGBO(235, 235, 235, 1),
              border: Border.all(
                  color: Colors.green,
                  width: 3.0,
                  style: BorderStyle.none
              ),
            ),
            child: Text(
              widget.title,
              textAlign: TextAlign.center,
            ),
          ),
        )
    );
  }
}

推荐阅读