【问题标题】:inherited widget and navigational drawer. the getter bloc was called on null继承的小部件和导航抽屉。在 null 上调用了 getter 块
【发布时间】:2020-04-16 09:34:42
【问题描述】:

我有一个带有导航抽屉菜单的应用程序。当我单击抽屉中的菜单项时,它会将我带到另一个页面。在那个屏幕上,我单击了另一个按钮,将我带到另一个屏幕。在这个屏幕上,我正在使用博客,但由于某种原因,我得到“getter bloc was called on null”。

这是我的代码 main.dart

import 'package:flutter/material.dart';
import 'package:finsec/widget/drawer_widget.dart';
import 'package:finsec/widget/inherited_month_year.dart';
import 'package:finsec/model/income/complexloginform.dart';
import 'package:finsec/screens/home/home_screen.dart';
import 'package:finsec/screens/transaction/transaction_list.dart';
import 'package:finsec/utils/colors.dart';
import 'package:finsec/utils/strings.dart';
import 'package:month_picker_dialog/month_picker_dialog.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:finsec/utils/localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:finsec/model/month_year.dart';
import 'package:finsec/data/blocs/provider.dart';
void main() => runApp(new MyApp( initialDate: DateTime.now()));

class MyApp extends StatefulWidget {
  final String title = home;
  final DateTime initialDate;

  const MyApp({Key key, @required this.initialDate}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  DateTime selectedDate, prevSelectedDate;
  String monthName1;
  int monthNumber, year;
  MonthYear monthYear;

  getDrawerItemWidget(int pos, String title) {
    switch (pos) {
      case 0:
        return new HomeScreen ();
      case 1:
        return new ComplexLoginForm();//SecondFragment();
      case 2:
        return new TransactionList(
          outstanding: totalOutstanding,
          received_or_paid:
          totalReceived, transactionType: title,);
      case 3:
        return new TransactionList(
          outstanding: totalOutstanding,
          received_or_paid: totalPaid,
          transactionType: title,);
      default:
        return new Text("Error");
    }
  }

  String titleAppBar = home;
  int tabIndex = 0;
  double elevation = 0;

  @override
  void initState() {
    setState(() {
      titleAppBar = widget.title;
    });
    super.initState();
    selectedDate = widget.initialDate;
  }


  void getMonthYear() {
    if(selectedDate != null) {
      monthName1 = monthNamesAbbrv[selectedDate.month];
      monthNumber = selectedDate.month;
      year = selectedDate.year;
      prevSelectedDate = selectedDate;
    }
    else {
      monthName1 = monthNamesAbbrv[prevSelectedDate.month];
      monthNumber = prevSelectedDate.month;
      year = prevSelectedDate.year;
    }

    monthYear = new MonthYear(monthNumber: monthNumber, year: year) ;
  }

  Widget homeScreen(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(titleAppBar),
        elevation: elevation,
        backgroundColor: colorPrimary,
        actions: <Widget>[
          Builder(
            builder: (context) => FlatButton.icon(
              icon: Icon(Icons.calendar_today, color: white,), //`Icon` to display
              label: Text(monthName1 + ' $year'  , style: TextStyle(color: white, fontSize: 18)), //`Text` to display
              onPressed: () {
                showMonthPicker(
                    context: context,
                    firstDate: DateTime( DateTime.now().year - 1 , 5),
                    lastDate: DateTime( DateTime.now().year + 1, 9 ),
                    initialDate: selectedDate ?? widget.initialDate
                )
                    .then((date) => setState(() {
                  selectedDate = date ;//!= null ? date : prevSelectedDate;

                }));
              },
            ),
          )
        ],
      ),
      drawer: DrawerWidget((title, index) {
        setState(() {
          titleAppBar = title;
          tabIndex = index;
        });
      }, tabIndex),
      body: getDrawerItemWidget(tabIndex, titleAppBar),
    );
  }


  @override
  Widget build(BuildContext context) {

    return
      Provider(
        child: MaterialApp(
          localizationsDelegates: [
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
          ],
          supportedLocales: [
            Locale('en'),
            Locale('zh'),
            Locale('fr'),
            Locale('es'),
            Locale('de'),
            Locale('ru'),
            Locale('ja'),
            Locale('ar'),
            Locale('fa'),
          ],
          title: widget.title,
          home: homeScreen(context)

    );
  }
}

事务列表类。这是我点击的菜单项,将我带到另一个屏幕


import 'package:flutter/material.dart';
import 'package:finsec/utils/colors.dart';
import 'package:finsec/utils/strings.dart';
import 'package:finsec/screens/transaction/text_switch_app_bar.dart';
import 'package:finsec/screens/transaction/row_column_layout_attributes.dart';
import 'package:finsec/widget/transaction_list_view.dart';
import 'package:finsec/screens/income/second_fragment.dart';
import 'package:finsec/screens/income/add_edit_income.dart';
import 'package:finsec/data/blocs/bloc_provider.dart';
import 'package:finsec/data/blocs/transaction_bloc.dart';
import 'package:finsec/model/income/income.dart';
import 'package:finsec/model/income/income_dao.dart';
import 'package:finsec/model/income/income_transactions.dart';

class TransactionList extends StatefulWidget {
  TransactionList({
    Key key,
    this.outstanding,
    this.received_or_paid,
    this.transactionType
  }) : super(key: key);

  final String outstanding , received_or_paid, transactionType;

  @override
  _TransactionListState createState() => new _TransactionListState();
}

class _TransactionListState extends State<TransactionList> {
  bool _isRow = true;
  MainAxisAlignment _mainAxisAlignment = MainAxisAlignment.start;
  CrossAxisAlignment _crossAxisAlignment = CrossAxisAlignment.start;
  MainAxisSize _mainAxisSize = MainAxisSize.min;
 String outstanding , received_or_paid, transactionType;
IncomeDao incomeDao;

  List<Income> incomeList;

  void _updateLayout(int index) {
    setState(() {
      _isRow = index == 0;
    });
  }

  getTransactionType() {
    switch ("${widget.transactionType}") {
      case incomeTransaction:
        return new AddEditIncome (appBarTitle: incomeTitle);
      case expenseTransaction:
        return new SecondFragment();
      default:
        return new Text("Error");
    }
  }

  MainAxisAlignment _mainAxisAlignmentFromIndex(int index) {
    switch (index) {
      case 0:
        return MainAxisAlignment.start;
      case 1:
        return MainAxisAlignment.end;
      case 2:
        return MainAxisAlignment.center;
      case 3:
        return MainAxisAlignment.spaceBetween;
      case 4:
        return MainAxisAlignment.spaceAround;
      case 5:
        return MainAxisAlignment.spaceEvenly;
    }
    return MainAxisAlignment.start;
  }

  void _updateMainAxisAlignment(int index) {
    setState(() {
      _mainAxisAlignment = _mainAxisAlignmentFromIndex(index);
    });
  }

  CrossAxisAlignment _crossAxisAlignmentFromIndex(int index) {
    switch (index) {
      case 0:
        return CrossAxisAlignment.start;
      case 1:
        return CrossAxisAlignment.end;
      case 2:
        return CrossAxisAlignment.center;
      case 3:
        return CrossAxisAlignment.stretch;
      case 4:
        return CrossAxisAlignment.baseline;
    }
    return CrossAxisAlignment.start;
  }

  void _updateCrossAxisAlignment(int index) {
    setState(() {
      _crossAxisAlignment = _crossAxisAlignmentFromIndex(index);
    });
  }

  void _updateMainAxisSize(int index) {
    setState(() {
      _mainAxisSize = index == 0 ? MainAxisSize.min : MainAxisSize.max;
    });
  }

  Widget _buildLayoutAttributesPage() {
    return RowColumnLayoutAttributes(
      onUpdateLayout: _updateLayout,
      onUpdateMainAxisAlignment: _updateMainAxisAlignment,
      onUpdateCrossAxisAlignment: _updateCrossAxisAlignment,
      onUpdateMainAxisSize: _updateMainAxisSize,
    );
  }

  Widget buildContent() {
    int count = 0;

    if (incomeList == null) {
      incomeList = List<Income>();
    }
      return Column(
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            mainAxisSize: MainAxisSize.max,
            children: [
              Expanded(
                flex: 1,
                child: Column(
                  children: <Widget>[
                    Text(
                      "${widget.outstanding}",
                      textAlign: TextAlign.center,
                        style: TextStyle( fontSize: 16.0)
                    ),
                    Padding(
                      padding: EdgeInsets.all(3.0),
                      child: Text(zeroAmount,
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            color: green, fontSize: 16.0
                          )),
                    ),
                  ],
                ),
              ),
              Container(width: 0.4, height: 40, color: Colors.black54),
              Expanded(
                flex: 1,
                child: Column(
                  children: [
                    Text(
                      "${widget.received_or_paid}",
                      textAlign: TextAlign.center,
                        style: TextStyle( fontSize: 16.0)
                    ),
                    Padding(
                      padding: EdgeInsets.all(3.0),
                      child: Text(zeroAmount, textAlign: TextAlign.center,
                          style: TextStyle(color: green, fontSize: 16)),
                    ),
                  ],
                ),
              ),
            ],
          ),

          Padding(
            padding: EdgeInsets.only(top: 12.0, left: 15.0, right: 15.0),
            child: Divider(
              height: 1,
              color: Colors.black54,
            ),
          ),

          Expanded(
              flex: 1,
              child: IncomeTransaction(),
          ),
        ],
      );

    }

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: TextSwitchAppBar(
          bottom: PreferredSize(
            child: _buildLayoutAttributesPage(),
          ),

        ),
        floatingActionButton: FloatingActionButton(
          backgroundColor: colorPrimary,
          onPressed: () {
            Navigator.push(context,
                MaterialPageRoute(builder: (context) => getTransactionType()));
          },
          child: Icon(
            Icons.add,
          ),
        ),
        body: Container(
            padding: EdgeInsets.symmetric(vertical: 16.0),
            child: buildContent()//IncomeTransaction()
        ),
      );
    }

}

在 TransactionList 类中,我单击一个按钮,将我带到另一个屏幕:AddEditIncome 在那个屏幕上,我正在调用一个块,例如:final bloc = Provider.of(context);

提供者的类是

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

class Provider extends InheritedWidget {
  final bloc = Bloc();

  Provider({Key key, Widget child}) : super(key: key, child: child);

  bool updateShouldNotify(_) => true;

  static Bloc of(BuildContext context) {
    //* What it does is through the "of" function, it looks through the context of a widget from the deepest in the widget tree
    //* and it keeps travelling up to each widget's parent's context until it finds a "Provider" widget
    //* and performs the type conversion to Provider through "as Provider" and then access the Provider's bloc instance variable
    return (context.dependOnInheritedWidgetOfExactType() as Provider).bloc;
  }
}


我收到错误消息:“getter bloc 被调用为 null”。我在主屏幕的材料应用程序功能中指定了 Provider 类包装。但看起来这可能只对 home: homeScreen(context) 而不是导航抽屉中的菜单项。有人可以帮助解决此问题,以便当我单击任何导航菜单项时,我不会因为空错误而调用 bloc?提前致谢

【问题讨论】:

    标签: flutter


    【解决方案1】:

    我通过直接从 main.dart 调用给出错误的屏幕来测试我的应用程序。然后我发现我需要将调用函数包装到一个脚手架小部件中,并在提供程序类中使用 inheritFromWidgetOfExactType 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-24
      • 2016-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多