如何将 Provider 的 ChangeNotifier 与有状态小部件一起使用?

问题描述 投票:0回答:1

我正在 Flutter 中构建一个照片编辑器。我的主页包含变量,例如图层列表和当前选定的图层。我的主页有一个子小部件工具栏,它需要访问这些变量并且必须在更改后更新主页。我想为此使用 Provider,但我不知道如何设置它,因为我无法同时扩展两个类。

import 'package:provider/provider.dart';

class Toolbar extends StatefulWidget {
  const Toolbar({super.key});

  @override
  State<Toolbar> createState() => _ToolbarState();
}

class _ToolbarState extends State<Toolbar> {  //EXTENDS ChangeNotifer????
  
  XFile? _image; 
  final _picker = ImagePicker();

  Future<void> _getImageFromGallery() async {
    final XFile? pickedFile = await _picker.pickMedia();
      if (pickedFile != null) {
        _image = XFile(pickedFile.path);
      }
  }

  void _addTextEntity() {
    TextEntity newTextEntity = TextEntity(
      controller: TextEntityController(), 
    );
    selectedLayer = newTextEntity; //Variable from parent
    textLayers.add(newTextEntity); //Variable from Parent
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: [
        PopupMenuButton(
          icon: const Icon(Icons.edit), //Leftmost icon on the toolbar
          itemBuilder: (BuildContext context) => [
            PopupMenuItem(
              child: ListTile(
                title: const Text("Add Image"),
                trailing: const Icon(Icons.image),
                onTap: () => {
                  _getImageFromGallery(),
                  Navigator.pop(context) //Terminates the project manager
                },
              )
            ),
            PopupMenuItem(
              child: ListTile(
                title: const Text("Add Shape"),
                trailing: const Icon(Icons.shape_line),
                onTap: () => {
                  /** Add Shape  */
                  Navigator.pop(context),
                }
              )
            ),
            PopupMenuItem(
              child: ListTile(
                title: const Text("Add Text"),
                trailing: const Icon(Icons.text_fields),
                onTap: () => {
                  _addTextEntity(),
                  Navigator.pop(context)
                }
              )
            ),
          ],
        ),
        
        const VerticalDivider(), //To seperate persistent project manager from the rest of the toolbar

        Row(
          children: [
            //Change Font
            IconButton(
              icon: const Icon(BoxIcons.bx_font),
              onPressed: () { /** Launch change font menu */},
            ),
            //Change Font Size
            IconButton(
              icon: const Icon(BoxIcons.bx_font_size),
              onPressed: () { /** Launch change font size slider */},
            ),
            //Justify
            IconButton(
              icon: const Icon(Icons.format_align_left),
              onPressed: () { /** Launch formating menu */},
            ),
            //Change Color
            IconButton(
              icon: const Icon(BoxIcons.bx_font_color),
              onPressed: () { /** Launch color picker */},
            ),
            //Add Stroke
            IconButton(
              icon: const Icon(LineAwesome.heading_solid),
              onPressed: () { /** Launch stroke slider */},
            ),
            //Add Shadow
            IconButton(
              icon: const Icon(Bootstrap.shadows),
              onPressed: () { /** Launch shadow sliders */},
            ),
          ]
        )
      ]
    );
  }

}
flutter dart flutter-dependencies flutter-provider
1个回答
0
投票

您可以通过为变更通知程序引入一个单独的类来实现这一点。我将为此提供示例代码。

在这里,我创建了一个名为 AppData 的类来更新 textToBeDisplayed 变量的值并随时通知值更改。

class AppData extends ChangeNotifier {
 String textToBeDisplayed = "Hello";
  void updateText(String text) {
   textToBeDisplayed = text;
   notifyListeners();
 }
}

然后将 ChangeNotifiersProvider 和 AppData 添加到 MyApp 类,如下所示:

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
 const MyApp({super.key});

 @override
 Widget build(BuildContext context) {
    return ChangeNotifierProvider(
    create: (context) => AppData(),
    child: MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
      home: FirstPage()),
   );
 }
}

现在,您可以使用以下代码从应用程序中的任何位置访问 textToBeDisplayed 的值:

String text =
    Provider.of<AppData>(context, listen: false).textToBeDisplayed;

每当您需要更改 textToBeDisplayed 的值时,都可以使用以下代码来实现:

Provider.of<AppData>(context, listen: false).updateText('World');

希望这个解释有帮助。如果有任何不清楚的地方,请随时询问。

© www.soinside.com 2019 - 2024. All rights reserved.