Flutter Widget不刷新问题

复制代码
import 'package:flutter/material.dart';

/// 温度显示 -- ok
class TemperatureIndication extends StatefulWidget {
  final ValueChanged<int> valueChanged;
  final int choosedItem;

  TemperatureIndication({this.valueChanged, this.choosedItem = 0});

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

class _TemperatureIndicationState extends State<TemperatureIndication> {
  int _choosedItem = 0;

  @override
  void initState() {
    super.initState();
   // 错误点在这里 _choosedItem
= widget.choosedItem; print('_TemperatureIndicationState initState:$_choosedItem'); } @override Widget build(BuildContext context) { // _choosedItem = widget.choosedItem; // print('_TemperatureIndicationState build:$_choosedItem'); return _buildItem(); } Widget _buildItem() { return Padding( padding: const EdgeInsets.symmetric(horizontal: 32.0), child: Column( children: <Widget>[ _buildTextItem(), Padding(padding: const EdgeInsets.only(top: 4.0)), _buildButtonItem(), ], ), ); } Widget _buildTextItem() { return Row( children: <Widget>[ Expanded( child: Center(child: Text('切')), ), Expanded( child: Center(child: Text('低')), ), Expanded( child: Center(child: Text('中')), ), Expanded( child: Center(child: Text('高')), ), ], ); } Widget _buildButtonItem() { return DecoratedBox( decoration: BoxDecoration(border: Border.all(width: 1.5, color: Color(0xffd6def1))), child: Row( children: <Widget>[ Expanded( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { _choosedItem = 0; setState(() {}); if (widget.valueChanged != null) { widget.valueChanged(0); } }, child: DecoratedBox( decoration: _choosedItem == 0 ? BoxDecoration( color: Colors.grey, ) : BoxDecoration(), child: Container( height: 28.0, ), ), ), ), Expanded( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { _choosedItem = 1; setState(() {}); if (widget.valueChanged != null) { widget.valueChanged(1); } }, child: DecoratedBox( decoration: _choosedItem == 1 ? BoxDecoration( color: Color(0xfffe0007), ) : BoxDecoration(), child: Container( height: 28.0, ), ), ), ), Expanded( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { _choosedItem = 2; setState(() {}); if (widget.valueChanged != null) { widget.valueChanged(2); } }, child: DecoratedBox( decoration: _choosedItem == 2 ? BoxDecoration( color: Color(0xfffe0007), ) : BoxDecoration(), child: Container( height: 28.0, ), ), ), ), Expanded( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { _choosedItem = 3; setState(() {}); if (widget.valueChanged != null) { widget.valueChanged(3); } }, child: DecoratedBox( decoration: _choosedItem == 3 ? BoxDecoration( color: Color(0xfffe0007), ) : BoxDecoration(), child: Container( height: 28.0, ), ), ), ), ], ), ); } }
复制代码

测试代码:

复制代码
@override
  Widget build(BuildContext context) {
    print('父类build问题:$chooseItem');
    return Scaffold(
      appBar: AppBar(),
      body: TemperatureIndication(
        valueChanged: (i) {
          chooseItem = i;
          print('点击选中的值:$chooseItem');
          chooseItem = 0;
          print('强制更改的值:$chooseItem');
          setState(() {});
        },
        choosedItem: chooseItem,
      ),
    );
  }
复制代码

简单功能:就是把选中的值返回给调用者

问题描述:在返回值函数里,强制把选中的值改为 0,发现没有效果?

结论:按照官网的文档说法,widget会由架构来判断是否会刷新,判断会刷新了才刷新。刚好,我这种写法是被判断为不刷新。

@override
  void initState() {
    super.initState();
    _choosedItem = widget.choosedItem;
    print('_TemperatureIndicationState initState:$_choosedItem');
  }

问题出在以上代码中。我在State类重新定义了一个属性在initState函数中接收StatefulWidget的属性,导致的出现这样子的问题。

正确的做法是在State的build方法中直接使用StatefulWidget的属性。即是widget.choosedItem在build方法中直接使用。

原因:State的initState只执行了一次,后面StatefulWidget的choosedItem更改了,但是没有再次执行initState方法,导致_choosedItem没有跟着更改。所以界面就不会跟着更改。

结论:StatefulWidget是State的配置文件,在State中直接使用StatefulWidget的属性。

以上代码改为:

复制代码
import 'package:flutter/material.dart';

/// 温度显示 -- ok
class TemperatureIndication extends StatefulWidget {
  final ValueChanged<int> valueChanged;
  final int choosedItem;

  TemperatureIndication({this.valueChanged, this.choosedItem = 0});

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

class _TemperatureIndicationState extends State<TemperatureIndication> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return _buildItem();
  }

  Widget _buildItem() {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 32.0),
      child: Column(
        children: <Widget>[
          _buildTextItem(),
          Padding(padding: const EdgeInsets.only(top: 4.0)),
          _buildButtonItem(),
        ],
      ),
    );
  }

  Widget _buildTextItem() {
    return Row(
      children: <Widget>[
        Expanded(
          child: Center(child: Text('切')),
        ),
        Expanded(
          child: Center(child: Text('低')),
        ),
        Expanded(
          child: Center(child: Text('中')),
        ),
        Expanded(
          child: Center(child: Text('高')),
        ),
      ],
    );
  }

  Widget _buildButtonItem() {
    return DecoratedBox(
      decoration: BoxDecoration(border: Border.all(width: 1.5, color: Color(0xffd6def1))),
      child: Row(
        children: <Widget>[
          Expanded(
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () {
                setState(() {});
                if (widget.valueChanged != null) {
                  widget.valueChanged(0);
                }
              },
              child: DecoratedBox(
                decoration: widget.choosedItem == 0
                    ? BoxDecoration(
                        color: Colors.grey,
                      )
                    : BoxDecoration(),
                child: Container(
                  height: 28.0,
                ),
              ),
            ),
          ),
          Expanded(
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () {
                setState(() {});
                if (widget.valueChanged != null) {
                  widget.valueChanged(1);
                }
              },
              child: DecoratedBox(
                decoration: widget.choosedItem == 1
                    ? BoxDecoration(
                        color: Color(0xfffe0007),
                      )
                    : BoxDecoration(),
                child: Container(
                  height: 28.0,
                ),
              ),
            ),
          ),
          Expanded(
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () {
                setState(() {});
                if (widget.valueChanged != null) {
                  widget.valueChanged(2);
                }
              },
              child: DecoratedBox(
                decoration: widget.choosedItem == 2
                    ? BoxDecoration(
                        color: Color(0xfffe0007),
                      )
                    : BoxDecoration(),
                child: Container(
                  height: 28.0,
                ),
              ),
            ),
          ),
          Expanded(
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () {
                setState(() {});
                if (widget.valueChanged != null) {
                  widget.valueChanged(3);
                }
              },
              child: DecoratedBox(
                decoration: widget.choosedItem == 3
                    ? BoxDecoration(
                        color: Color(0xfffe0007),
                      )
                    : BoxDecoration(),
                child: Container(
                  height: 28.0,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
复制代码

 

posted @   柏。  阅读(6563)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示