问题描述
我有三个小部件,第一个是 LightBulb(stateless)
,它们具有一些颜色属性.第二个是名为 LightColorSelector(stateless)
的小部件,该小部件具有 DropdownMenu
,其字符串类型为 Red
, Green
和 Blue
.并且,第三个类是 Classroom(有状态的小部件)
,它是这两个类的父类.我的目的是设置该类的状态.我需要在 Classroom
内设置这三种颜色的列表,当有人单击 LightColorSelector
项之一时, LightBulb
应该根据单击颜色.但是, LightBulb
中的颜色始终返回null.我认为没有设置.实际上,我可能知道错误在哪里.我认为在 LightColorSelector
函数中有一个 onChanged
属性,并且我没有将 value
设置为 func()代码>.我在下面标记了我怀疑发生错误的地方.
I have three widgets first one is LightBulb(stateless)
that have some color properties. The second one is widget named as LightColorSelector(stateless)
that has a DropdownMenu
with string type items Red
, Green
and Blue
. And, the third class is Classroom(stateful widget)
which is the parent of that two classes. My aim is to set the states from that class.I need to set a list of that three colors inside the Classroom
, when someone clicks on one of the LightColorSelector
items the LightBulb
should switches according to clicked color. However, the color inside the LightBulb
returns always null. I think it didn't set. Actually, I might know where is the mistake. I think in the LightColorSelector
function there is a onChanged
property and I didn't set the value
into the func()
. I marked below where I suspect the mnistake is occur.
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class LightBulb extends StatelessWidget {
bool isLit;
Color color;
LightBulb(bool isLit, Color color) {
this.isLit = isLit;
this.color = color;
print(color.toString());
}
Widget build(BuildContext context) {
return Container(
color: isLit ? color : Colors.red,
padding: EdgeInsets.all(5),
child: isLit ? Text('ON') : Text('OFF'),
);
}
}
class LightButton extends StatelessWidget {
Function func;
bool isLightOn;
LightButton(Function func, bool iSLightOn) {
this.func = func;
this.isLightOn = iSLightOn;
}
String title() {
if (isLightOn) return "Turn light off";
return "Turn light on";
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 12),
color: Colors.red,
child: Container(
color: Colors.blue,
child: MaterialButton(
textColor: Colors.white,
onPressed: () => func(),
child: Text(
title(),
style: TextStyle(color: Colors.white),
),
),
),
);
}
}
class Classroom extends StatefulWidget {
@override
_ClassroomState createState() => _ClassroomState();
}
class _ClassroomState extends State<Classroom> {
bool isLightOn = false;
String title = "Not set yet";
List<Color> lightColor = [Colors.red, Colors.green, Colors.blue];
Color color;
String value;
selectLightColor() {
setState(() {
if (value == 'Red') color = lightColor[0];
if (value == 'Green') color = lightColor[1];
if (value == 'Blue')
color = lightColor[2];
else
color = Colors.amber;
});
}
onButtonPressed() {
setState(() {
isLightOn = !isLightOn;
});
}
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.blue,
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
LightBulb(isLightOn, color),
LightButton(onButtonPressed, isLightOn),
LightColorSelector(selectLightColor),
],
),
),
);
}
}
class LightColorSelector extends StatelessWidget {
String initialVal = 'Red';
Function func;
LightColorSelector(Function func) {
this.func = func;
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10),
child: DropdownButton(
value: initialVal,
onChanged: (value) => func, // =========== Here the error occurs ==========================
items: <String>['Red', 'Green', 'Blue']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
));
}
}
样本输出
推荐答案
您可以在
下复制粘贴运行完整代码步骤1:在 _ClassroomState
class _ClassroomState extends State<Classroom> {
..
Color color = Colors.red;
String value = 'Red';
第2步:回调函数 selectLightColor
需要参数 selectedValue
并使用 if if if
,则此处出现逻辑错误
Step 2: Callback function selectLightColor
need parameter selectedValue
and use if else if
, you have logic error here
selectLightColor(String selectedValue) {
setState(() {
value = selectedValue;
if (selectedValue == 'Red') {
color = lightColor[0];
} else if (selectedValue == 'Green') {
color = lightColor[1];
} else if (selectedValue == 'Blue')
color = lightColor[2];
else
color = Colors.amber;
});
}
第3步: LightColorSelector
构造函数
和 onChanged
需要设置 initialVal
和 onChanged
需要调用 func(value)
;
Step 3: LightColorSelector
constructor
and onChanged
need to set initialVal
and onChanged
need to call func(value)
;
class LightColorSelector extends StatelessWidget {
String initialVal;
Function func;
LightColorSelector(Function func, String value) {
this.func = func;
this.initialVal = value;
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10),
child: DropdownButton<String>(
value: initialVal,
onChanged: (value) {
initialVal = value;
func(value);
},
工作演示
完整代码
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(body: Classroom()),
);
}
}
// ignore: must_be_immutable
class LightBulb extends StatelessWidget {
bool isLit;
Color color;
LightBulb(bool isLit, Color color) {
this.isLit = isLit;
this.color = color;
print(color.toString());
}
Widget build(BuildContext context) {
return Container(
color: isLit ? color : Colors.red,
padding: EdgeInsets.all(5),
child: isLit ? Text('ON') : Text('OFF'),
);
}
}
class LightButton extends StatelessWidget {
Function func;
bool isLightOn;
LightButton(Function func, bool iSLightOn) {
this.func = func;
this.isLightOn = iSLightOn;
}
String title() {
if (isLightOn) return "Turn light off";
return "Turn light on";
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 12),
color: Colors.red,
child: Container(
color: Colors.blue,
child: MaterialButton(
textColor: Colors.white,
onPressed: () => func(),
child: Text(
title(),
style: TextStyle(color: Colors.white),
),
),
),
);
}
}
class Classroom extends StatefulWidget {
@override
_ClassroomState createState() => _ClassroomState();
}
class _ClassroomState extends State<Classroom> {
bool isLightOn = false;
String title = "Not set yet";
List<Color> lightColor = [Colors.red, Colors.green, Colors.blue];
Color color = Colors.red;
String value = 'Red';
selectLightColor(String selectedValue) {
setState(() {
value = selectedValue;
if (selectedValue == 'Red') {
color = lightColor[0];
} else if (selectedValue == 'Green') {
color = lightColor[1];
} else if (selectedValue == 'Blue')
color = lightColor[2];
else
color = Colors.amber;
});
}
onButtonPressed() {
setState(() {
isLightOn = !isLightOn;
});
}
@override
Widget build(BuildContext context) {
return Center(
child: Container(
//color: Colors.blue,
padding: EdgeInsets.all(5),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
LightBulb(isLightOn, color),
LightButton(onButtonPressed, isLightOn),
LightColorSelector(selectLightColor, value),
],
),
),
);
}
}
class LightColorSelector extends StatelessWidget {
String initialVal;
Function func;
LightColorSelector(Function func, String value) {
this.func = func;
this.initialVal = value;
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10),
child: DropdownButton<String>(
value: initialVal,
onChanged: (value) {
initialVal = value;
func(value);
},
items: <String>['Red', 'Green', 'Blue']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
));
}
}
这篇关于来自有状态父级的无状态小部件dropdownButton的Setstate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!