下面附有代码。 如何创建具有不同颜色的Shape的新小部件, 从下拉菜单中选择,通过按灰色按钮(COLOR CHANGE), 根据下拉菜单中选择的内容? 顶部的Container在这里无事可做,只是一个占位符。
我已经对其进行了测试,没有Widgets MySquare,MyRound和MyRectangle仅根据下拉选择更改颜色,并且可以正常工作。但是,使用其他窗口小部件类MySquare,MyRound和MyRectangle似乎不会重绘新的窗口小部件。
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyTrial(strShape: 'ROUND'));
}
}
class MyTrial extends StatefulWidget{
final String strShape;
MyTrial({this.strShape});
@override
MyTrialState createState() {
return new MyTrialState();
}
}
class MyTrialState extends State<MyTrial> {
List<String> listShapes;
String strShapeSelected;
Widget widgetType;
@override
void initState() {
super.initState();
listShapes = ['SQUARE', 'ROUND','RECTANGLE'];
strShapeSelected = widget.strShape;
widgetType = _myGetShape('ROUND');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Change\nColor'),
actions: <Widget>[
/// button to change color
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: GestureDetector(onTap: () {
_myChangeShapeColor(strShapeSelected);
setState(() {});
//print('Gesture $strShapeSelected');
},
child: new Container(
child: new Center(
child: new Padding(
padding: const EdgeInsets.all(5.0),
child: new Text('COLOR\nCHANGE',textAlign: TextAlign.center,),
)),
decoration: new BoxDecoration(
color: Colors.blueGrey, shape: BoxShape.circle),
),
),
),
/// drop down list
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: DropdownButton<String>(
items: listShapes.map((String value) {
return new DropdownMenuItem(
child: new Text('$value'),
value: value,
);
}).toList(),
value: strShapeSelected,
onChanged: (String newValue) {
setState(() {
strShapeSelected = newValue;
});
widgetType = _myGetShape(strShapeSelected);
}),
)
],),
body: Column(
children: <Widget>[
/// place holder
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
height: 80.0, color: Colors.teal,),
),
/// shape widget
/// changed by drop-down
Center(child: widgetType),
],
),
);
}
Widget _myGetShape(String newValue) {
Widget newShape;
switch(newValue){
case 'SQUARE':
newShape = MySquare(myColor: Colors.brown,);
break;
case 'ROUND':
newShape = MyRound(myColor: Colors.green,);
break;
case 'RECTANGLE':
newShape = MyRectangle(myColor: Colors.blue,);
break;
}
return newShape;
}
void _myChangeShapeColor(String strNewShape) {
switch(strNewShape){
case 'SQUARE':
widgetType = MySquare(myColor: Colors.amber,);
break;
case 'ROUND':
widgetType = MyRound(myColor: Colors.lightGreenAccent,);
break;
case 'RECTANGLE':
widgetType = MyRectangle(myColor: Colors.purple,);
break;
}
setState(() {});
}
}
/// SQUARE
class MySquare extends StatefulWidget{
final Color myColor;
MySquare({this.myColor});
@override
MySquareState createState() {
return new MySquareState();
}
}
class MySquareState extends State<MySquare> {
Color newColor;
@override
void initState() {
newColor = widget.myColor;
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(child: Center(
child: Text('SQUARE',style: TextStyle(fontSize: 15.0))),
color: newColor,
width: 120.0,height: 120.0,);
}
}
/// ROUND
class MyRound extends StatefulWidget{
final Color myColor;
MyRound({this.myColor});
@override
MyRoundState createState() {
return new MyRoundState();
}
}
class MyRoundState extends State<MyRound> {
Color newColor;
@override
void initState() {
newColor = widget.myColor;
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(child: Center(
child: Text('ROUND',style: TextStyle(fontSize: 15.0))),
decoration: BoxDecoration(color: newColor,
shape: BoxShape.circle),
width: 120.0,height: 120.0,);
}
}
/// RECTANGLE
class MyRectangle extends StatefulWidget{
final Color myColor;
MyRectangle({this.myColor});
@override
MyRectangleState createState() {
return new MyRectangleState();
}
}
class MyRectangleState extends State<MyRectangle> {
Color newColor;
@override
void initState() {
newColor = widget.myColor;
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(child: Center(
child: Text('RECTANGLE',style: TextStyle(fontSize: 15.0))),
color: newColor,
width: 200.0,height: 120.0,);
}
}
答案 0 :(得分:1)
您需要在MySquare,MyRound & MyRectangle
中转换-StatelessWidget
类。其余代码保持不变,并且可以按预期工作。
现在您将其命名为StatefulWidget
-因此它们一旦初始化便保持状态。因此不会改变颜色。
/// SQUARE
class MySquare extends StatelessWidget {
final Color myColor;
MySquare({this.myColor});
@override
Widget build(BuildContext context) {
return Container(
child: Center(child: Text('SQUARE', style: TextStyle(fontSize: 15.0))),
color: myColor,
width: 120.0,
height: 120.0,
);
}
}
与矩形和圆形相同。
更新:
如果要将其保留为StatefulWidget
。然后,您需要使用-didUpdateWidget方法。
class MySquareState extends State<MySquare> {
Color newColor;
@override
void initState() {
newColor = widget.myColor;
super.initState();
}
@override
void didUpdateWidget(MySquare oldWidget) {
super.didUpdateWidget(oldWidget);
print('Called');
newColor = widget.myColor;
}
@override
Widget build(BuildContext context) {
return Container(child: Center(
child: Text('SQUARE',style: TextStyle(fontSize: 15.0))),
color: newColor,
width: 120.0,height: 120.0,);
}
}