Search code examples
flutterflutter-provider

flutter - using provider to change font size globally


I'm trying to use provider in my flutter app to allow the user to change the font size for some widgets.

I'm following the method described in github.com/flutter/samples/blob/master/provider_counter/lib/main.dart but the font size isn't changing.

I have a UI widget which shows plus and minus buttons:

import "package:flutter/material.dart";
import './size_controller.dart';
import 'package:provider/provider.dart';


class TypeSize extends StatelessWidget {


  final _standardSize = 20.0;

  @override

  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(20.0),
      child: Row(
        children: <Widget>[
          Text(
            "Change type size: ",
            style: TextStyle(fontSize: _standardSize),
          ),
          ButtonTheme(
              minWidth: 50,
              child: RaisedButton(
                onPressed: () {
                  if (_standardSize < 23.0) {
                    Provider.of<FontSizeController>(context, listen: false).increment(_standardSize);
                  }
                },
                child: Text(
                  "+", style: TextStyle(
                    color: Colors.white,
                    fontSize: 30),
                  ),
                color: Colors.green,
              ),
            ),
          ButtonTheme(
            minWidth: 50,
            child: RaisedButton(
              onPressed: () {
                if (_standardSize > 20.0) {
                    Provider.of<FontSizeController>(context, listen: false).decrement(_standardSize);
                }
              },
              child: Text(
                "-", style: TextStyle(
                  color: Colors.white,
                  fontSize: 30,
                  ),
                ),
              color: Colors.green,
            ),
          ),
        ],
      ),
    );
  }
}

FontSizeController looks like this:

import 'package:flutter/material.dart';

class FontSizeController with ChangeNotifier {

  double value = 20.0;

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

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

}

and finally the widget that I want to change looks like this:

import 'package:flutter/material.dart';
// import 'package:wfa_ambo_bloc/main.dart';
import 'package:provider/provider.dart';
import '../controllers/size_controller.dart';

class Comfort extends StatefulWidget {
  @override
  _ComfortState createState() => _ComfortState();
}

class _ComfortState extends State<Comfort> {

  int _comfortSliderValue = 3;
  // double _standardSize = 20;

  @override

  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.only(bottom: 40),
      child: Column(
      children: <Widget>[
        Align(
          alignment: Alignment.centerLeft,
          child: ChangeNotifierProvider(
            create: (context) => FontSizeController(),
            child: Container(
              padding: EdgeInsets.all(20.0),
              child: Consumer<FontSizeController>(
                builder: (
                  context, 
                  sizeController, 
                  child) => Text(
                    "How comfortable was your journey?",
                  textAlign: TextAlign.left,
                  style: TextStyle(
                    fontWeight: FontWeight.w400,
                    fontFamily: "Roboto",
                    letterSpacing: 0.5,
                      fontSize: sizeController.value,
                    ),
                  ),
                ),
              ),
            ),
          ),
... etc

Nothing is happening when the buttons are clicked. Can anybody help please?

The example that I'm trying to adapt is all contained within the main() but I've separated out my widgets to try and make everything cleaner - is that what is making the difference?


Solution

  • No need to use a variable in your widget (remove _standardSize).

    Just keep the value in your ChangeNotifier and use it directly (through a getter) :

    import 'package:flutter/material.dart';
    
    class FontSizeController with ChangeNotifier {
    
      double _value = 20.0;
    
      int get value => _value;
    
      void increment() {
        _value++;
        notifyListeners();
      }
    
      void decrement() {
        _value--;
        notifyListeners();
      }
    
    }
    

    Then on plus and minus buttons, simply increment or decrement value from your ChangeNotifier :

    // on plus button pressed
    Provider.of<FontSizeController>(context, listen: false).increment();
    
    // on minus button pressed
    Provider.of<FontSizeController>(context, listen: false).decrement();
    

    Finally in the widget where you want your text to be sized :

    fontSize: Provider.of<FontSizeController>(context, listen: true).value