delaram
delaram

Reputation: 819

Provider doesn't rebuild The UI

the problem is simple and clear I'm just new to provider and don"t know how to handle it

here is my main.dart file :

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => UILogic()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Login Signup UI",
      home: LoginSignupScreen(),
    );
  }
}

here is my UILogic file :

class UILogic extends ChangeNotifier {
  bool _isSignupScreen = true;
  bool _isMale = true;
  bool _isRememberMe = false;

  bool get isSignupScreen {
    return _isSignupScreen;
  }

  bool get isMale {
    return _isMale;
  }

  bool get isRememberMe {
    return _isRememberMe;
  }

  toggleScreen() {
    _isSignupScreen = !_isSignupScreen;
    notifyListeners();
  }

  togglegender() {
    _isMale = !_isMale;
    notifyListeners();
  }

  rememberMe() {
    _isRememberMe = !_isRememberMe;
    notifyListeners();
  }
}

My LogInSignUpScreen :

class LoginSignupScreen extends StatefulWidget {
  @override
  _LoginSignupScreenState createState() => _LoginSignupScreenState();
}

class _LoginSignupScreenState extends State<LoginSignupScreen> {
  @override
  Widget build(BuildContext context) {
    final uiLogic = context.read<UILogic>();
    return Scaffold(
      backgroundColor: Palette.backgroundColor,
      body: Stack(
        children: [
          Positioned(
            top: 0,
            right: 0,
            left: 0,
            child: Container(
              height: 300,
              decoration: BoxDecoration(
                  image: DecorationImage(
                      image: AssetImage("assets/images/background.jpg"),
                      fit: BoxFit.fill)),
              child: Container(
                padding: EdgeInsets.only(top: 90, left: 20),
                color: Color(0xFF3b5999).withOpacity(.85),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    RichText(
                      text: TextSpan(
                          text: "Welcome to",
                          style: TextStyle(
                            fontSize: 25,
                            letterSpacing: 2,
                            color: Colors.yellow[700],
                          ),
                          children: [
                            TextSpan(
                              text: uiLogic.isSignupScreen
                                  ? " Rizona,"
                                  : " Back,",
                              style: TextStyle(
                                fontSize: 25,
                                fontWeight: FontWeight.bold,
                                color: Colors.yellow[700],
                              ),
                            )
                          ]),
                    ),
                    SizedBox(
                      height: 5,
                    ),
                    Text(
                      uiLogic.isSignupScreen
                          ? "Signup to Continue"
                          : "Signin to Continue",
                      style: TextStyle(
                        letterSpacing: 1,
                        color: Colors.white,
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
          // Trick to add the shadow for the submit button
          buildBottomHalfContainer(true, context),
          //Main Contianer for Login and Signup
          AnimatedPositioned(
            duration: Duration(milliseconds: 700),
            curve: Curves.bounceInOut,
            top: uiLogic.isSignupScreen ? 200 : 230,
            child: AnimatedContainer(
              duration: Duration(milliseconds: 700),
              curve: Curves.bounceInOut,
              height: uiLogic.isSignupScreen ? 380 : 250,
              padding: EdgeInsets.all(20),
              width: MediaQuery.of(context).size.width - 40,
              margin: EdgeInsets.symmetric(horizontal: 20),
              decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(15),
                  boxShadow: [
                    BoxShadow(
                        color: Colors.black.withOpacity(0.3),
                        blurRadius: 15,
                        spreadRadius: 5),
                  ]),
              child: SingleChildScrollView(
                child: Column(
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: [
                        GestureDetector(
                          onTap: () {
                            context.read<UILogic>().toggleScreen();
                            // setState(() {
                            //   isSignupScreen = false;
                            // });
                          },
                          child: Column(
                            children: [
                              Text(
                                "LOGIN",
                                style: TextStyle(
                                    fontSize: 16,
                                    fontWeight: FontWeight.bold,
                                    color: !uiLogic.isSignupScreen
                                        ? Palette.activeColor
                                        : Palette.textColor1),
                              ),
                              if (!uiLogic.isSignupScreen)
                                Container(
                                  margin: EdgeInsets.only(top: 3),
                                  height: 2,
                                  width: 55,
                                  color: Colors.orange,
                                )
                            ],
                          ),
                        ),
                        GestureDetector(
                          onTap: () {
                            // context.watch<UILogic>().toggleScreen();
                            uiLogic.isSignupScreen;
                            // setState(() {
                            //   isSignupScreen = true;
                            // });
                          },
                          child: Column(
                            children: [
                              Text(
                                "SIGNUP",
                                style: TextStyle(
                                    fontSize: 16,
                                    fontWeight: FontWeight.bold,
                                    color: uiLogic.isSignupScreen
                                        ? Palette.activeColor
                                        : Palette.textColor1),
                              ),
                              if (uiLogic.isSignupScreen)
                                Container(
                                  margin: EdgeInsets.only(top: 3),
                                  height: 2,
                                  width: 55,
                                  color: Colors.orange,
                                )
                            ],
                          ),
                        )
                      ],
                    ),
                    if (uiLogic.isSignupScreen) buildSignupSection(context),
                    if (!uiLogic.isSignupScreen) buildSigninSection(context),
                  ],
                ),
              ),
            ),
          ),
          // Trick to add the submit button
          buildBottomHalfContainer(false, context),
          // Bottom buttons
          Positioned(
            top: MediaQuery.of(context).size.height - 100,
            right: 0,
            left: 0,
            child: Column(
              children: [
                Text(uiLogic.isSignupScreen
                    ? "Or Signup with"
                    : "Or Signin with"),
                Container(
                  margin: EdgeInsets.only(right: 20, left: 20, top: 15),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      buildTextButton(LineAwesomeIcons.facebook, "Facebook",
                          Palette.facebookColor),
                      buildTextButton(LineAwesomeIcons.google_plus_g, "Google",
                          Palette.googleColor),
                    ],
                  ),
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

the problem is the screen doesnt react to anything it doesnt rebuild the UI .. to sumarize the problem o seprate out the pices of code i guess its wrong so you can find the solution :

here is where i have created a variable to be able to have the data through the widget :

class _LoginSignupScreenState extends State<LoginSignupScreen> {
  @override
  Widget build(BuildContext context) {
    final uiLogic = context.read<UILogic>();

and here is where i needed a rebuild :

GestureDetector(
                          onTap: () {
                            // context.watch<UILogic>().toggleScreen();
                            uiLogic.isSignupScreen;
                            // setState(() {
                            //   isSignupScreen = true;
                            // });
                          },

and here:

GestureDetector(
                          onTap: () {
                            context.read<UILogic>().toggleScreen();
                            // setState(() {
                            //   isSignupScreen = false;
                            // });
                          },

and here in another file :

GestureDetector(
                onTap: () {
                  context.read<UILogic>().togglegender();
                },

and here in another file :

GestureDetector(
                onTap: () {
                  context.watch<UILogic>().isMale;

                  // setState(() {
                  //   isMale = true;
                  // });
                },

I cant understand where is the problem i have kept the widgets statefull for no reason . i just want to solve the problem first ...could it be about animated container ? or im using the provider the wrong way ? please guide me with actual code ... i appreciate your help inadvance.

Upvotes: 0

Views: 180

Answers (1)

Jonathan Ixcayau
Jonathan Ixcayau

Reputation: 713

Inside builder you have to use watch instead read

 @override
  Widget build(BuildContext context) {
    final uiLogic = context.watch<UILogic>();
    return Scaffold(
      backgroundColor: Palette.backgroundColor,
      body: Stack(

and in callbacks like onTap you have to use read instead watch

GestureDetector(
   onTap: () {
   context.read<UILogic>().isMale;

   // setState(() {
   //   isMale = true;
   // });
 },

Upvotes: 2

Related Questions