Flutter中Visibility组件包裹ListView.builder第三次切换可见性失效
问题根因
你遇到的切换失效不是Visibility组件的问题,是两处代码错误共同导致的:
- 列表数据被意外清空:你在
ListView.builder的itemBuilder中写了遍历+删除currency.allCurrenciesList元素的逻辑,第一次Visibility显示为true时,itemBuilder每执行一次就会删除列表第一个元素,首次列表渲染完成后currency.allCurrenciesList已经被清空。后续你再把_currencyVisible设为true时,itemCount为0,列表没有任何内容渲染,看起来就像切换没有生效。 - 状态变量生命周期问题:
_currencyVisible现在定义在menuItems方法内部,如果menuItems是在Widget的build方法中直接调用,每次页面重绘都会重新执行menuItems,变量会被重置为初始值false,导致状态丢失。
修复方案
首先删掉itemBuilder里多余的for循环和删除数组元素的逻辑,ListView.builder本身会根据index逐个渲染元素,不需要手动遍历。如果你的组件是StatefulWidget,建议把_currencyVisible放到State类的成员变量中维护,避免状态被意外重置。
修复后代码
menuItems(BuildContext context) { bool _currencyVisible = false; return StatefulBuilder( builder: (BuildContext context, void Function(void Function()) setState) { return ListView( children: [ ListTile( title: FutureBuilder<dynamic>( future: getUserCurrencySymbol(), builder:(BuildContext context, AsyncSnapshot<dynamic> snapshot) { return Text("Currency " + snapshot.data.toString()); }), trailing: IconButton( icon: Icon(Icons.refresh), onPressed: () { setState(() { _currencyVisible = !_currencyVisible; }); }, ), ), Visibility( visible: _currencyVisible, child: ListView.builder( shrinkWrap: true, itemCount: currency.allCurrenciesList.length, itemBuilder: (context, index) { Currency c = currency.allCurrenciesList[index]; return Card( child: ListTile( title: Text(c.country), subtitle: Text(c.shortCurrency), trailing: Text(c.symbol), onTap: () { saveUserCurrency(c.country, context); }, ), ); }, ), ), ], ); }, ); }
内容的提问来源于stack exchange,提问作者UTPAL GAURAV
相关产品推荐
相关产品推荐

