list中改变值,setState无法刷新小部件【解答】

今天刷Flutter社区的时候,碰巧看到了一个这样的问题,回想了一下自己最近一个月也遇到不少关于setState无效的问题,请教了下同事,果然姜还是老的辣,哈哈~
温馨提示:由于本人文笔欠佳和涉世尚浅,如果你理解不了的话,请尝试一下自己打断点操作,这真的对理解很有帮助)

引入问题link.

(以上链接就是别人的问题,此处就不另外把问题描述一遍了,大家从上面链接查看原问题把!)

原因

父widget用到子widget时,第一次使用时,会执行子widget中声明的构造函数,之后就不会执行了,但是子widget的build还是会执行的。最好的测试方法就是打断点,见图:

解说断点测试

打完下面三个断点,运行代码,我们知道每次界面渲染的时候,是渲染1次Row,然后5次带不同参数的GameTabs,循环如此。设置断点后按F9执行下一步,会发现,三个断点的执行情况是1-2-3-2-3-2-3-2-3-2-3–>1-3-3-3-3-3–>1-3-3-3-3-3…,也就是说除了第一次渲染的时候,对active重新赋了值,之后setState重构界面时,用的还是之前的active。
在这里插入图片描述

解决方案

细心的小伙伴已经发现我将

if (active) {
  return ActiveGameTabs(title);
}

修改为

if (widget.active) {
  return ActiveGameTabs(title);
}

目的是使得build子组件的时候,我们使用的是GameTabs这个widget的active,每次重构的时候GameTabs构造方法会被调用,但是_GameTabsState构造方法不会被调用,和widget的状态有关系(StatefulWidget与State)。

修改:

针对他人的代码略做了点改动

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'dart:ui';

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();
}

List<bool> tabsActive = [true,false,false,false,false];
class _MyHomePageState extends State<MyHomePage> {

  void changeTabs(int view) {
    print("change");
    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) {
//    print("build2");
    return Scaffold(
        body:Container(
//          padding: EdgeInsets.only(top: MediaQueryData.fromWindow(window).padding.top),
          padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
          child: Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              GameTabs("tab1",1,tabsActive[0],changeTabs).featureView(),
              GameTabs("tab2",2,tabsActive[1],changeTabs).featureView(),
              GameTabs("tab3",3,tabsActive[2],changeTabs).featureView(),
              GameTabs("tab4",4,tabsActive[3],changeTabs).featureView(),
              GameTabs("tab5",5,tabsActive[4],changeTabs).featureView(),
            ],
          ),
        )
    );
    print(tabsActive[3]);
  }
}
typedef CallIntFun = void Function(int);
class GameTabs {
  final String title;
  final int view;
  final bool active;
  final CallIntFun changeTabs;
  GameTabs(this.title,this.view,this.active,this.changeTabs);

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

欢迎提问和纠错哈~❤

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值