【问题标题】:Data transfer between pages with ChangeNotifierProvider in FlutterFlutter 中使用 ChangeNotifierProvider 在页面之间传输数据
【发布时间】:2021-04-23 16:30:17
【问题描述】:

我正在使用 Flutter 开发一个应用程序。我把屏幕分成两半。屏幕上方有按钮。当您按下这些按钮时,屏幕底部的页面将发生变化。 我为此工作使用了 ChangeNotifierProvider。但它给出了以下错误。在不打开管理面板的情况下,它会通过将屏幕涂成红色来给出此错误。

我还查看了会导致此错误的情况,它们都没有问题。我不明白错误在哪里。

谁能帮我修复代码?

错误信息:

错误:在此 AdminHomePage 小部件上方找不到正确的提供程序 发生这种情况是因为您使用了不包括您选择的提供者的BuildContext。有几种常见的情况:

  • 您在main.dart 中添加了一个新提供程序并执行了热重载。要解决此问题,请执行热重启。
  • 您尝试读取的提供程序位于不同的路径中。 提供者是“范围的”。因此,如果您在路由中插入提供程序,则其他路由将无法访问该提供程序。
  • 您使用了BuildContext,它是您尝试读取的提供程序的祖先。 确保 AdminHomePage 在您的 MultiProvider/Provider 下。这通常发生在您创建提供程序并尝试立即读取它时。

组成屏幕图像的代码(相关代码行:3.4.15.71.86.)=

void main() {
  runApp(
    ChangeNotifierProvider<StateAltMenuData>(
      create: (BuildContext context) => StateAltMenuData(),
      child: MaterialApp(
        home: AdminHomePage(),
      ),
    ),
  );
}
 
class AdminHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Function altMenu = Provider.of<StateAltMenuData>(context).altMenuDegistir;
 
    final screenHeight = MediaQuery.of(context).size.height;
    return Scaffold(
      body: Column(
        children: <Widget>[
          Expanded(
            flex: 3,
            child: Stack(
              children: <Widget>[
                OpaqueImage(
                  color: primaryColorOpacity.withOpacity(0.85),
                  imageUrl: "assets/images/kitap_arkaplan.jpg",
                ),
                SafeArea(
                  child: Padding(
                    padding: const EdgeInsets.all(4),
                    child: Column(
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Align(
                              alignment: Alignment.centerLeft,
                              child: IconButton(
                                icon: const Icon(Icons.star),
                                color: Colors.white,
                                onPressed: () {
                                  Navigator.pushAndRemoveUntil(
                                      context,
                                      PageTransition(
                                          type: PageTransitionType.fade,
                                          child: UserHomePage()),
                                      (Route<dynamic> route) => false);
                                },
                              ),
                            ),
                            Align(
                              alignment: Alignment.topCenter,
                              child: Text(
                                "Yönetici Sayfası",
                                textAlign: TextAlign.center,
                                style: headingTextStyle,
                              ),
                            ),
                            Align(
                              alignment: Alignment.centerRight,
                              child: IconButton(
                                icon: const Icon(
                                    Icons.supervisor_account_rounded),
                                color: Colors.white,
                                onPressed: () {},
                              ),
                            ),
                          ],
                        ),
                        ControlButtons(),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            flex: 5,
            child: SingleChildScrollView(
              child: Container(
                height: screenHeight * (5 / 8),
                padding: const EdgeInsets.only(top: 0),
                color: Colors.white,
                child: altMenu(),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

保存状态信息的代码 =

class StateAltMenuData with ChangeNotifier {
  int altMenuIndex = 1;
 
  altMenuDegistir(int yeniIndex) {
    altMenuIndex = yeniIndex;
    notifyListeners();
    switch (yeniIndex) {
      case 1:
        return Kutuphane();
        break;
      case 2:
        return KitapAra();
        break;
      case 3:
        return TalebeEkle();
        break;
      case 4:
        return TalebeAra();
        break;
      default:
        return Container(
          child: Center(
            child: Text("Bir şeyler ters gitti."),
          ),
        );
    }
  }
}

按钮代码(相关代码行:4.11.23.39.51.)=

class ControlButtons extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Function yeniIndex = Provider.of<StateAltMenuData>(context).altMenuDegistir;
    return Table(
      children: [
        TableRow(
          children: [
            GestureDetector(
              onTap: () {
                yeniIndex(1);
              },
              child: ControlButtonCard(
                icon: Icon(
                  Icons.add_circle_outline_rounded,
                  color: Colors.blue,
                ),
                text: "Kütüphane",
              ),
            ),
            GestureDetector(
              onTap: () {
                yeniIndex(2);
              },
              child: ControlButtonCard(
                icon: Icon(
                  Icons.search_rounded,
                  color: Colors.blue,
                ),
                text: "Kitap Ara",
              ),
            ),
          ],
        ),
        TableRow(
          children: [
            GestureDetector(
              onTap: () {
                yeniIndex(3);
              },
              child: ControlButtonCard(
                icon: Icon(
                  Icons.person_add,
                  color: Colors.blue,
                ),
                text: "Talebe Ekle",
              ),
            ),
            GestureDetector(
              onTap: () {
                yeniIndex(4);
              },
              child: ControlButtonCard(
                icon: Icon(
                  Icons.person_search,
                  color: Colors.blue,
                ),
                text: "Talebe Ara",
              ),
            ),
          ],
        ),
      ],
    );
  }
}

【问题讨论】:

    标签: flutter state provider data-transfer flutter-change-notifier


    【解决方案1】:

    在这里查看我对另一个问题的回答Provider to a different page not working as excpected

    如果仍然有问题,请告诉我。

    【讨论】:

    • void main() { runApp( MultiProvider( providers: [ ChangeNotifierProvider&lt;StateAltMenuData&gt;( create: (BuildContext context) =&gt; StateAltMenuData(), ) ], child: MaterialApp( home: AdminHomePage(), ), ), ); } 我试过了。但是没用
    • 好的。我很高兴你有一个解决方案。对我来说,multiprovider 与几个 BLOC 一起工作。也许我们的不同之处在于我使用 BLOC。我将使用 ChangeNotifier 对其进行测试。最好的问候和安全。
    【解决方案2】:

    我已经解决了这个问题。我在某处看不到解决方案。我已经工作了三四天了。也许它会帮助某人,不像我那么难。我把解决方案留在这里。

    1- 我注意到从用户面板切换到管理面板时运行的功能不在 ChangeNotifierProvider 中。我是这样做的:

    我用 ChangeNotifierProvider 包装了名为 AdminHomePage 的无状态小部件,并向子级返回了一个名为 AdminPage 的新类。

    void main () (
      runApp (
        MaterialApp (
          home: AdminHomePage (),
        ),
      );
    }
    
    class AdminHomePage extends StatelessWidget {
      @override
      Widget build (BuildContext context) {
        return ChangeNotifierProvider <StateAltMenuData> (
            create: (BuildContext context) => StateAltMenuData (),
            child: AdminPage ());
      }
    }
    
    class AdminPage extends StatelessWidget {
      @override
      Widget build (BuildContext context) {
        int altMenuIndex = Provider.of <StateAltMenuData> (context) .altMenuIndex;
        final screenHeight = MediaQuery.of (context) .size.height;
        return Scaffold (
          body: Column (
    

    2- 这样做之后,又出现了另一个问题。将在上面第 86 行显示图像的函数要求我提供动态值,我将其返回为空。我解决了如下:

    我在 AdminPage 中分配了一个名为 altMenuInde​​x 的变量。此变量的值调用 StateAltMenuData 中的 altMenuInde​​x。这已经被按钮上的值占用了。

    int altMenuIndex = Provider.of <StateAltMenuData> (context) .altMenuIndex;
    

    3- 我将 StateAltMenuData 的内部更改如下。我创建了两个不同的函数变量。所以我可以在不同的地方调用不同的函数。

    class StateAltMenuData with ChangeNotifier {
      int altMenuIndex = 1;
    
      void change altMenuIndex (int newIndex) (
        altMenuIndex = newIndex;
        notifyListeners ();
      }
    
      Change subMenu (subMenuIndex) (
        switch (subMenuIndex) (
          case 1:
            return Library ();
            break;
          case 2:
            return Search Book ();
            break;
          case 3:
            return Add to Request ();
            break;
          case 4:
            returnCall Request ();
            break;
          default:
            return Container (
              child: Center (
                child: Text ("Something went wrong"),
              ),
            );
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 2020-04-24
      • 1970-01-01
      • 2016-08-30
      • 2020-09-10
      相关资源
      最近更新 更多