自有状​​态父级的无状态小部件dropdownButton的Se

自有状​​态父级的无状态小部件dropdownButton的Se

本文介绍了来自有状​​态父级的无状态小部件dropdownButton的Setstate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个小部件,第一个是 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, Greenand 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 02:23