Flutter используйте несколько виджетов с отслеживанием состояния из отдельных файлов в другом

#flutter #dart

Вопрос:

Я разделил виджеты для своего приложения для раскрашивания на разные файлы.

вот примерное представление дерева виджетов, над которым я намерен работать. Я хочу использовать menu_items.dart в PaintingScreen.dart и menu_items.dart буду содержать

  1. color_palette.dart
  2. stroke_picker.dart
  3. stroke_picker.dart

введите описание изображения здесь

Поскольку это приложение для раскраски, пользователи смогут изменять цвет, указанный в color_palette и stroke width , opacity

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

Вот мой color_palette.dart :

 class ColorPalette extends StatefulWidget {
  @override
  _ColorPaletteState createState() => _ColorPaletteState();
}

class _ColorPaletteState extends State<ColorPalette> {
  Color selectedColor = Colors.black;
  Color pickerColor = Color(0xff443a49);
  Color currentColor = Color(0xff443a49);

  void changeColor(Color color) {
    setState(() => selectedColor = color);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: BlockPicker(pickerColor: pickerColor, onColorChanged: changeColor),
    );
  }
}
 

Вот мой opacity_picker.dart

 class OpacityPicker extends StatefulWidget {
  @override
  _OpacityPickerState createState() => _OpacityPickerState();
}

class _OpacityPickerState extends State<OpacityPicker> {
  double opacity = 1.0;
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          IconButton(
            onPressed: () {
              opacity = 0.1;
            },
            icon: Icon(Icons.opacity, size: 20),
          ),
          IconButton(
            onPressed: () {
              opacity = 0.5;
            },
            icon: Icon(Icons.opacity, size: 30),
          ),
          IconButton(
            onPressed: () {
              opacity = 1.0;
            },
            icon: Icon(Icons.opacity, size: 40),
          ),
        ],
      ),
    );
  }
}
 

Both of this widgets will be used in menu_items.dart

 class UtilityItems extends StatefulWidget {
  final double opacity;
  final double strokeWidth;

  UtilityItems({@required this.opacity, @required this.strokeWidth});
  @override
  _UtilityItemsState createState() => _UtilityItemsState();
}

class _UtilityItemsState extends State<UtilityItems> {
  List<TouchPoints> points = [];
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Container(
        child: Column(
          children: [
            StrokePicker(),
            OpacityPicker(),
            ColorPalette(),
          ],
        ),
      ),
    );
  }
}
 

Теперь в PaintingScreen.дарт есть несколько мест, где я хочу использовать предметы из menu_items.dart :

внутренний детектор жестов:

 onPanUpdate: (details) {
   setState(() {
      RenderBox renderBox = context.findRenderObject();
      points.add(TouchPoints(
         points: renderBox.globalToLocal(
              details.globalPosition),
              paint: Paint()
                  ..strokeCap = strokeType
                  ..isAntiAlias = true
                  ..color = selectedColor.withOpacity(opacity)
                  ..strokeWidth = strokeWidth));
       });
},
 

И внутри Расширенного:

 Expanded(
  flex: 2,
  child: Container(
      decoration: BoxDecoration(
         color: Colors.grey,
         borderRadius: BorderRadius.all(
             Radius.circular(20),
         ),
      ),
      height: MediaQuery.of(context).size.height * 0.75,
      width: MediaQuery.of(context).size.width / 4,
      child: UtilityItems(
         opacity: opacity, strokeWidth: strokeWidth),
      ),
),
 

UtilityItems от menu_items.dart показывает все, кроме обновления значений. Кто-нибудь может объяснить, почему значения не обновляются? И что я должен реализовать, чтобы это сработало?

Комментарии:

1. Используйте riverpod/провайдера в качестве государственного мэна.

Ответ №1:

В настоящее время другие ваши виджеты не знают, когда пользователь выбирает цвет с помощью вашего ColorPalette виджета. Это связано с тем, что выбранный им цвет хранится только в ColorPalette виджете. Чтобы решить эту проблему, нам нужен способ, позволяющий любому другому виджету хранить/изменять/считывать значение цвета, заданное пользователем.

Простой способ достичь этого-использовать Riverpod. Это позволит вам создать Color переменную, доступ к которой можно получить из любого виджета. Взгляните на этот встречный пример. Он counter обновляется виджетом, а затем считывается другим виджетом.

Комментарии:

1. так final strokeWidthProvider = StateProvider((ref) => 3.0); что должно быть внутри menu_items.dart ?