我有一个网格视图,可以映射来自数据库的数据,并且其中的每个Container都有一个扁平按钮,上面写着“ apply”,我希望当用户单击按钮时按钮的颜色可以改变,而不必是他们在轻按容器时按下的按钮,它也会更改按钮的颜色,甚至更好
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),
),
),
)
],
),
),
),
],
),
);
},
);
}
}
答案 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),
),
),
)
],
),
),
),
],
),
);
},
)
);
}
}
希望这会有所帮助。