• 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( 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( 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,
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      }
    }
  • 相关阅读:
    Linux防火墙管理(iptables)以及开放端口配置
    CSS 样式引入方式、常用选择器以及优先级权重的计算
    初识外边距合并-margin collapsing
    纯CSS实现自适应正方形
    常用正则
    vue 学习记录
    VScode 之快速创建vue模板
    vscode之常用插件
    工具函数
    Axios之配置参数
  • 原文地址:https://www.cnblogs.com/hbolin/p/10607719.html
Copyright © 2020-2023  润新知