ListView 中的问题切换值颤动

Posted

技术标签:

【中文标题】ListView 中的问题切换值颤动【英文标题】:Problem switch values in ListView flutter 【发布时间】:2020-01-19 11:52:01 【问题描述】:

我在 ListView 中为每个元素创建了一个 Switch 小部件。当我点击开关时,所有元素的值都会改变。 我检查了颤振文档,飞镖文档......我想,我没有在 onChanged 方法中恢复元素位置。

但是怎么做呢?

当我单击时,我的值 isSwitched 发生了变化。 多亏了:snapshot.data[index].name

主题画面:

class _ThemePage extends State<ThemePage> 
  bool isSwitched = false;
  @override
  Widget build(BuildContext context) 
    return new Scaffold(
      appBar: new AppBar(
        title: Text("Blackbox"),
        leading: Image.asset(
          'assets/img/logo_ineat.png',
          fit: BoxFit.contain,
          height: 32,
        ),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            new Container(
                margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
                child: new Text('Sélection du profil',
                    style: new TextStyle(
                        fontSize: 24, fontWeight: FontWeight.bold)),
                alignment: Alignment.topCenter),
            new Flexible(
              child: new Container(
                child: new FutureBuilder<List<t.Theme>>(
                    future: t.Theme().getThemes(),
                    builder: (BuildContext context, AsyncSnapshot snapshot) 
                      if (snapshot.hasData) 
                        if (snapshot.data != null) 
                          return new Column(
                            children: <Widget>[
                              new Expanded(
                                child: new ListView.builder(
                                  itemCount: snapshot.data.length,
                                  itemBuilder: (BuildContext context, index) 
                                    return ListTile(
                                      title:
                                          new Text(snapshot.data[index].name),
                                          trailing: new Switch(
                                            value: isSwitched,
                                            activeColor: Colors.pink,
                                            activeTrackColor: Colors.pinkAccent,
                                            onChanged: (value)
                                              setState(() 
                                               isSwitched = value; 
                                               if(value==true) 
                                                 print(snapshot.data[index].name);
                                               
                                              );
                                            ,
                                          ),
                                    );
                                  ,
                                ),
                              ),
                            ],
                          );
                        
                       else 
                        new Text("Loading...");
                        return new CircularProgressIndicator();
                      
                    ),
              ),
            ),
            new Container(
              margin: EdgeInsets.only(right: 10.0),
              child: new RaisedButton.icon(
                /*onPressed: () 
                  Navigator.pushReplacement(context,
                      MaterialPageRoute(builder: (context) => Technologies()));
                ,*/
                label: Text('Suivant'),
                icon: Icon(Icons.navigate_next),
              ),
              alignment: Alignment.bottomRight,
            ),
          ],
        ),
      ),
    );
  


【问题讨论】:

【参考方案1】:

您正在使用单个属性 isSwitched 控制切换值

你可以

创建另一个有状态小部件,将您的开关逻辑放在那里(如果您想读取值,请使用回调)(更简洁) 创建布尔列表而不是单个属性

第一个解决方案的代码:


class YourListViewItem extends StatefulWidget 

  final String title;

  const YourListViewItem(Key key, this.title) : super(key: key);

  @override
  _YourListViewItemState createState() => _YourListViewItemState();


class _YourListViewItemState extends State<YourListViewItem> 

  bool isSwitched = false;

  @override
  Widget build(BuildContext context) 
    return ListTile(
      title:
      new Text(widget.title),
      trailing: new Switch(
        value: isSwitched,
        activeColor: Colors.pink,
        activeTrackColor: Colors.pinkAccent,
        onChanged: (value)
          setState(() 
            isSwitched = value;
          );
        ,
      ),
    );
  



class _ThemePage extends State<ThemePage> 
  bool isSwitched = false;
  @override
  Widget build(BuildContext context) 
    return new Scaffold(
      appBar: new AppBar(
        title: Text("Blackbox"),
        leading: Image.asset(
          'assets/img/logo_ineat.png',
          fit: BoxFit.contain,
          height: 32,
        ),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            new Container(
                margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
                child: new Text('Sélection du profil',
                    style: new TextStyle(
                        fontSize: 24, fontWeight: FontWeight.bold)),
                alignment: Alignment.topCenter),
            new Flexible(
              child: new Container(
                child: new FutureBuilder<List<t.Theme>>(
                    future: t.Theme().getThemes(),
                    builder: (BuildContext context, AsyncSnapshot snapshot) 
                      if (snapshot.hasData) 
                        if (snapshot.data != null) 
                          return new Column(
                            children: <Widget>[
                              new Expanded(
                                child: new ListView.builder(
                                  itemCount: snapshot.data.length,
                                  itemBuilder: (BuildContext context, index) 
                                    return YourListViewItem(title: snapshot.data[index].name);
                                  ,
                                ),
                              ),
                            ],
                          );
                        
                       else 
                        new Text("Loading...");
                        return new CircularProgressIndicator();
                      
                    ),
              ),
            ),
            new Container(
              margin: EdgeInsets.only(right: 10.0),
              child: new RaisedButton.icon(
                /*onPressed: () 
                  Navigator.pushReplacement(context,
                      MaterialPageRoute(builder: (context) => Technologies()));
                ,*/
                label: Text('Suivant'),
                icon: Icon(Icons.navigate_next),
              ),
              alignment: Alignment.bottomRight,
            ),
          ],
        ),
      ),
    );
  



【讨论】:

以上是关于ListView 中的问题切换值颤动的主要内容,如果未能解决你的问题,请参考以下文章

按特定值对 ListView 或 ListView.ItemTemplate 进行排序

滚动行为中的文本和 ListView 颤动

一些滚动后颤动ListView KeepAlive

如何构建包含 ListView.Builder 的自定义行,以在颤动中构建 ElevatedButton?

listview点击item中的button改变item中的其它的控件的值

如何在颤动/飞镖的 ListView 项目中更改背景颜色