【问题标题】:How to change container when radio button clicked单击单选按钮时如何更改容器
【发布时间】:2020-12-30 09:42:34
【问题描述】:

我有这个布局:

我想在单击“选择时间”时将此蓝色容器更改为另一个容器

这是单选按钮的代码:

class TimeRadioButtonsClass extends StatefulWidget {
  @override
  _TimeRadioButtonsClassState createState() => _TimeRadioButtonsClassState();
  List<String> labels;
  String picked;
  Function function;
  TimeRadioButtonsClass({this.picked , this.labels , this.function});
}

class _TimeRadioButtonsClassState extends State<TimeRadioButtonsClass> {
  @override
  Widget build(BuildContext context) {
    return RadioButtonGroup(
      orientation: GroupedButtonsOrientation.VERTICAL,
      margin: const EdgeInsets.only(left: 12.0),
      onSelected: (String selected) => setState((){
        widget.picked = selected;
      }),
      labels: widget.labels,
      picked: widget.picked,
      activeColor: Color(0xffFFD243),
      onChange: (String label, int index) {
          print("label: $label index: $index");
          widget.function(label,index);
      },
    );
  }
}

在这里我将这个类称为CheckoutClass

TimeRadioButtonsClass(picked: picked , labels: when),

注意:我在CheckoutClass 中使用了setState,通过在TimeRadioButtonsClass 中将其作为参数访问,它只更改了一次容器。

我不知道setState不起作用的原因!

编辑:我将函数作为参数传递给TimeRadioButtonsClass(我在上面编辑TimeRadioButtonsClass代码),这是调用代码:

TimeRadioButtonsClass(picked: picked , labels: when , function: (String label , int index){
              setState(() {
                   if(index == 1){
                       indexRadio = 1;
                       print("indexRadio 1 : "+indexRadio.toString());
                   }
                   else{
                       indexRadio = 0;
                       print("indexRadio 2 : "+indexRadio.toString());
                   }
              });
       },),
       indexRadio == 1 ? Container(
           height: 50.0,
           color: Colors.blue,
         ):
        Container(
            height: 50.0,
            color: Colors.red,
         ),

【问题讨论】:

  • 你的容器在哪里,你能不能也显示代码,你想改变颜色?

标签: flutter dart setstate


【解决方案1】:

如果您的containerclass 之外,那么您可以在radiobutton 的选定button 上创建一个callback

widget.onTap(selected);

onTap 方法添加这行代码,以在调用它的类中创建一个callback

class TimeRadioButtonsClass extends StatefulWidget {
  @override
  _TimeRadioButtonsClassState createState() => _TimeRadioButtonsClassState();
  List<String> labels;
  String picked;
  Function onTap;
  TimeRadioButtonsClass({this.picked, this.labels, this.onTap});
}

class _TimeRadioButtonsClassState extends State<TimeRadioButtonsClass> {
  @override
  Widget build(BuildContext context) {
    return RadioButtonGroup(
      // orientation: GroupedButtonsOrientation.VERTICAL,
      margin: const EdgeInsets.only(left: 12.0),
      onSelected: (String selected) {
        setState(() {
          widget.picked = selected;
        });
        widget.onTap(selected);  //This will make a callback to your class and send the selected value in the onTap method of that class.
      },
      labels: widget.labels,
      picked: widget.picked,
      activeColor: Color(0xffFFD243),
      onChange: (String label, int index) =>
          print("label: $label index: $index"),
    );
  }
}

现在要从class 中获取onTap 值,请调用您的widget,如下所示

注意:这里的值 1 和 2 是您选择的单选按钮 string 1 是 ASAP 而 2 是 选择计时器

TimeRadioButtonsClass(
        picked: "picked",
        onTap: (value) {
          if (value == 1) {
            //do change for one
            containerColor = Colors.blue;

              setState(() {

              });
          } else if (value == 2) {
            //do change for two
            containerColor = Colors.red;

              setState(() {

              });
          }
        },
      )

将容器的颜色定义为默认值,以便更改类的 onTap 方法的颜色

  Color containerColor = Colors.red;

现在显示container如下

Container(
      height: 100,
      width: 100,
      color: containerColor,
    );

已编辑 2:-(此代码更改容器的颜色,并且现在单选按钮也每次都更改)

  String picked = "ASAP"; // Add this line at the top

将 Calling TimeRadioButtonsClass ClassCode 替换为此

    TimeRadioButtonsClass(
      picked: picked,
      labels: [
        "ASAP",
        "Select Timer",
      ],
      onTap: (
        int index,
      ) {
        indexRadio = index;
           if (index == 0) {
              picked = "ASAP";
            } else {
              picked = "Select Timer";
            }
        setState(() {});
      },
    ),
    indexRadio == 0
        ? Container(
            height: 50.0,
            color: Colors.blue,
          )
        : Container(
            height: 50.0,
            color: Colors.red,
          ),

并且还将 TimeRadioButtonClass 本身替换为 code

import 'package:flutter/material.dart'; 导入'package:grouped_buttons/grouped_buttons.dart';

class TimeRadioButtonsClass extends StatefulWidget {
  @override
  _TimeRadioButtonsClassState createState() => _TimeRadioButtonsClassState();
  List<String> labels;
  String picked;
  Function(int) onTap;
  TimeRadioButtonsClass({this.picked, this.labels, this.onTap});
}

class _TimeRadioButtonsClassState extends State<TimeRadioButtonsClass> {
  @override
  Widget build(BuildContext context) {
    return RadioButtonGroup(
        orientation: GroupedButtonsOrientation.VERTICAL,
        margin: const EdgeInsets.only(left: 12.0),
        labels: widget.labels,
        picked: widget.picked,
        activeColor: Colors.red,
        onChange: (String label, int index) {
          print(index);
          widget.onTap(index);
        });
  }
}

我所做的是删除了onSelected(也许以后可能会用到),并将 onTap function 改为pass int

【讨论】:

  • 从逻辑上讲,这个解决方案应该可以工作,但它会改变一次颜色,并且单选按钮不会移动到第二个按钮
  • @LailaMattar 请出示相关文件的完整代码,我会尝试调查并找到问题。
  • @LailaMattar 我正在尝试复制我的问题,你能告诉我你正在使用哪个 RadioGroupButton 包吗?
  • 我导入了这个包(grouped_buttons: ^1.0.4)
  • @LailaMattar 我能够更改容器的颜色,请检查我的最新代码,但我没有使用选择的变量,你能告诉我它的用途和它包含的值吗在开始。
【解决方案2】:

setState() 仅适用于特定的 State 类。

每当您更改 State 对象的内部状态时,请在您传递给 setState 的函数中进行更改

调用 setState 会通知框架此对象的内部状态已发生更改,可能会影响此子树中的用户界面,这会导致框架为此 State 对象安排构建。

setState() docs

这里,setState() 正在运行,但您的容器不在其范围内。

选择日期后,_TimeRadioButtonsClassState.build 将被调用,这不会影响您的容器,因为您的容器不在该小部件(或类,如果您愿意)中

如果可能,请尝试在您将调用 setState 的小部件内移动容器或尝试使用 a different state management approach

更复杂的方法是使用 GlobalKey 并将其作为参数传递给您的 StatefulWidget 并调用 setState 或使用 context.findAncestorStateOfType

【讨论】:

    【解决方案3】:

    试试这个:

    class _TimeRadioButtonsClassState extends State<TimeRadioButtonsClass> {
          String _picked;
          initState() {
           _picked = widget.picked;
           super.initState();
          }
          @override
          Widget build(BuildContext context) {
            return RadioButtonGroup(
              orientation: GroupedButtonsOrientation.VERTICAL,
              margin: const EdgeInsets.only(left: 12.0),
              onSelected: (String selected) => setState((){
                _picked = selected;
              }),
              labels: widget.labels,
              picked: _picked,
              activeColor: Color(0xffFFD243),
              onChange: (String label, int index) => print("label: $label index: $index"),
            );
          }
        }
    

    【讨论】:

      猜你喜欢
      • 2018-05-11
      • 2012-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-17
      • 2019-02-04
      相关资源
      最近更新 更多