Flutter Widget不刷新问题

1import 'package:flutter/material.dart'; 2 3/// 温度显示 -- ok 4class TemperatureIndication extends StatefulWidget { 5 final ValueChanged<int> valueChanged; 6 final int choosedItem; 7 8 TemperatureIndication({this.valueChanged, this.choosedItem = 0}); 9 10 @override 11 _TemperatureIndicationState createState() => _TemperatureIndicationState(); 12} 13 14class _TemperatureIndicationState extends State<TemperatureIndication> { 15 int _choosedItem = 0; 16 17 @override 18 void initState() { 19 super.initState();   // 错误点在这里 20 _choosedItem = widget.choosedItem; 21 print('_TemperatureIndicationState initState:$_choosedItem'); 22 } 23 24 @override 25 Widget build(BuildContext context) { 26// _choosedItem = widget.choosedItem; 27// print('_TemperatureIndicationState build:$_choosedItem'); 28 return _buildItem(); 29 } 30 31 Widget _buildItem() { 32 return Padding( 33 padding: const EdgeInsets.symmetric(horizontal: 32.0), 34 child: Column( 35 children: <Widget>[ 36 _buildTextItem(), 37 Padding(padding: const EdgeInsets.only(top: 4.0)), 38 _buildButtonItem(), 39 ], 40 ), 41 ); 42 } 43 44 Widget _buildTextItem() { 45 return Row( 46 children: <Widget>[ 47 Expanded( 48 child: Center(child: Text('切')), 49 ), 50 Expanded( 51 child: Center(child: Text('低')), 52 ), 53 Expanded( 54 child: Center(child: Text('中')), 55 ), 56 Expanded( 57 child: Center(child: Text('高')), 58 ), 59 ], 60 ); 61 } 62 63 Widget _buildButtonItem() { 64 return DecoratedBox( 65 decoration: BoxDecoration(border: Border.all(width: 1.5, color: Color(0xffd6def1))), 66 child: Row( 67 children: <Widget>[ 68 Expanded( 69 child: GestureDetector( 70 behavior: HitTestBehavior.opaque, 71 onTap: () { 72 _choosedItem = 0; 73 setState(() {}); 74 if (widget.valueChanged != null) { 75 widget.valueChanged(0); 76 } 77 }, 78 child: DecoratedBox( 79 decoration: _choosedItem == 0 80 ? BoxDecoration( 81 color: Colors.grey, 82 ) 83 : BoxDecoration(), 84 child: Container( 85 height: 28.0, 86 ), 87 ), 88 ), 89 ), 90 Expanded( 91 child: GestureDetector( 92 behavior: HitTestBehavior.opaque, 93 onTap: () { 94 _choosedItem = 1; 95 setState(() {}); 96 if (widget.valueChanged != null) { 97 widget.valueChanged(1); 98 } 99 }, 100 child: DecoratedBox( 101 decoration: _choosedItem == 1 102 ? BoxDecoration( 103 color: Color(0xfffe0007), 104 ) 105 : BoxDecoration(), 106 child: Container( 107 height: 28.0, 108 ), 109 ), 110 ), 111 ), 112 Expanded( 113 child: GestureDetector( 114 behavior: HitTestBehavior.opaque, 115 onTap: () { 116 _choosedItem = 2; 117 setState(() {}); 118 if (widget.valueChanged != null) { 119 widget.valueChanged(2); 120 } 121 }, 122 child: DecoratedBox( 123 decoration: _choosedItem == 2 124 ? BoxDecoration( 125 color: Color(0xfffe0007), 126 ) 127 : BoxDecoration(), 128 child: Container( 129 height: 28.0, 130 ), 131 ), 132 ), 133 ), 134 Expanded( 135 child: GestureDetector( 136 behavior: HitTestBehavior.opaque, 137 onTap: () { 138 _choosedItem = 3; 139 setState(() {}); 140 if (widget.valueChanged != null) { 141 widget.valueChanged(3); 142 } 143 }, 144 child: DecoratedBox( 145 decoration: _choosedItem == 3 146 ? BoxDecoration( 147 color: Color(0xfffe0007), 148 ) 149 : BoxDecoration(), 150 child: Container( 151 height: 28.0, 152 ), 153 ), 154 ), 155 ), 156 ], 157 ), 158 ); 159 } 160}

测试代码:

1@override 2 Widget build(BuildContext context) { 3 print('父类build问题:$chooseItem'); 4 return Scaffold( 5 appBar: AppBar(), 6 body: TemperatureIndication( 7 valueChanged: (i) { 8 chooseItem = i; 9 print('点击选中的值:$chooseItem'); 10 chooseItem = 0; 11 print('强制更改的值:$chooseItem'); 12 setState(() {}); 13 }, 14 choosedItem: chooseItem, 15 ), 16 ); 17 }

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

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

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

1@override 2 void initState() { 3 super.initState(); 4 _choosedItem = widget.choosedItem; 5 print('_TemperatureIndicationState initState:$_choosedItem'); 6 }

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

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

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

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

以上代码改为:

1import 'package:flutter/material.dart'; 2 3/// 温度显示 -- ok 4class TemperatureIndication extends StatefulWidget { 5 final ValueChanged<int> valueChanged; 6 final int choosedItem; 7 8 TemperatureIndication({this.valueChanged, this.choosedItem = 0}); 9 10 @override 11 _TemperatureIndicationState createState() => _TemperatureIndicationState(); 12} 13 14class _TemperatureIndicationState extends State<TemperatureIndication> { 15 @override 16 void initState() { 17 super.initState(); 18 } 19 20 @override 21 Widget build(BuildContext context) { 22 return _buildItem(); 23 } 24 25 Widget _buildItem() { 26 return Padding( 27 padding: const EdgeInsets.symmetric(horizontal: 32.0), 28 child: Column( 29 children: <Widget>[ 30 _buildTextItem(), 31 Padding(padding: const EdgeInsets.only(top: 4.0)), 32 _buildButtonItem(), 33 ], 34 ), 35 ); 36 } 37 38 Widget _buildTextItem() { 39 return Row( 40 children: <Widget>[ 41 Expanded( 42 child: Center(child: Text('切')), 43 ), 44 Expanded( 45 child: Center(child: Text('低')), 46 ), 47 Expanded( 48 child: Center(child: Text('中')), 49 ), 50 Expanded( 51 child: Center(child: Text('高')), 52 ), 53 ], 54 ); 55 } 56 57 Widget _buildButtonItem() { 58 return DecoratedBox( 59 decoration: BoxDecoration(border: Border.all(width: 1.5, color: Color(0xffd6def1))), 60 child: Row( 61 children: <Widget>[ 62 Expanded( 63 child: GestureDetector( 64 behavior: HitTestBehavior.opaque, 65 onTap: () { 66 setState(() {}); 67 if (widget.valueChanged != null) { 68 widget.valueChanged(0); 69 } 70 }, 71 child: DecoratedBox( 72 decoration: widget.choosedItem == 0 73 ? BoxDecoration( 74 color: Colors.grey, 75 ) 76 : BoxDecoration(), 77 child: Container( 78 height: 28.0, 79 ), 80 ), 81 ), 82 ), 83 Expanded( 84 child: GestureDetector( 85 behavior: HitTestBehavior.opaque, 86 onTap: () { 87 setState(() {}); 88 if (widget.valueChanged != null) { 89 widget.valueChanged(1); 90 } 91 }, 92 child: DecoratedBox( 93 decoration: widget.choosedItem == 1 94 ? BoxDecoration( 95 color: Color(0xfffe0007), 96 ) 97 : BoxDecoration(), 98 child: Container( 99 height: 28.0, 100 ), 101 ), 102 ), 103 ), 104 Expanded( 105 child: GestureDetector( 106 behavior: HitTestBehavior.opaque, 107 onTap: () { 108 setState(() {}); 109 if (widget.valueChanged != null) { 110 widget.valueChanged(2); 111 } 112 }, 113 child: DecoratedBox( 114 decoration: widget.choosedItem == 2 115 ? BoxDecoration( 116 color: Color(0xfffe0007), 117 ) 118 : BoxDecoration(), 119 child: Container( 120 height: 28.0, 121 ), 122 ), 123 ), 124 ), 125 Expanded( 126 child: GestureDetector( 127 behavior: HitTestBehavior.opaque, 128 onTap: () { 129 setState(() {}); 130 if (widget.valueChanged != null) { 131 widget.valueChanged(3); 132 } 133 }, 134 child: DecoratedBox( 135 decoration: widget.choosedItem == 3 136 ? BoxDecoration( 137 color: Color(0xfffe0007), 138 ) 139 : BoxDecoration(), 140 child: Container( 141 height: 28.0, 142 ), 143 ), 144 ), 145 ), 146 ], 147 ), 148 ); 149 } 150}
点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Flutter学习之动态ListView

import'package:flutter/material.dart';voidmain(){runApp(listname(item:newList<String.generate(1000,(i)"genarate$i")));}

Flutter

在Flutter加载网页?也是有WebView的哦,和Android一样1.添加依赖dependencies:flutter\_webview\_plugin:^0.2.122.导入库import'import'package:flutter\_webview\_plugin/flutter\_webview\_plug

Flutter中日期组件DatePicker及组件汉化

Flutter提供了DatePicker组件进行时间选择。日期组件及时间组件代码示例:import'package:flutter/material.dart';//第三方插件,需要提前配置import'package:date_format/date_format.dart';classDat

Flutter 页面入栈和出栈

Docs(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fdocs.flutter.io%2Fflutter%2Fwidgets%2FNavigatorclass.html)demoimport'package:flutter/material.dart';

Flutter学习之重叠布局

1.两个元素的重叠布局可以使用stack组件import'package:flutter/material.dart';voidmain(){runApp(MyApp());}classMyAppextendsStatelessWidget{