如何从另一个小部件状态处理一个小部件状态?
Posted
技术标签:
【中文标题】如何从另一个小部件状态处理一个小部件状态?【英文标题】:How to handle a one widget state from another widget state? 【发布时间】:2019-10-30 11:30:52 【问题描述】:我正在制作一个带有购物车的颤振应用程序。现在,当我们选择特定产品时,我只是在处理它的单一功能,在增加或减少其数量之后,我们的购物车不会立即显示购物车上该商品的数量。我们必须转到另一个小部件,然后它会更新购物车上的计数。 注意: HomeScreen 包含两个有状态的小部件,一个是底部导航栏,其中包含购物车和其他图标以及其他图标及其各自的 UI,另一个是显示我们所有产品的产品屏幕,在我的产品屏幕中,我使用了 listview 和在其 UI 中,我使用 - 和 + 图标来增加或减少其数量。我正在共享小部件的代码 - 和 +(产品屏幕的一小部分),我想在其上实现此功能。 这是要显示的视频链接 https://youtu.be/3qqVpmWguys
主屏幕:
class HomeScreen extends StatefulWidget
@override
_HomeScreenState createState() => _HomeScreenState();
class _HomeScreenState extends State<HomeScreen>
//static _HomeScreenState of(BuildContext context) => context.ancestorStateOfType(const TypeMatcher<_HomeScreenState>());
int _currentindex = 0;
var cart;
final List<Widget> children = [
ProductScreen(),
OrderScreen(),
CartScreen(),
AccountScreen(),
];
List<BottomNavigationBarItem> _buildNavigationItems()
var bloc = Provider.of<CartManager>(context);
int totalCount = bloc.getCart().length;
setState(()
totalCount;
);
return <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Icons.reorder,
size: 30,
color: Colors.white,
),
title: Text(
'Product',
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.add_alert,
size: 30,
color: Colors.white,
),
title: Text(
'Order',
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
BottomNavigationBarItem(
icon: Stack(
children: <Widget>[
Icon(
Icons.shopping_cart,
size: 30,
color: Colors.white,
),
Positioned(
bottom: 12.0,
right: 0.0,
child: Container(
constraints: BoxConstraints(
minWidth: 20.0,
minHeight: 20.0,
),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10.0),
),
child: Center(
child: Text(
'$totalCount',
style: TextStyle(
fontSize: 12,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
)
],
),
title: Text(
'Cart',
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.lock,
size: 30,
color: Colors.white,
),
title: Text(
'Account',
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
];
@override
Widget build(BuildContext context)
return SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomPadding: true,
body: children[_currentindex],
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.transparent,
backgroundColor: Colors.orange,
onTap: onNavigationTapbar,
currentIndex: _currentindex,
items: _buildNavigationItems(),
type: BottomNavigationBarType.fixed,
),
),
);
void onNavigationTapbar(int index)
setState(()
_currentindex = index;
);
ProductScreen 增量器或减量器:
class TEProductIncrementor extends StatefulWidget
var product;
TEProductIncrementor(
this.product,
);
@override
_TEProductIncrementorState createState() => new _TEProductIncrementorState();
class _TEProductIncrementorState extends State<TEProductIncrementor>
int totalCount = 0;
@override
Widget build(BuildContext context)
var cartmanager = CartManager();
void decrementsavecallback()
// bloc.decreaseToCart(widget.ctlist);
//CartManager().updateToCart(totalCount.toString(), widget.ctlist);
setState(()
if (totalCount > 0)
totalCount--;
cartmanager.updateToCart(totalCount.toString(),widget.product);
);
void increasesavecallback()
setState(()
totalCount++;
cartmanager.updateToCart(totalCount.toString(),widget.product);
);
return Container(
margin: EdgeInsets.only(top: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: Colors.orange),
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
iconSize: 30,
icon: new Icon(
Icons.remove,
),
onPressed: ()
decrementsavecallback();
,
),
Text(
totalCount.toString(),
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
IconButton(
iconSize: 30,
icon: new Icon(Icons.add),
onPressed: ()
increasesavecallback();
,
)
],
),
),
);
【问题讨论】:
为什么不在 bloc 和 streambuilder 中为购物车小部件使用购物车流?您可以将较大的小部件中的 bloc 对象传递给较小的小部件并在那里更新它 是的,对我来说很有效。谢谢你的帮助 【参考方案1】:您可以将整个函数传递到刚刚实现的小部件中,如下所示
class Parent extends StatefulWidget
@override
_ParentState createState() => _ParentState();
class _ParentState extends State<Parent>
@override
Widget build(BuildContext context)
return Button(
()
setState(()
///define your logic here
);
);
class Button extends StatelessWidget
final Function onTap;
Button(this.onTap);
@override
Widget build(BuildContext context)
return FlatButton(
onPressed: onTap,
);
但如果你的项目很大,那么我会建议你使用任何状态管理库,比如 redux 或 mobx。
https://pub.dev/packages/mobx
【讨论】:
【参考方案2】:您可以为此使用 BLoC 模式,
Here 是您可以查看的完整答案和演示代码。
【讨论】:
在 bloc 模式中,我们可以同时处理两个以上小部件的状态吗?因为我使用了两个不同的有状态小部件,一个有底部导航栏,另一个有产品屏幕。 是的,您可以使用 bloc 模式管理多个状态,您需要创建多个流和多个流构建器,如果您不想使用 BloC 模式,您可以使用 Inherited Widget 并使用状态几乎来自任何地方的另一个班级。您可以参考上面的链接以获取继承的小部件github.com/devarshranpara/flutter_showcaseview/blob/master/lib/…【参考方案3】:为什么不用钥匙? 在两个小部件上分配一个 GlobalKey,然后,当您需要更新该状态时,您只需调用
yourGlobalKeyName.currentState.setState(()
//your code
);
【讨论】:
以上是关于如何从另一个小部件状态处理一个小部件状态?的主要内容,如果未能解决你的问题,请参考以下文章
从另一个有状态小部件调用一个有状态小部件中的方法 - Flutter