Flutter State Management - ScopedModel

Last updated Mar 24, 2020

This example we are going to learn How to Hanlde State Management with ScopedModel

in Flutter

Lets' Start

Step 1: Create Flutter Application

Step 2: Add dependencies

Add dependencies in pubspec.yaml file

 
dev_dependencies:
  flutter_test:
    sdk: flutter
  scoped_model: ^1.0.1

 

Step 3: Create Model class

A class which extends Model

 
import 'package:scoped_model/scoped_model.dart';

class MyScopeModel extends Model{
  int count=0;
  bool _isDonateClicked=false;

  get coount=>count;
  get donateClicked=>_isDonateClicked;

  void donate(bool value)
  {
    _isDonateClicked=value;
    notifyListeners();
  }

  void increment()
  {
    count++;
    notifyListeners();
  }

  void decrement()
  {
    count--;
    notifyListeners();
  }

}

 

Step 4: Create UI Widget

 
import 'package:flutter/material.dart';
import 'package:flutter_tutorial/scopemodel/model.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

import 'package:scoped_model/scoped_model.dart';
class ScopeModelPage extends StatefulWidget{
  @override
  State createState() {
    // TODO: implement createState
    return ScopeModelPageState();
  }

}

class ScopeModelPageState extends State
{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.height,
      decoration: BoxDecoration(

        image: DecorationImage(
          fit: BoxFit.fill,
            image: NetworkImage("https://previews.123rf.com/images/seamartini/seamartini1703/seamartini170300661/73813381-restaurant-dinner-top-view-icon-set-with-chinese-pork-dishes-mediterranean-vegetable-salad-czech-mea.jpg"))
      ),
      child: Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            Material(
              color: Colors.white,
              elevation: 14,
                borderRadius: BorderRadius.only(topRight: Radius.circular(40),topLeft: Radius.circular(40),),
              shadowColor: Color(0X802196f3),
              child: ScopedModelDescendant(builder: (context,child,model){

                if(model.donateClicked)
                  {
                    return buildContent(context,model);
                  }else
                    {
                      return _buildInitContent(context,model);
                    }
              }),
              //child: _buildInitContent(context),
            )
          ],
        ),
      ),
    );
  }

}

_buildInitContent(context,model) {
  return Align(
        alignment: Alignment.bottomCenter,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: 250,
          child: Column(
            children: [
              _titleContainer(model),
              _priceContainer(model),
              _donateContainer(model),
            ],
          ),
        ),
  );
}

_donateContainer(MyScopeModel model) {
  return Padding(padding: EdgeInsets.all(10),
  child: RaisedButton(onPressed: (){model.donate(true);},
    textColor: Colors.white,
    color: (Colors.amber),
    shape: RoundedRectangleBorder(),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        Text("Add Cart", style: TextStyle(fontSize: 20),),
        Icon(FontAwesomeIcons.shoppingCart,color: Colors.white,size: 30,)
      ],
    ),
  ),
  );
}

_priceContainer(MyScopeModel model) {

  return Padding(
    padding: EdgeInsets.all(15),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        RawMaterialButton(onPressed: (){model.decrement();},
        child: Icon(FontAwesomeIcons.minus,color: Colors.white,size: 20,),
          shape: CircleBorder(),
          elevation: 2.0,
            fillColor: Colors.red,
          padding: EdgeInsets.all(10),
        ),
        Text("\u0024 ${model.count}", style: TextStyle(
          color: Colors.pink,
          fontSize: 20
        ),),
        RawMaterialButton(onPressed: (){model.increment();},
          child: Icon(FontAwesomeIcons.plus,color: Colors.white,size: 20,),
          shape: CircleBorder(),
          elevation: 2.0,
          fillColor: Colors.green,
          padding: EdgeInsets.all(10),
        )
      ],
    ),
  );
}

_titleContainer(model) {
  return Container(
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Padding(padding: EdgeInsets.only(top: 10,bottom: 10,left: 10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text("MyFoodzy",
            style: TextStyle(
              color: Colors.brown,
              fontSize: 20,
              fontWeight: FontWeight.bold,
            ),),
            SizedBox(height: 20,),
            Text("Very Spice Food Prepared with\n user Custom menu",
            style: TextStyle(
              color: Colors.blueGrey,
              fontSize: 14,
            ),)
          ],
        ),

        ),
        Padding(
          padding: EdgeInsets.only(right: 10),
          child: Text("Cancel",style: TextStyle(
            color: Color(0Xffdd6b3d),
            fontSize: 12,
          ),),
        )

      ],
    ),
  );



}

buildContent(context,model)
{
  return Align(
    alignment: Alignment.bottomCenter,
    child: Container(
      width: MediaQuery.of(context).size.width,
        height: 150,
        child: Column(
          children: [
            Padding(
              padding: EdgeInsets.all(10),
              child: Text("MyFoodzy",
                style: TextStyle(
                  color: Colors.brown,
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),),
            ),
        Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [

            Text("Total Amount", style: TextStyle(fontSize: 20),),
            Text(" \u0024 200", style: TextStyle(fontSize: 20),),
          ],),
            proceedPayment(model),

          ],
        )
    ),
  );
}

proceedPayment(model) {
  return Padding(padding: EdgeInsets.all(10),
    child: RaisedButton(onPressed: (){model.donate(false);},
      textColor: Colors.white,
      color: (Colors.amber),
      shape: RoundedRectangleBorder(),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Text("Proceed & Close", style: TextStyle(fontSize: 20),),
          Icon(FontAwesomeIcons.creditCard,color: Colors.white,size: 30,)
        ],
      ),
    ),
  );
}

ScopedModelDescendant is the child widget which folled by ScopeModel parent widget.

 

Step 5: Update main dart file

 
void main() => runApp(MyApp());
MyScopeModel model=new MyScopeModel();
class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return ScopedModel(
      model: model,
      child: MaterialApp(
        theme: ThemeData(
            primaryColor: Colors.pink
        ),
        home: ScopeModelPage(),
      ),
    );

  }

}

 

Parent widget should be ScopedModel, this will handle entire state of its child widgets

 

Step 6: Run Application

Flutter StateManagement - ScopedModel

 

Flutter StateManagement - ScopedModel

Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

796 Views