'Didn't change the color of container
I want to change the color of the Container when it is pressed and go to the new screen but when I come back the color must have changed.
class FreelancerLayout extends StatefulWidget {
const FreelancerLayout({Key? key}) : super(key: key);
@override
State<FreelancerLayout> createState() => _FreelancerLayoutState();
}
class _FreelancerLayoutState extends State<FreelancerLayout>
with AutomaticKeepAliveClientMixin<FreelancerLayout> {
@override
Widget build(BuildContext context) {
super.build(context);
return SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: GridView.builder(
itemCount: catList.length,
shrinkWrap: true,
primary: false,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 8.0,
mainAxisSpacing: 10.0),
itemBuilder: (context, index) => Center(
child: GridCategory(
category: catList[index],
press: () {
pushNewScreen(context,
screen: CategoryPage(category: catList[index]));
}),
),
),
),
GridCategory.dart
class GridCategory extends StatefulWidget {
final Category category;
final VoidCallback? press;
const GridCategory({
Key? key,
required this.category,
this.press,
// required this.selectedIcon,
// required this.unSelectedIcon,
}) : super(key: key);
@override
State<GridCategory> createState() => _GridCategoryState();
}
class _GridCategoryState extends State<GridCategory> {
final bool isSelected = false;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: widget.press,
child: Container(
width: 110,
decoration: BoxDecoration(
color: isSelected ? AppColors.fIconsAndTextColor : Colors.white,
borderRadius: BorderRadius.circular(30.0)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(child: Image.asset(widget.category.catImage!)),
Text(
widget.category.iconName!,
textAlign: TextAlign.center,
style: TextStyle(color: isSelected ? Colors.white : Colors.black),
),
const SizedBox(height: 10)
],
),
),
);
}
}
Solution 1:[1]
First, I don't see any method to change isSelected here, soo it value alway false. Second, isSelected is final make it value can't changes, remove final. Thirt, because isSelected is local props, it changes will no appear in other page, you need to passing selected from parent if you want it.
Update: In case you want highlight selected category when selected and change it when select other cate? You need create a variable call 'selectedIndex' to store the selected category index, handle changes it everytime u tap a category. Update code below
_FreelancerLayoutState
...
int? selectedIndex; // Add this
@override
Widget build(BuildContext context) {
...
itemBuilder: (context, index) => Center(
child: GestureDetector(
onPressed: () {
setState(() => selectedIndex = index);
pushNewScreen(
context,
screen: CategoryPage(category: catList[index])
);
},
child: GridCategory(
category: catList[index],
isSelected: selectedIndex == index,
),
),
),
...
}
}
GridCategory
class GridCategory extends StatefulWidget {
...
final Category category;
final bool isSelected; // add this
// final VoidCallback? press; Remove this
...
}
_GridCategoryState
...
// final bool isSelected = false; Remove this
...
@override
Widget build(BuildContext context) {
// Removed InkWell
// return InkWell(
// onTap: widget.press,
// child: ...
// );
return Container(
width: 110,
decoration: BoxDecoration(
color: widget.isSelected ? AppColors.fIconsAndTextColor : Colors.white,
borderRadius: BorderRadius.circular(30.0)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(child: Image.asset(widget.category.catImage!)),
Text(
widget.category.iconName!,
textAlign: TextAlign.center,
style: TextStyle(color: widget.isSelected ? Colors.white : Colors.black),
),
const SizedBox(height: 10)
],
),
),
}
...
Solution 2:[2]
Change the GridCategory widget to a stateful widget. Then you can update the onTap function to change the boolean and then call the callback.
onTap: (){
setState((){
isSelected = true;
});
press();
},
Solution 3:[3]
On your GridCategory widget, pass isSelected from parent.
class GridCategory extends StatelessWidget {
final Category category;
final VoidCallback? press;
final bool isSelected;
const GridCategory({
Key? key,
required this.isSelected,
required this.category,
this.press,
}) : super(key: key);
......
To keep track of selected index you need a list, I am using List<int> here,
class _FreelancerLayoutState extends State<FreelancerLayout>
with AutomaticKeepAliveClientMixin<FreelancerLayout> {
List<int> selectedIndex = [];
....
itemBuilder: (context, index) => Center(
child: GridCategory(
isSelected: selectedIndex.contains(index),
press: () {
if (selectedIndex.contains(index)) {
selectedIndex.remove(
index); // remove selected index if already exist
} else {
selectedIndex.add(index);
}
//... perform others
}),
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Advait |
| Solution 3 | Yeasin Sheikh |
