flutter - использование провайдера для глобального изменения размера шрифта

Я пытаюсь использовать поставщика в своем приложении Flutter, чтобы пользователь мог изменять размер шрифта для некоторых виджетов.

Я следую методу, описанному в github.com/flutter/samples/blob/master/provider_counter/lib/main.dart, но размер шрифта не меняется.

У меня есть виджет пользовательского интерфейса, который показывает кнопки плюс и минус:

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 выглядит так:

import 'package:flutter/material.dart';

class FontSizeController with ChangeNotifier {

  double value = 20.0;

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

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

}

и, наконец, виджет, который я хочу изменить, выглядит так:

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

При нажатии на кнопки ничего не происходит. Кто-нибудь может помочь?

Пример, который я пытаюсь адаптировать, содержится в main (), но я выделил свои виджеты, чтобы попытаться сделать все чище - вот в чем разница?


person Malcolm Whild    schedule 08.02.2020    source источник
comment
Привет, дружище, поделись своим кодом. Я не могу изменить размер.   -  person Priyank    schedule 09.08.2020
comment
@Priyank - конечно, но в комментариях нет места, чтобы поместить полный код. Как лучше поделиться? Что происходит, когда вы нажимаете кнопки изменения размера?   -  person Malcolm Whild    schedule 09.08.2020


Ответы (1)


Нет необходимости использовать переменную в вашем виджете (удалите _standardSize).

Просто сохраните значение в вашем ChangeNotifier и используйте его напрямую (через геттер):

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();
  }

}

Затем на кнопках «плюс» и «минус» просто увеличивайте или уменьшайте значение вашего ChangeNotifier:

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

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

Наконец, в виджете, в котором вы хотите изменить размер текста:

fontSize: Provider.of<FontSizeController>(context, listen: true).value
person Yann39    schedule 08.02.2020
comment
Downvoter, пожалуйста, объясните ... это решение было протестировано, оно работает нормально и намного лучше, чем использование ненужных переменных. - person Yann39; 09.02.2020
comment
Большое спасибо за то, что нашли время ответить на этот вопрос. Я не уверен, почему ваш ответ был отклонен. Вы были правы в том, что вам не нужно передавать переменную _standardSize, и ваш метод, похоже, соответствует рекомендуемому на github.com/flutter/samples/blob/master/provider_counter/lib/. В моем случае мне пришлось изменить расположение виджета ChangeNotifierProvider. Я отвлекся, не загрязняя область видимости, и поместил ее в виджет вопросов пользовательского интерфейса, а не в main. - person Malcolm Whild; 10.02.2020
comment
Действительно, если вы используете Provider.of, тогда ваш ChangeNotifierProvider должен быть перемещен в виджет-предок (может быть главным). Я использовал Provider.of, чтобы получить значение в моем ответе в качестве примера, но, конечно, вы можете продолжать использовать Consumer, если хотите (особенно если вам нужны более конкретные перестройки виджетов), и в этом случае вам не нужно перемещать ChangeNotifierProvider в главный. Все зависит от структуры вашего приложения и от того, где вам нужно получить доступ к данным провайдера. - person Yann39; 10.02.2020
comment
@ Yann39 Я думаю, что слушать должно быть правдой: in fontSize: Provider.of ‹FontSizeController› (контекст, слушай: false) .value - person iamnabink; 22.11.2020
comment
@iamnabink Правда :) - person Yann39; 23.11.2020