I'm trying to change the color of my container on ontap event (inside gridview builder). It was working fine when I was using setState. But as I changed it to Getx, the print statement is working fine but the color of container is not changing. here is the code.
Here is the screens where I'm trying to display my gridview
class _SelectRoleScreenState extends State<SelectRoleScreen> {
MyController myController = Get.put(MyController());
var colorFromController;
int selctedValue;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: double.infinity,
height: 250.0,
child: upperPortion(),
),
Padding(
padding: EdgeInsets.all(8.0),
child: GridView.builder(
shrinkWrap: true,
primary: false,
itemCount: myController.roles.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 16,
crossAxisSpacing: 20,
),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
colorFromController =
myController.selectedColor.value;
colorFromController = index;
print(colorFromController);
// setState(() {
// _selectedColor = index;
// });
},
child: Padding(
padding: EdgeInsets.only(bottom: 8),
child: Obx(
() => Container(
width: sizeWidth(context) / 2.5,
decoration: BoxDecoration(
color: colorFromController == index
? primaryColor
: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey[200],
blurRadius: 2,
offset: Offset(0, 5),
),
],
),
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
SizedBox(
height: 5,
),
Image.asset(
myController.roles[index]['roleImage'],
color: colorFromController == index
? Colors.white
: primaryColor,
height: 50,
width: 50,
),
Text(
myController.roles[index]['roleName']
.toUpperCase(),
style: TextStyle(
fontSize: 16,
color: colorFromController == index
? Colors.white
: Colors.black,
),
),
Container(
width: 150,
child: Text(
myController.roles[index]
['roleDescription'],
style: TextStyle(
color: colorFromController == index
? Colors.white
: Colors.black,
fontSize: 12,
),
textAlign: TextAlign.center,
),
),
SizedBox(
height: 5,
),
],
),
),
),
),
);
}),
),
SizedBox(
height: 15,
),
CustomButton(
buttonText: "Get Started",
buttonColor: primaryColor,
textColor: Colors.white,
onPress: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CreateAccountPartnerScreen()),
);
},
),
SizedBox(
height: 15,
),
],
),
),
),
);
}
}
Here is the controller class
import 'package:get/get.dart';
class MyController extends GetxController {
final RxInt selectHomeScreen = 0.obs;
RxInt selectedColor = 1.obs;
List<Map> roles = [
{
'roleImage': 'assets/icons/select_partner/Pet Shop.png',
'roleName': "pet shop",
'roleDescription': 'Sell Your Products to Pet Lovers',
'homeIndex': 0,
},
{
'roleImage': 'assets/icons/select_partner/Sitter.png',
'roleName': "Sitter",
'roleDescription': 'Provide Pet Sitter Services',
'homeIndex': 1,
},
{
'roleImage': 'assets/icons/select_partner/Vets Clinic.png',
'roleName': "Vets Clinic",
'roleDescription': 'Do Appointments with Pet Lovers',
'homeIndex': 2,
},
{
'roleImage': 'assets/icons/select_partner/Groomer.png',
'roleName': "Groomer",
'roleDescription': 'Do Grooming Appointments with Pet Lovers',
'homeIndex': 3,
},
{
'roleImage': 'assets/icons/select_partner/Aglity Trainer.png',
'roleName': "Aglity Trainer",
'roleDescription': 'Train Pets Different Skills',
'homeIndex': 4,
},
{
'roleImage': 'assets/icons/select_partner/Govertment.png',
'roleName': "Govertment",
'roleDescription': 'Renew Pets Licences and Apply For Pets Passport',
'homeIndex': 5,
},
].obs;
}
Any help would be appreciated
The reason it's not rebuilding is because your onTap
isn't changing any variable from the GetX class. This is intended behavior to minimize unnecessary rebuilds.
All you need to do is change the actual GetX variable in the onTap
of your gesture detector.
onTap: () {
myController.selectedColor.value = index;
print(colorFromController);
},
Then within your BoxDecoration
make the logic depend on the GetX variable and not a local one.
Obx(
() => Container(
width: sizeWidth(context) / 2.5,
decoration: BoxDecoration(
color: myController.selectedColor.value == index
? primaryColor
: Colors.white,
.....
Essentially you don't need the local colorFromController
variable. Just replace it with myController.selectedColor.value
in the whole page.
I also suggest just putting the primaryColor
variable in the GetX class as well and make the whole page stateless since you're not doing anything that requires a stateful widget.