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

簡單功能:就是把選中的值返回給調用者app

問題描述:在返回值函數裏,強制把選中的值改成 0,發現沒有效果?ide

結論:按照官網的文檔說法,widget會由架構來判斷是否會刷新,判斷會刷新了才刷新。恰好,我這種寫法是被判斷爲不刷新。函數

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

問題出在以上代碼中。我在State類從新定義了一個屬性在initState函數中接收StatefulWidget的屬性,致使的出現這樣子的問題。測試

正確的作法是在State的build方法中直接使用StatefulWidget的屬性。便是widget.choosedItem在build方法中直接使用。ui

緣由:State的initState只執行了一次,後面StatefulWidget的choosedItem更改了,可是沒有再次執行initState方法,致使_choosedItem沒有跟着更改。因此界面就不會跟着更改。this

結論:StatefulWidget是State的配置文件,在State中直接使用StatefulWidget的屬性。spa

以上代碼改成:code

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,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
相關文章
相關標籤/搜索