我在小部件树中有一个FloatingActionButton,它具有flutter_bloc中的BlocProvider
。像这样:
BlocProvider(
builder: (context) {
SomeBloc someBloc = SomeBloc();
someBloc.dispatch(SomeEvent());
return someBloc;
},
child: Scaffold(
body: ...
floatingActionButton: FloatingActionButton(
onPressed: _openFilterSchedule,
child: Icon(Icons.filter_list),
),
)
);
这将打开一个模式底部页面:
void _openFilterSchedule() {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return TheBottomSheet();
},
);
}
我正在尝试在SomeBloc
内使用BlocProvider.of<SomeBloc>(context)
访问TheBottomSheet
,但出现以下错误:
BlocProvider.of() called with a context that does not contain a Bloc of type SomeBloc.
我尝试使用https://stackoverflow.com/a/56533611/2457045中描述的解决方案,但仅适用于BottomSheet
而不适用于ModalBottomSheet
。
注意:这不限于BlocProvider
或flutter_bloc
。 provider软件包中的任何提供程序都具有相同的行为。
如何在BlocProvider.of<SomeBloc>(context)
内部访问showModalBottomSheet
?
如果无法做到这一点,如何使https://stackoverflow.com/a/56533611/2457045解决方案适应模态底部工作表?
答案 0 :(得分:3)
答案 1 :(得分:1)
InheritedWidgets(因此是Provider)的范围仅限于小部件树。在该树之外无法访问它们。
问题是,使用showDialog
和类似功能,对话框位于不同的窗口小部件树中-可能无法访问所需的提供程序。
因此,有必要在新的小部件树中添加所需的提供程序:
void myShowDialog() {
final myModel = Provider.of<MyModel>(context, listen: false);
showDialog(
context: context,
builder: (_) {
return Provider.value(value: myModel, child: SomeDialog());
},
);
}
答案 2 :(得分:1)
showModalBottomSheet
中的提供者(底部)
void myBottomSheet() {
final myModel = Provider.of<MyModel>(context, listen: false);
showModalBottomShee(
context: context,
builder: (_) {
return ListenableProvider.value(
value: myModel,
child: Text(myModel.txtValue),
);
},
);
}
答案 3 :(得分:0)
您应该将Scaffold小部件及其子部件拆分为另一个StatefulWidget
来自单个窗口小部件
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
builder: (context) {
SomeBloc someBloc = SomeBloc();
someBloc.dispatch(SomeEvent());
return someBloc;
},
child: Scaffold(
body: ...
floatingActionButton: FloatingActionButton(
onPressed: _openFilterSchedule,
child: Icon(Icons.filter_list),
),
)
);
}
}
分为这两个小部件
class MainScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
builder: (context) {
SomeBloc someBloc = SomeBloc();
someBloc.dispatch(SomeEvent());
return someBloc;
},
child: Screen(),
);
}
}
和..
class Screen extends StatelessWidget {
void _openFilterSchedule() {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return TheBottomSheet();
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ...
floatingActionButton: FloatingActionButton(
onPressed: _openFilterSchedule,
child: Icon(Icons.filter_list),
),
);
}
}
答案 4 :(得分:0)
我找到了一个解决方案,只需将您的showModalBottomSheet与StatefulBuilder一起返回,并使用您的模式表构建器的上下文传递给您的提供者即可。下面是我的代码的一部分:
Future<Widget> showModal(int qty, Product product) async {
return await showModalBottomSheet(
isScrollControlled: true,
backgroundColor: Colors.transparent,
context: context,
builder: (BuildContext ctx) {
return StatefulBuilder(builder: (ctx, state) {
return Container(
child: RaisedButton(
onPressed: () {
Product prod = Product(product.id,
product.sku, product.name, qty);
Provider.of<CartProvider>(ctx, listen:
false).addCart(prod);}),);
}
}
);
}