Я пытаюсь научиться правильному управлению состоянием с поставщиком, у меня проблема, с которой у меня проблемы. Насколько я могу судить, я все делаю в соответствии с инструкциями из трех отдельных руководств для провайдеров. Я также успешно использую его для своей таблицы данных без проблем. Однако я продолжаю получать сообщения об ошибках и сбоях при попытке использовать поставщика для моего BottomNavigationBar и моего appBar вверх по дереву виджетов.
Я хочу, чтобы моя нижняя панель навигации была отделена от состояния нулевого экрана. Итак, я устанавливаю int с нажатиями кнопок нижней панели навигации в соответствии с индексом, это должно обновить мой индекс GlobalData pageSelection. Затем я обращаюсь к нему вверх по дереву для тернарных операторов. Но я получаю странную ошибку, говоря, что это не в дереве виджетов ...
Я безуспешно пытался сделать то, что указано в предложении об ошибке.
Любая помощь приветствуется!
import 'package:flutter/material.dart';
class GlobalData extends ChangeNotifier {
int pageSelectionIndex = 0;
void updatePageSelection(int index) {
pageSelectionIndex = index;
notifyListeners();
}
}
BottomNavBar
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fp_provider_demo_one/models/global_data.dart';
import 'package:fp_provider_demo_one/screens/balance_screen.dart';
import 'package:fp_provider_demo_one/screens/subtract_screen.dart';
import 'package:fp_provider_demo_one/screens/add_screen.dart';
import 'package:fp_provider_demo_one/screens/inquiry_screen.dart';
import 'package:provider/provider.dart';
// ignore: must_be_immutable
class BottomNavBar extends StatefulWidget {
@override
_BottomNavBarState createState() => _BottomNavBarState();
}
class _BottomNavBarState extends State<BottomNavBar> {
int _currentTabIndex = 0;
@override
Widget build(BuildContext context) {
final _tabPages = <Widget>[
AddScreen(),
SubtractScreen(),
BalanceScreen(),
InquiryScreen()
];
final _navBarItems = <BottomNavigationBarItem>[
const BottomNavigationBarItem(
icon: Icon(Icons.add_circle), label: 'Add'),
const BottomNavigationBarItem(
icon: Icon(Icons.remove_circle), label: 'Subtract'),
const BottomNavigationBarItem(
icon: Icon(Icons.grid_on_rounded), label: 'Balance'),
const BottomNavigationBarItem(
icon: Icon(Icons.show_chart), label: 'Inquiry'),
];
assert(_tabPages.length == _navBarItems.length);
final navBar = BottomNavigationBar(
items: _navBarItems,
showUnselectedLabels: true,
showSelectedLabels: true,
unselectedItemColor: Colors.grey,
selectedItemColor: Colors.orange,
currentIndex: _currentTabIndex,
type: BottomNavigationBarType.fixed,
onTap: (int index) {
Provider.of<GlobalData>(context).updatePageSelection(index);
setState(() {
_currentTabIndex = index;
});
},
);
return Scaffold(
body: _tabPages[_currentTabIndex],
bottomNavigationBar: navBar,
);
}
}
Нулевой экран:
///
///
/// Holds bottom nav bar which in turn switches through screens
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fp_provider_demo_one/models/global_data.dart';
import 'package:fp_provider_demo_one/widgets/bottom_nav_bar.dart';
import 'package:provider/provider.dart';
class ZeroScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
int _selectedIndex = Provider.of<GlobalData>(context).pageSelectionIndex;
return Scaffold(
appBar: AppBar(
title: (_selectedIndex == 0)
? Text('Add')
: (_selectedIndex == 1)
? Text('Subtract')
: (_selectedIndex == 2)
? Text('Balance')
: Text('Inquiry'),
backgroundColor: (_selectedIndex == 0)
? Colors.green
: (_selectedIndex == 1)
? Colors.red
: (_selectedIndex == 2)
? Colors.blue
: Colors.orange,
),
bottomNavigationBar: BottomNavBar(),
);
}
}
Ошибка:
======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
Tried to listen to a value exposed with provider, from outside of the widget tree.
This is likely caused by an event handler (like a button's onPressed) that called
Provider.of without passing `listen: false`.
To fix, write:
Provider.of<GlobalData>(context, listen: false);
It is unsupported because may pointlessly rebuild the widget associated to the
event handler, when the widget tree doesn't care about the value.
The context used was: BottomNavBar(state: _BottomNavBarState#38ad7)
'package:provider/src/provider.dart':
Failed assertion: line 262 pos 7: 'context.owner.debugBuilding ||
listen == false ||
debugIsInInheritedProviderUpdate'
When the exception was thrown, this was the stack:
#2 Provider.of (package:provider/src/provider.dart:262:7)
#3 _BottomNavBarState.build.<anonymous closure> (package:fp_provider_demo_one/widgets/bottom_nav_bar.dart:49:18)
#4 _BottomNavigationBarState._createTiles.<anonymous closure> (package:flutter/src/material/bottom_navigation_bar.dart:974:26)
#5 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:991:20)
#6 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#035fc
debugOwner: GestureDetector
state: ready
won arena
finalPosition: Offset(144.0, 783.0)
finalLocalPosition: Offset(46.5, 21.5)
button: 1
sent tap down
====================================================================================================