在网格视图中更改单个小部件的属性

时间:2019-12-11 17:25:08

标签: flutter dart

我有一个网格视图,可以映射来自数据库的数据,并且其中的每个Container都有一个扁平按钮,上面写着“ apply”,我希望当用户单击按钮时按钮的颜色可以改变,而不必是他们在轻按容器时按下的按钮,它也会更改按钮的颜色,甚至更好See the image here to understand more

import 'package:flutter/material.dart';
class FoundCourses extends StatefulWidget {
  @override
  _FoundCoursesState createState() => _FoundCoursesState();
}
class _FoundCoursesState extends State<FoundCourses> {
 // bool _applied = false;
  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate:
          new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
      scrollDirection: Axis.vertical,
      itemCount: 5,
      itemBuilder: (context, index) {
        return Padding(
          padding: const EdgeInsets.only(bottom: 10.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              GestureDetector(
                onTap: () {
                  // What do i do here?
                },
                child: Container(
                  height: 350,
                  width: 170,
                  decoration: BoxDecoration(
                    // border: Border.all(color: Color(0xff940D5A)),
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(17.0),
                    boxShadow: <BoxShadow>[
                      BoxShadow(
                        color: Colors.grey,
                        offset: Offset(1.0, 15.0),
                        blurRadius: 20.0,
                      ),
                    ],
                  ),
                  child: Column(
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.only(
                            top: 20.0, right: 10.0, left: 30.0, bottom: 3.0),
                        child: Text(
                          "$index",
                          style: TextStyle(
                              color: Color(0xff00315C),
                              fontSize: 14.0,
                              fontFamily: 'Poppins',
                              fontWeight: FontWeight.w600),
                          // textAlign: TextAlign.center,
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.symmetric(vertical: 8.0),
                        child: Text(
                          "Instructor \nMahfuz A.",
                          style: TextStyle(
                            color: Color(0xff00315C),
                            fontSize: 12.0,
                            fontFamily: 'Poppins',
                            fontWeight: FontWeight.w500,
                          ),
                        ),
                      ),
                      Expanded(
                        child: FlatButton(
                          onPressed: () {//or what do i here},
                          color: Color(0xff940D5A),
                          padding: EdgeInsets.symmetric(horizontal: 65.0),
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.only(
                                  bottomRight: Radius.circular(17),
                                  bottomLeft: Radius.circular(17))),
                          child: Text(
                            "Apply",
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 14.0,
                                fontFamily: 'Poppins',
                                fontWeight: FontWeight.w600),
                          ),
                        ),
                      )
                    ],
                  ),
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}

2 个答案:

答案 0 :(得分:1)

您有几个选择,但是我要做的是:使每个 tile 状态化(而不是整个网格),并跟踪每个图块是否被应用。

您缺少的主要内容是使用setState()来改变水龙头的状态。构建小部件以更改颜色/按钮内容时,您还需要检查状态。

1)为Gridview中的每个项目创建一个新的StatefulWidget:

class FoundCourseTile extends StatefulWidget {
  final int number;

  const FoundCourseTile(this.number);

  @override
  _FoundCourseTileState createState() => _FoundCourseTileState();
}

class _FoundCourseTileState extends State<FoundCourseTile> {
  bool applied = false;

  Widget build(BuildContext context) {
    return Padding(
          padding: const EdgeInsets.only(bottom: 10.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              GestureDetector(
                // toggle state on tap
                onTap: () {
                  setState(() => applied = !applied); 
                },
                child: Container(
                  height: 350,
                  width: 170,
                  decoration: BoxDecoration(
                    // border: Border.all(color: Color(0xff940D5A)),
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(17.0),
                    boxShadow: <BoxShadow>[
                      BoxShadow(
                        color: Colors.grey,
                        offset: Offset(1.0, 15.0),
                        blurRadius: 20.0,
                      ),
                    ],
                  ),
                  child: Column(
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.only(
                            top: 20.0, right: 10.0, left: 30.0, bottom: 3.0),
                        child: Text(
                          "${widget.number}",
                          style: TextStyle(
                              color: Color(0xff00315C),
                              fontSize: 14.0,
                              fontFamily: 'Poppins',
                              fontWeight: FontWeight.w600),
                          // textAlign: TextAlign.center,
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.symmetric(vertical: 8.0),
                        child: Text(
                          "Instructor \nMahfuz A.",
                          style: TextStyle(
                            color: Color(0xff00315C),
                            fontSize: 12.0,
                            fontFamily: 'Poppins',
                            fontWeight: FontWeight.w500,
                          ),
                        ),
                      ),
                      Expanded(
                        child: FlatButton(
                          // toggle state on tap
                          onPressed: () {setState(() => applied = !applied);},
                          // set color based on state
                          color: applied ? Colors.green : Colors.red,
                          padding: EdgeInsets.symmetric(horizontal: 65.0),
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.only(
                                  bottomRight: Radius.circular(17),
                                  bottomLeft: Radius.circular(17))),
                          child: applied ? /* icon code goes here */ : Text(
                            "Apply",
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 14.0,
                                fontFamily: 'Poppins',
                                fontWeight: FontWeight.w600),
                          ),
                        ),
                      )
                    ],
                  ),
                ),
              ),
            ],
          ),
        );
  }
}

然后将GridView简化为无状态:

class FoundCourses extends StatelessWidget {
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate:
          SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
      scrollDirection: Axis.vertical,
      itemCount: 5,
      itemBuilder: (_, index) => FoundCourseTile(index),
    );
  }
}

答案 1 :(得分:1)

@Eimen,一种方法是在现有代码中生成选定索引的列表,并仅将颜色应用于选定项的索引。这是实现此方法的方法,

class FoundCourses extends StatefulWidget {
  @override
  _FoundCoursesState createState() => _FoundCoursesState();
}

class _FoundCoursesState extends State<FoundCourses> {
  // bool _applied = false;
  List<int> selectedIndexList = new List<int>();
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home:GridView.builder(
      gridDelegate:
          new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
      scrollDirection: Axis.vertical,
      itemCount: 5,
      itemBuilder: (context, index) {
        return Padding(
          padding: const EdgeInsets.only(bottom: 10.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              GestureDetector(
                onTap: () {
                  // What do i do here?
                  if (!selectedIndexList.contains(index)) {
                    selectedIndexList.add(index);
                  } else {
                    selectedIndexList.remove(index);
                  }
                  setState(() {

                  });
                },
                child: Container(
                  height: 350,
                  width: 170,
                  decoration: BoxDecoration(
                    // border: Border.all(color: Color(0xff940D5A)),
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(17.0),
                    boxShadow: <BoxShadow>[
                      BoxShadow(
                        color: Colors.grey,
                        offset: Offset(1.0, 15.0),
                        blurRadius: 20.0,
                      ),
                    ],
                  ),
                  child: Column(
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.only(
                            top: 20.0, right: 10.0, left: 30.0, bottom: 3.0),
                        child: Text(
                          "$index",
                          style: TextStyle(
                              color: Color(0xff00315C),
                              fontSize: 14.0,
                              fontFamily: 'Poppins',
                              fontWeight: FontWeight.w600),
                          // textAlign: TextAlign.center,
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.symmetric(vertical: 8.0),
                        child: Text(
                          "Instructor \nMahfuz A.",
                          style: TextStyle(
                            color: Color(0xff00315C),
                            fontSize: 12.0,
                            fontFamily: 'Poppins',
                            fontWeight: FontWeight.w500,
                          ),
                        ),
                      ),
                      Expanded(
                        child: FlatButton(
                          onPressed: () {
                            if (!selectedIndexList.contains(index)) {
                              selectedIndexList.add(index);
                            } else {
                              selectedIndexList.remove(index);
                            }
                            setState(() {

                            });
                          }, //or what do i here},
                          color: selectedIndexList.contains(index) ? Colors.green : Color(0xff940D5A),
                          padding: EdgeInsets.symmetric(horizontal: 65.0),
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.only(
                                  bottomRight: Radius.circular(17),
                                  bottomLeft: Radius.circular(17))),
                          child: selectedIndexList.contains(index) ? Icon(Icons.check, color: Colors.white, size: 35.0,) : Text(
                            "Apply",
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 14.0,
                                fontFamily: 'Poppins',
                                fontWeight: FontWeight.w600),
                          ),
                        ),
                      )
                    ],
                  ),
                ),
              ),
            ],
          ),
        );
      },
    )
    );
  }
}

demo

希望这会有所帮助。