Home > Net >  ChangeNotifier changing but widget not updating with gestureDetector
ChangeNotifier changing but widget not updating with gestureDetector

Time:10-12

I have this simple changeNotifierProvider

here it is

import 'package:flutter/material.dart';

class CreatePetProvider extends ChangeNotifier {
  String? _gender = 'Male';
  get gender => _gender;


  set changeGender(String gender){
    _gender = gender;
    // print(this.gender);
    notifyListeners();
  }
}

here is in main.dart

    return MultiProvider(
      providers: [
        ChangeNotifierProvider<CreatePetProvider>(
          create: (_) => CreatePetProvider(),
        )
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: AppTheme.lightTheme,
        home: const LoginScreen(),
        routes: routes,
      ),
    );
  }
}

Here's my widget which is not being updated

GestureDetector(onTap: () => _genderProvider.changeGender = 'Male', child: GenderButton(title: 'Male', selected: _genderProvider.gender == 'Male')),
GestureDetector(onTap: () => _genderProvider.changeGender = 'Female', child: GenderButton(title: 'Female', selected: _genderProvider.gender == 'Female'))

Those are simply two buttons which change their background when selected.

Here is the widget code

import 'package:flutter/material.dart';

import '../../theme/app_theme.dart';

class GenderButton extends StatelessWidget {
  const GenderButton({
    Key? key,
    required this.title,
    required this.selected,
  }) : super(key: key);

  final String title;
  final bool selected;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
      alignment: Alignment.center,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(16),
        gradient: LinearGradient(
          colors: selected
              ? [AppTheme.gradient1, AppTheme.gradient2]
              : [Colors.white, Colors.white],
        ),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.25),
            spreadRadius: 0,
            blurRadius: 5,
            offset: const Offset(1, 1), // changes position of shadow
          ),
        ],
      ),
      child: Text(
        title,
        style: TextStyle(
          color: selected ? Colors.white : Colors.black,
          fontWeight: FontWeight.w500,
          fontSize: 16,
          fontFamily: 'Montserrat',
        ),
      ),
    );
  }
}

I have no idea what I am doing wrong every other provider in my app is working. I hope you can help me. Thanks in advance!

CodePudding user response:

Code is working fine. I am not facing any problem with this code. button is changing color, also ui gets selected gender perfectly.

check if you initialize provider correctly on ui in build function

 final _genderProvider = Provider.of<CreatePetProvider>(context);

CodePudding user response:

you have to listen the changes, to update your widget.

read is update the value, but not update the UI imidietly, only updated when the widget marked as dirty widget.

watch when there's any changes, it rebuild the widget based on current value

 GestureDetector(
    onTap: () => context.read<Counter>().changeGender = 'Male',
    child: GenderButton(
        title: 'Male', selected: context.watch<Counter>().gender == 'Male')),
GestureDetector(
    onTap: () => context.read<Counter>().changeGender = 'Female',
    child: GenderButton(
        title: 'Female', selected: context.watch<Counter>().gender == 'Female'))

its not changed, because you have sepated class GenderButton. which is, the widget will not rebuild as long as its not marked as a dirty widget by flutter. your gender value was updated, but the widget need to rebuild. then since its not dirty widget, flutter will keep to show old widget that show old value.

*sorry for my bad explanation, hope you got the point.

  • Related