簡體   English   中英

使用 Flutter 提供程序 package 時出現問題

[英]Problems while using Flutter Provider package

我正在創建一個非常簡單的應用程序來練習 flutter 提供者 package。 該應用程序有一個燈泡,單擊時應使用提供程序更改其背景和屏幕背景。 但這似乎不起作用。 TBH 這很令人困惑

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

void main() => runApp(MainApp());

class Data extends ChangeNotifier{
  bool isOn = false;
  void toggle(){
    this.isOn = !this.isOn;
    notifyListeners();
    print("new value is $isOn");
  }
}

class MainApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Data>(
      create: (context) => Data(),
      child: MaterialApp(
        home: Home(),
      ),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      backgroundColor: Provider.of<Data>(context).isOn ? Colors.yellow[100] : Colors.black,
      body: Center(
        child: Column(
          children: <Widget>[
            Stick(),
            Bulb(),
          ],
        ),
      ),
    );
  }
}

class Stick extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 150,
      width: 40,
      color: Colors.brown,
    );
  }
}

class Bulb extends StatefulWidget {
  @override
  _BulbState createState() => _BulbState();
}

class _BulbState extends State<Bulb> {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      width: 250,
      decoration: BoxDecoration(
          borderRadius: BorderRadius.only(
              topLeft: Radius.circular(100),
              topRight: Radius.circular(100),
              bottomLeft: Radius.circular(30),
              bottomRight: Radius.circular(30)),
          color: Provider.of<Data>(context).isOn ? Colors.yellow : Colors.white,
      ),
      child: GestureDetector(
        onTap: (){
          Provider.of<Data>(context).toggle();
          setState(() {
          });
        },
      ),
    );
  }
}

樹結構有一個主應用程序,其中包含一個 Home 應用程序,其中包含 2 個其他小部件,一個容器內的棒和一個燈泡。 單擊燈泡時,我正在嘗試更新燈泡的背景和 Home 小部件。 燈泡有一個手勢檢測器任何類型的提示或幫助表示贊賞

嘗試在提供者調用中添加listen: false

Provider.of<Data>(context, listen: false).toggle();

問題是因為Provider構造函數有一個命名參數listen ,默認情況下它等於true 當您使用Provider.of()方法時,這種行為會強制重建。 在當前的構建仍處於活動狀態時調用build是不可能的。 這就是為什么您建議將listen設置為false的原因,因為它會禁用默認行為。

最好像這樣實現:

...

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Consumer<Data>(
      builder: (_, data, __) {
        return Scaffold(
          appBar: AppBar(),
          backgroundColor: data.isOn ? Colors.yellow[100] : Colors.black,
          body: Center(
            child: Column(
              children: <Widget>[
                Stick(),
                Bulb(),
              ],
            ),
          ),
        );
      }
    );
  }
}
...

class _BulbState extends State<Bulb> {
  @override
  Widget build(BuildContext context) {
    return Consumer<Data>(
      builder: (_, data, __) {
        return Container(
          height: 200,
          width: 250,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(100),
              topRight: Radius.circular(100),
              bottomLeft: Radius.circular(30),
              bottomRight: Radius.circular(30)
            ),
            color: data.isOn ? Colors.yellow : Colors.white,
          ),
          child: GestureDetector(
            onTap: () {
              data.toggle();
              setState(() {});
            },
          ),
        );
      },
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM