简体   繁体   English

Flutter:“ onPressed”作用于列表视图中的所有“ IconButton”

[英]Flutter: `onPressed` acts on all `IconButton`s in a list view

I want to change color of every icon after pressing. 我想在按下后更改每个图标的颜色。 But all of icons in a ExpandableContainer change after pressing one of them. 但是,在按下其中一个图标后, ExpandableContainer所有图标都会更改。

class _ExpandableListViewState extends State<ExpandableListView> {
  bool expandFlag = false;
  Color _iconColor = Colors.white;

  @override
  Widget build(BuildContext context) {
    return new Container(
      margin: new EdgeInsets.symmetric(vertical: 1.0),
      child: new Column(
        children: <Widget>[
          new Container(
               .
               .
               .
               ),
          new ExpandableContainer(              
              expanded: expandFlag,
              expandedHeight: ...              
              child: new ListView.builder(
                itemBuilder: (BuildContext context, int index) {
                  return new Container(
                    decoration:
                        new BoxDecoration(border: new Border.all(width: 1.0, color: Colors.grey), color: Colors.black),                        
                     child: new ListTile(
                       title: ...

                       leading: new IconButton(
                        icon: Icon(Icons.star, color: _iconColor),
                        onPressed: () {
                          setState(() {                           
                           _iconColor = _iconColor == Colors.white ? Colors.yellow : Colors.white;                           
                          });
                        },
                      ),                                            
                      subtitle: ...                                                 
                  ), 
                  );
                },
                itemCount: ...,
              ))
        ],
      ),
    );
  }
}

class ExpandableContainer extends StatelessWidget {
  final bool expanded;
  final double expandedHeight;
  final Widget child;

  ExpandableContainer({
    @required this.child,
    this.expandedHeight,
    this.expanded = true,
  });

  @override
  Widget build(BuildContext context) {
.
.
.
}

Whole code: 整个代码:

import 'package:flutter/material.dart';
import 'data.dart';

void main() {
  runApp(new MaterialApp(home: new Home()));
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      backgroundColor: Colors.grey,
      appBar: new AppBar(
        title: new Text("Expandable List", style: TextStyle(color: Colors.black)),
        backgroundColor: Colors.lightGreen,
      ),
      body: new ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return new ExpandableListView(title: broadcast[index].title, ind: index);
        },
        itemCount: broadcast.length,
      ),
    );
  }
}

class ExpandableListView extends StatefulWidget {
  final String title;
  final int ind;

  const ExpandableListView({this.title, this.ind});

  @override
  _ExpandableListViewState createState() => new _ExpandableListViewState();
}

class _ExpandableListViewState extends State<ExpandableListView> {
  bool expandFlag = false;
  Color _iconColor = Colors.white;

  @override
  Widget build(BuildContext context) {
    return new Container(
      margin: new EdgeInsets.symmetric(vertical: 1.0),
      child: new Column(
        children: <Widget>[
          new Container(
            color: Colors.blue[300],
            padding: new EdgeInsets.symmetric(horizontal: 5.0),
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                new IconButton(
                    icon: new Container(
                      height: 50.0,
                      width: 50.0,
                      decoration: new BoxDecoration(
                        color: Colors.deepOrange,
                        shape: BoxShape.circle,
                      ),
                      child: new Center(
                        child: new Icon(
                          expandFlag ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down,
                          color: Colors.white,
                          size: 30.0,
                        ),
                      ),
                    ),
                    onPressed: () {
                      setState(() {
                        expandFlag = !expandFlag;
                      });
                    }),
                new Text(
                  widget.title,
                  style: new TextStyle(fontWeight: FontWeight.bold,fontSize: 20.0, color: Colors.black87),
                )
              ],
            ),
          ),
          new ExpandableContainer(              
              expanded: expandFlag,
              expandedHeight: 90.0 * (broadcast[widget.ind].contents.length < 4 ? broadcast[widget.ind].contents.length : 4), // + (0.0 ?: 29.0),              
              child: new ListView.builder(
                itemBuilder: (BuildContext context, int index) {
                  return new Container(
                    decoration:
                        new BoxDecoration(border: new Border.all(width: 1.0, color: Colors.grey), color: Colors.black),                        
                     child: new ListTile(
                      title: new Text(
                        broadcast[widget.ind].contents[index],
                        style: new TextStyle(fontWeight: FontWeight.bold, color: Colors.lightGreen),
                        textAlign: TextAlign.right,
                      ),
                       leading: new IconButton(
                        icon: Icon(Icons.star, color: _iconColor),
                        onPressed: () {
                          setState(() {                           
                           _iconColor = _iconColor == Colors.white ? Colors.yellow : Colors.white;                           
                          });
                        },
                      ),                                            
                      subtitle: new Text ('${broadcast[widget.ind].team[index]}\n${broadcast[widget.ind].time[index]}          ${broadcast[widget.ind].channel[index]}',
                      textAlign: TextAlign.right, style:TextStyle(color: Colors.white)),
                      isThreeLine: true,                       
                  ), 
                  );
                },
                itemCount: broadcast[widget.ind].contents.length,
              ))
        ],
      ),
    );
  }
}

class ExpandableContainer extends StatelessWidget {
  final bool expanded;
  final double expandedHeight;
  final Widget child;
  //final Color iconColor;

  ExpandableContainer({
    @required this.child,
    this.expandedHeight,
    this.expanded = true,
    //this.iconColor,
  });

  @override
  Widget build(BuildContext context) {
    double screenWidth = MediaQuery.of(context).size.width;
    return new AnimatedContainer(
      duration: new Duration(milliseconds: 100),
      curve: Curves.easeInOut,
      width: screenWidth,
      height: expanded ? expandedHeight : 0.0,
      child: new Container(
        child: child,
        decoration: new BoxDecoration(border: new Border.all(width: 1.0, color: Colors.blue)),
      ),
    );
  }
}

You need to make the list item a StatefulWidget in which you have the state _iconColor 您需要将列表项设置为StatefulWidget,其中状态为_iconColor

Stateful List Tile 有状态列表图块

class StatefulListTile extends StatefulWidget {
  const StatefulListTile({this.subtitle, this.title});
  final String subtitle, title;
  @override
  _StatefulListTileState createState() => _StatefulListTileState();
}

class _StatefulListTileState extends State<StatefulListTile> {
  Color _iconColor = Colors.white;
  @override
  Widget build(BuildContext context) {
    return new Container(
      decoration: new BoxDecoration(
          border: new Border.all(width: 1.0, color: Colors.grey),
          color: Colors.black),
      child: new ListTile(
        title: new Text(
          widget?.title ?? "",
          style: new TextStyle(
              fontWeight: FontWeight.bold, color: Colors.lightGreen),
          textAlign: TextAlign.right,
        ),
        leading: new IconButton(
          icon: Icon(Icons.star, color: _iconColor),
          onPressed: () {
            setState(() {
              _iconColor =
                  _iconColor == Colors.white ? Colors.yellow : Colors.white;
            });
          },
        ),
        subtitle: new Text(widget?.subtitle ?? "",
            textAlign: TextAlign.right, style: TextStyle(color: Colors.white)),
        isThreeLine: true,
      ),
    );
  }
}

Usage 用法


class ExpandableListView extends StatefulWidget {
  final String title;
  final int ind;

  const ExpandableListView({this.title, this.ind});

  @override
  _ExpandableListViewState createState() => new _ExpandableListViewState();
}

class _ExpandableListViewState extends State<ExpandableListView> {
  bool expandFlag = false;
  Color _iconColor = Colors.white;

  @override
  Widget build(BuildContext context) {
    return new Container(
      margin: new EdgeInsets.symmetric(vertical: 1.0),
      child: new Column(
        children: <Widget>[
          new Container(
            color: Colors.blue[300],
            padding: new EdgeInsets.symmetric(horizontal: 5.0),
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                new IconButton(
                    icon: new Container(
                      height: 50.0,
                      width: 50.0,
                      decoration: new BoxDecoration(
                        color: Colors.deepOrange,
                        shape: BoxShape.circle,
                      ),
                      child: new Center(
                        child: new Icon(
                          expandFlag
                              ? Icons.keyboard_arrow_up
                              : Icons.keyboard_arrow_down,
                          color: Colors.white,
                          size: 30.0,
                        ),
                      ),
                    ),
                    onPressed: () {
                      setState(() {
                        expandFlag = !expandFlag;
                      });
                    }),
                new Text(
                  widget.title,
                  style: new TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 20.0,
                      color: Colors.black87),
                )
              ],
            ),
          ),
          new ExpandableContainer(
              expanded: expandFlag,
              expandedHeight: 90.0 *
                  (broadcast[widget.ind].contents.length < 4
                      ? broadcast[widget.ind].contents.length
                      : 4), // + (0.0 ?: 29.0),
              child: new ListView.builder(
                itemBuilder: (BuildContext context, int index) {
                  return StatefulListTile(
                    title: broadcast[widget.ind].contents[index],
                    subtitle:
                        '${broadcast[widget.ind].team[index]}\n${broadcast[widget.ind].time[index]}          ${broadcast[widget.ind].channel[index]}',
                  );
                },
                itemCount: broadcast[widget.ind].contents.length,
              ))
        ],
      ),
    );
  }
}

You should make the color property distinct for each element in the ListView , what you are doing is that the color is global and shared among all the icons in the ListView , for this reason all icons are changing their color when one icon is pressed. 您应该使ListView每个元素的color属性都不同,您正在做的是颜色是全局的,并且在ListView中的所有图标之间共享,因此,当按下一个图标时,所有图标都会更改其颜色。

class Broadcast {
  final String title;
  List<String> contents;
  List<String> team = [];
  List<String> time = [];
  List<String> channel = [];
  Color iconColor = Colors.white; //initialize at the beginning

  Broadcast(this.title, this.contents, this.team, this.time, this.channel); //, this.icon);
}

edit your ExpandableListView 编辑您的ExpandableListView

class ExpandableListView extends StatefulWidget {

  final int ind;
  final Broadcast broadcast;

  const ExpandableListView({this.broadcast,this.ind});

  @override
  _ExpandableListViewState createState() => new _ExpandableListViewState();
}

edit your Home class 编辑您的Home

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      backgroundColor: Colors.grey,
      appBar: new AppBar(
        title: new Text("Expandable List", style: TextStyle(color: Colors.black)),
        backgroundColor: Colors.lightGreen,
      ),
      body: new ListView.builder(
        itemBuilder: (BuildContext context, int index) {
          return new ExpandableListView(title: broadcast[index], ind: index);
        },
        itemCount: broadcast.length,
      ),
    );

  }
}

edit your _ExpandableListViewState 编辑您的_ExpandableListViewState

class _ExpandableListViewState extends State<ExpandableListView> {
  bool expandFlag = false;

  @override
  Widget build(BuildContext context) {
    return new Container(
      margin: new EdgeInsets.symmetric(vertical: 1.0),
      child: new Column(
        children: <Widget>[
          new Container(
            color: Colors.blue[300],
            padding: new EdgeInsets.symmetric(horizontal: 5.0),
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                new IconButton(
                    icon: new Container(
                      height: 50.0,
                      width: 50.0,
                      decoration: new BoxDecoration(
                        color: Colors.deepOrange,
                        shape: BoxShape.circle,
                      ),
                      child: new Center(
                        child: new Icon(
                          expandFlag ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down,
                          color: Colors.white,
                          size: 30.0,
                        ),
                      ),
                    ),
                    onPressed: () {
                      setState(() {
                        expandFlag = !expandFlag;
                      });
                    }),
                new Text(
                  widget.broadcast.title,
                  style: new TextStyle(fontWeight: FontWeight.bold,fontSize: 20.0, color: Colors.black87),
                )
              ],
            ),
          ),
          new ExpandableContainer(              
              expanded: expandFlag,
              expandedHeight: 90.0 * (broadcast[widget.ind].contents.length < 4 ? broadcast[widget.ind].contents.length : 4), // + (0.0 ?: 29.0),              
              child: new ListView.builder(
                itemBuilder: (BuildContext context, int index) {
                  return new Container(
                    decoration:
                        new BoxDecoration(border: new Border.all(width: 1.0, color: Colors.grey), color: Colors.black),                        
                     child: new ListTile(
                      title: new Text(
                        broadcast[widget.ind].contents[index],
                        style: new TextStyle(fontWeight: FontWeight.bold, color: Colors.lightGreen),
                        textAlign: TextAlign.right,
                      ),
                       leading: new IconButton(
                        icon: Icon(Icons.star, color:  widget.broadcast.iconColor),
                        onPressed: () {
                          setState(() {
                           widget.broadcast.iconColor = widget.broadcast.iconColor == Colors.white ? Colors.yellow : Colors.white;                                          

                          });
                        },
                      ),                                            
                      subtitle: new Text ('${broadcast[widget.ind].team[index]}\n${broadcast[widget.ind].time[index]}          ${broadcast[widget.ind].channel[index]}',
                      textAlign: TextAlign.right, style:TextStyle(color: Colors.white)),
                      isThreeLine: true,                       
                  ), 
                  );
                },
                itemCount: broadcast[widget.ind].contents.length,
              ))
        ],
      ),
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM